diff --git a/lib/generator/artifact.ts b/lib/generator/artifact.ts index 681eb5189..1484c9dcd 100644 --- a/lib/generator/artifact.ts +++ b/lib/generator/artifact.ts @@ -49,7 +49,7 @@ import { trojanFilter, socks5Filter, } from '../utils/filter'; -import { prependFlag } from '../utils/flag'; +import { prependFlag, removeFlag } from '../utils/flag'; import { loadLocalSnippet } from './template'; export interface ArtifactOptions { @@ -362,9 +362,12 @@ export class Artifact extends EventEmitter { } } - // 给节点名加国旗 if (provider.addFlag) { - nodeConfig.nodeName = prependFlag(nodeConfig.nodeName); + // 给节点名加国旗 + nodeConfig.nodeName = prependFlag(nodeConfig.nodeName, provider.removeExistingFlag); + } else if (provider.removeExistingFlag) { + // 去掉名称中的国旗 + nodeConfig.nodeName = removeFlag(nodeConfig.nodeName); } // TCP Fast Open diff --git a/lib/provider/Provider.ts b/lib/provider/Provider.ts index ba21b4b17..52972e8da 100644 --- a/lib/provider/Provider.ts +++ b/lib/provider/Provider.ts @@ -15,6 +15,7 @@ export default class Provider { public readonly youtubePremiumFilter?: ProviderConfig['youtubePremiumFilter']; public readonly customFilters?: ProviderConfig['customFilters']; public readonly addFlag?: boolean; + public readonly removeExistingFlag?: boolean; public readonly tfo?: boolean; public readonly mptcp?: boolean; public readonly renameNode?: ProviderConfig['renameNode']; @@ -39,6 +40,7 @@ export default class Provider { Joi.any().allow(Joi.function(), Joi.object({ filter: Joi.function(), supportSort: Joi.boolean().strict() })) ), addFlag: Joi.boolean().strict(), + removeExistingFlag: Joi.boolean().strict(), mptcp: Joi.boolean().strict(), tfo: Joi.boolean().strict(), startPort: Joi.number().integer().min(1024).max(65535), @@ -57,18 +59,24 @@ export default class Provider { throw error; } - this.type = config.type; - this.nodeFilter = config.nodeFilter; - this.netflixFilter = config.netflixFilter; - this.youtubePremiumFilter = config.youtubePremiumFilter; - this.customFilters = config.customFilters; - this.addFlag = config.addFlag; - this.tfo = config.tfo; - this.mptcp = config.mptcp; - this.startPort = config.startPort; - this.renameNode = config.renameNode; - this.relayUrl = config.relayUrl; this.supportGetSubscriptionUserInfo = false; + + [ + 'type', + 'nodeFilter', + 'netflixFilter', + 'youtubePremiumFilter', + 'customFilters', + 'addFlag', + 'removeExistingFlag', + 'tfo', + 'mptcp', + 'startPort', + 'renameNode', + 'relayUrl', + ].forEach(key => { + this[key] = config[key]; + }); } public get nextPort(): number { diff --git a/lib/types.ts b/lib/types.ts index 3e884c199..1adaf8104 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -103,6 +103,7 @@ export interface ProviderConfig { readonly [name: string]: NodeNameFilterType|SortedNodeNameFilterType; }; readonly addFlag?: boolean; + readonly removeExistingFlag?: boolean; readonly tfo?: boolean; readonly mptcp?: boolean; readonly renameNode?: (name: string) => string; diff --git a/lib/utils/flag.ts b/lib/utils/flag.ts index 46b6d4897..b3f79d77a 100644 --- a/lib/utils/flag.ts +++ b/lib/utils/flag.ts @@ -1,29 +1,48 @@ import EmojiRegex from 'emoji-regex' import flag from '../misc/flag_cn'; -const flagMap: { - [name: string]: string; -} = {}; +const flagMap: Map = new Map(); Object.keys(flag).forEach(emoji => { flag[emoji].forEach((name: string) => { - flagMap[name] = emoji; + flagMap.set(name, emoji); }); }); -export const prependFlag = (str: string): string => { +export const addFlagMap = (name: string|RegExp, emoji: string): void => { + flagMap.set(name, emoji); +}; + +export const prependFlag = (str: string, removeExistingEmoji = false): string => { const emojiRegex = EmojiRegex(); const existingEmoji = emojiRegex.exec(str); - // 如果已经存在 emoji 则不作处理 if (existingEmoji) { - return str; + if (removeExistingEmoji) { + // 去除已有的 emoji + str = removeFlag(str); + } else { + // 不作处理 + return str; + } } - for (const key in flagMap) { - if (flagMap.hasOwnProperty(key) && str.toUpperCase().includes(key)) { - return `${flagMap[key]} ${str}`; + for (const [key, value] of flagMap.entries()) { + if (typeof key === 'string') { + if (str.toUpperCase().includes(key)) { + return `${value} ${str}`; + } + } else { + if (key.test(str)) { + return `${value} ${str}`; + } } } + return str; }; + +export const removeFlag = (str: string): string => { + const emojiRegex = EmojiRegex(); + return str.replace(emojiRegex, '').trim(); +}; diff --git a/test/utils/flag.test.ts b/test/utils/flag.test.ts index f5e3ecf68..0b772feeb 100644 --- a/test/utils/flag.test.ts +++ b/test/utils/flag.test.ts @@ -1,5 +1,5 @@ import test from 'ava'; -import { prependFlag } from '../../lib/utils/flag'; +import { prependFlag, removeFlag } from '../../lib/utils/flag'; test('addFlag', t => { t.is(prependFlag('美国'), '🇺🇸 美国'); @@ -10,4 +10,12 @@ test('addFlag', t => { t.is(prependFlag('us'), '🇺🇸 us'); t.is(prependFlag('🇺🇸 jp'), '🇺🇸 jp'); t.is(prependFlag('🇯🇵 US'), '🇯🇵 US'); + t.is(prependFlag('🇺🇸 jp', true), '🇯🇵 jp'); + t.is(prependFlag('🇯🇵 🇺🇸 jp', true), '🇯🇵 jp'); + t.is(prependFlag('🇺🇸 🇯🇵 US', true), '🇺🇸 US'); +}); + +test('removeFlag', t => { + t.is(removeFlag('🇺🇸 jp'), 'jp'); + t.is(removeFlag('🇺🇸 🇺🇸 jp'), 'jp'); });