From 237ecd497eb0b9ed01982e08ae135a6869784e48 Mon Sep 17 00:00:00 2001 From: Virgil Clyne Date: Wed, 22 Jun 2022 22:29:56 +0800 Subject: [PATCH] feat: Update getFlag() #build Update geo.js --- backend/src/utils/geo.js | 355 ++++++++++++++++++--------------------- 1 file changed, 164 insertions(+), 191 deletions(-) diff --git a/backend/src/utils/geo.js b/backend/src/utils/geo.js index 603616f..924a7af 100644 --- a/backend/src/utils/geo.js +++ b/backend/src/utils/geo.js @@ -1,14 +1,21 @@ // get proxy flag according to its name export function getFlag(name) { // flags from @KOP-XIAO: https://github.com/KOP-XIAO/QuantumultX/blob/master/Scripts/resource-parser.js - const flags = { - '🇦🇿': ['阿塞拜疆'], - '🇦🇹': ['奥地利', '奧地利', 'Austria', '维也纳'], - '🇦🇺': [ - 'AU', - 'Australia', - 'Sydney', - '澳大利亚', + // flags from @surgioproject: https://github.com/surgioproject/surgio/blob/master/lib/misc/flag_cn.ts + + // refer: https://zh.wikipedia.org/wiki/ISO_3166-1二位字母代码 + // refer: https://zh.wikipedia.org/wiki/ISO_3166-1三位字母代码 + const Flags = { + '🏳️‍🌈': ['流量', '时间', '过期', 'Bandwidth', 'Expire'], + '🇸🇱': ['应急', '测试节点'], + '🇦🇩': ['AD', 'AND', 'Andorra', '安道尔'], + '🇦🇪': ['AE', 'ARE', 'United Arab Emirates', '阿联酋', '迪拜'], + '🇦🇫': ['AF', 'AFG', 'Afghanistan', '阿富汗'], + '🇦🇱': ['AL', 'ALB', 'Albania', '阿尔巴尼亚', '阿爾巴尼亞'], + '🇦🇲': ['AM', 'ARM', 'Armenia', '亚美尼亚'], + '🇦🇷': ['AR', 'ARG', 'Argentina', '阿根廷'], + '🇦🇹': ['AT', 'AUT', 'Austria', '奥地利', '奧地利', '维也纳'], + '🇦🇺': ['AU', 'AUS', 'Australia', '澳大利亚', '澳洲', '墨尔本', '悉尼', @@ -18,78 +25,79 @@ export function getFlag(name) { '滬澳', '沪澳', '广澳', + 'Sydney' ], - '🇧🇪': ['BE', '比利時', '比利时'], - '🇧🇬': ['保加利亚', '保加利亞', 'Bulgaria'], - '🇧🇭': ['BH', '巴林'], - '🇧🇩': ['BD', '孟加拉'], - '🇵🇰': ['巴基斯坦'], - '🇰🇭': ['柬埔寨'], - '🇺🇦': ['烏克蘭', '乌克兰'], - '🇭🇷': ['克罗地亚', 'HR', '克羅地亞'], - '🇨🇦': [ - 'Canada', - 'CANADA', - 'CAN', - 'Waterloo', - '加拿大', + '🇦🇿': ['AZ', 'AZE', 'Azerbaijan', '阿塞拜疆'], + '🇧🇦': ['BA', 'BIH', 'Bosnia and Herzegovina', '波黑共和国', '波黑'], + '🇧🇩': ['BD', 'BGD', 'Bangladesh', '孟加拉国', '孟加拉'], + '🇧🇪': ['BE', 'BEL', 'Belgium', '比利时', '比利時'], + '🇧🇬': ['BG', 'BGR', 'Bulgaria', '保加利亚', '保加利亞'], + '🇧🇭': ['BH', 'BHR', 'Bahrain', '巴林'], + '🇧🇷': ['BR', 'BRA', 'Brazil', '巴西', '圣保罗'], + '🇧🇾': ['BY', 'BLR', 'Belarus', '白俄罗斯', '白俄'], + '🇨🇦': ['CA', 'CAN', 'Canada', '加拿大', '蒙特利尔', '温哥华', '楓葉', '枫叶', '滑铁卢', '多伦多', - 'CA', + 'Waterloo', ], - '🇨🇭': ['瑞士', '苏黎世', 'Switzerland', 'Zurich'], - '🇳🇬': ['尼日利亚', 'NG', '尼日利亞'], - '🇨🇿': ['Czechia', '捷克'], - '🇸🇰': ['斯洛伐克', 'SK'], - '🇷🇸': ['RS', '塞尔维亚'], - '🇲🇩': ['摩爾多瓦', 'MD', '摩尔多瓦'], - '🇩🇪': [ - 'DE', - 'German', - 'GERMAN', - '德国', + '🇨🇭': ['CH', 'CHE', 'Switzerland', '瑞士', '苏黎世', 'Zurich'], + '🇨🇱': ['CL', 'CHL', 'Chile', '智利'], + '🇨🇳': ['CN', 'CHN', 'China', '中国', + '中國', + '回国', + '回國', + '江苏', + '北京', + '上海', + '广州', + '深圳', + '杭州', + '徐州', + '青岛', + '宁波', + '镇江', + 'back', + ], + '🇨🇴': ['CO', 'COL', 'Colombia', '哥伦比亚'], + '🇨🇷': ['CR', 'CRI', 'Costa Rica', '哥斯达黎加'], + '🇨🇾': ['CY', 'CYP', 'Cyprus', '塞浦路斯'], + '🇨🇿': ['CZ', 'CZE', 'Czechia', '捷克'], + '🇩🇪': ['DE', 'DEU', 'German', '德国', '德國', - '法兰克福', '京德', '滬德', '廣德', '沪德', '广德', + '法兰克福', 'Frankfurt', ], - '🇦🇲': ['亚美尼亚', 'AM', 'Armenia'], - '🇦🇩': ['安道尔', 'AD', 'Andorra'], - '🇷🇪': ['留尼汪', '法属留尼汪', 'Réunion', 'RE'], - '🇵🇾': ['巴拉圭', 'Paraguay', 'PY'], '🇩🇰': ['DK', 'DNK', '丹麦', '丹麥'], - '🇪🇸': ['ES', '西班牙', 'Spain'], - '🇪🇺': ['EU', '欧盟', '欧罗巴'], - '🇫🇮': ['Finland', '芬兰', '芬蘭', '赫尔辛基'], - '🇫🇷': ['FR', 'France', '法国', '法國', '巴黎'], - '🇬🇧': [ + '🇪🇨': ['EC', 'ECU', 'Ecuador', '厄瓜多尔'], + '🇪🇪': ['EE', 'EST', 'Estonia', '爱沙尼亚'], + '🇪🇬': ['EG', 'EGY', 'Egypt', '埃及'], + '🇪🇸': ['ES', 'ESP', 'Spain', '西班牙'], + '🇪🇺': ['EU', 'European Union', '欧盟', '欧罗巴'], + '🇫🇮': ['FI', 'FIN', 'Finland', '芬兰', '芬蘭', '赫尔辛基'], + '🇫🇷': ['FR', 'FRA', 'France', '法国', '法國', '巴黎'], + '🇬🇧': ['GB', 'GBR', 'Great Britain', '英国', 'UK', - 'GB', 'England', 'United Kingdom', - '英国', '伦敦', '英', 'London', ], - '🇲🇴': ['MO', 'Macao', '澳门', '澳門', 'CTM'], - '🇰🇿': ['哈萨克斯坦', '哈萨克'], - '🇭🇺': ['匈牙利', 'Hungary'], - '🇭🇰': [ - 'HK', - 'Hongkong', + '🇬🇪': ['GE', 'GEO', 'Georgia', '格鲁吉亚', '格魯吉亞'], + '🇬🇷': ['GR', 'GRC', 'Greece', '希腊', '希臘'], + '🇭🇰': ['HK', 'HKG', 'Hongkong', '香港', 'Hong Kong', 'HongKong', 'HONG KONG', - '香港', '深港', '沪港', '呼港', @@ -102,53 +110,81 @@ export function getFlag(name) { '京港', '港', ], - '🇮🇩': ['Indonesia', '印尼', '印度尼西亚', '雅加达'], - '🇮🇪': ['Ireland', 'IRELAND', '爱尔兰', '愛爾蘭', '都柏林'], - '🇮🇱': ['Israel', '以色列'], - '🇮🇳': ['India', 'IND', 'INDIA', '印度', '孟买', 'MFumbai'], - '🇮🇸': ['IS', 'ISL', '冰岛', '冰島'], - '🇰🇵': ['KP', '朝鲜'], - '🇰🇷': [ - 'KR', - 'Korea', - 'KOR', - '韩国', - '首尔', + '🇭🇷': ['HR', 'HRV', 'Croatia', '克罗地亚', '克羅地亞'], + '🇭🇺': ['HU', 'HUN', 'Hungary', '匈牙利'], + '🇯🇴': ['JO', 'JOR', 'Jordan', '约旦'], + '🇯🇵': ['JP', 'JPN', 'Japan', '日本', + '东京', + '大阪', + '埼玉', + '沪日', + '穗日', + '川日', + '中日', + '泉日', + '杭日', + '深日', + '辽日', + '广日', + '大坂', + 'Osaka', + 'Tokyo', + ], + '🇰🇪': ['KE', 'KEN', 'Kenya', '肯尼亚'], + '🇰🇬': ['KG', 'KGZ', 'Kyrgyzstan', '吉尔吉斯斯坦'], + '🇰🇭': ['KH', 'KGZ', 'Cambodia', '柬埔寨'], + '🇰🇵': ['KP', 'PRK', 'North Korea', '朝鲜'], + '🇰🇷': ['KR', 'KOR', 'Korea', '韩国', '韩', '韓', + '首尔', '春川', 'Chuncheon', 'Seoul', ], - '🇱🇺': ['卢森堡'], - '🇱🇻': ['Latvia', 'Latvija', '拉脱维亚'], - '🇲🇽': ['MEX', 'MX', '墨西哥'], - '🇲🇾': [ - 'MY', - 'Malaysia', - 'MALAYSIA', - '马来西亚', - '大馬', - '馬來西亞', - '吉隆坡', - ], - '🇧🇾': ['BY', '白俄', '白俄罗斯'], - '🇳🇱': ['NL', 'Netherlands', '荷兰', '荷蘭', '尼德蘭', '阿姆斯特丹'], - '🇳🇵': ['尼泊尔'], + '🇰🇿': ['KZ', 'KAZ', 'Kazakhstan', '哈萨克斯坦', '哈萨克'], + '🇮🇩': ['ID', 'IDN', 'Indonesia', '印尼', '印度尼西亚', '雅加达'], + '🇮🇪': ['IE', 'IRL', 'Ireland', '爱尔兰', '愛爾蘭', '都柏林'], + '🇮🇱': ['IL', 'ISR', 'Israel', '以色列'], + '🇮🇲': ['IM', 'Isle of Man', '马恩岛', '馬恩島'], + '🇮🇳': ['IN', 'IND', 'India', '印度', '孟买', 'MFumbai'], + '🇮🇷': ['IR', 'IRN', 'Iran', '伊朗'], + '🇮🇸': ['IS', 'ISL', 'Iceland', '冰岛', '冰島'], + '🇮🇹': ['IT', 'ITA', 'Italy', '意大利', '義大利', '米兰', 'Nachash'], + '🇱🇹': ['LT', 'Lithuania', '立陶宛'], + '🇱🇺': ['LU', 'Luxembourg', '卢森堡'], + '🇱🇻': ['LV', 'Latvia', '拉脱维亚', 'Latvija'], + '🇲🇦': ['MA', 'Morocco', '摩洛哥'], + '🇲🇩': ['MD', 'Moldova', '摩尔多瓦', '摩爾多瓦'], + '🇳🇬': ['NG', 'Nigeria', '尼日利亚', '尼日利亞'], + '🇲🇰': ['MK', 'Macedonia', '马其顿', '馬其頓'], + '🇲🇳': ['MN', 'Mongolia', '蒙古'], + '🇲🇴': ['MO', 'MAC', 'Macao', '澳门', '澳門', 'CTM'], + '🇲🇹': ['MT', 'Malta', '马耳他'], + '🇲🇽': ['MX', 'MEX', 'Mexico', '墨西哥'], + '🇲🇾': ['MY', 'MYS', 'Malaysia', '马来西亚', '馬來西亞', '吉隆坡', '大馬'], + '🇳🇱': ['NL', 'NLD', 'Netherlands', '荷兰', '荷蘭', '尼德蘭', '阿姆斯特丹'], + '🇳🇴': ['NO', 'NOR', 'Norway', '挪威'], + '🇳🇵': ['NP', 'Nepal', '尼泊尔'], + '🇳🇿': ['NZ', 'NZL', 'New Zealand', '新西兰', '新西蘭'], + '🇵🇦': ['PA', 'Panama', '巴拿马'], + '🇵🇪': ['PE', 'Peru', '秘鲁', '祕魯'], '🇵🇭': ['PH', 'Philippines', '菲律宾', '菲律賓'], - '🇵🇷': ['PR', '波多黎各'], - '🇷🇴': ['RO', '罗马尼亚'], - '🇷🇺': [ - 'RU', - 'Russia', - '俄罗斯', + '🇵🇰': ['PK', 'Pakistan', '巴基斯坦'], + '🇵🇱': ['PL', 'POL', 'Poland', '波兰', '波蘭'], + '🇵🇷': ['PR', 'Puerto Rico', '波多黎各'], + '🇵🇹': ['PT', 'PRT', 'Portugal', '葡萄牙'], + '🇵🇾': ['PY', 'Paraguay', '巴拉圭'], + '🇷🇴': ['RO', 'Romania', '罗马尼亚'], + '🇷🇸': ['RS', 'Serbia', '塞尔维亚'], + '🇷🇪': ['RE', 'Réunion', '留尼汪', '法属留尼汪'], + '🇷🇺': ['RU', 'RUS', 'Russia', '俄罗斯', '俄国', '俄羅斯', '伯力', '莫斯科', '圣彼得堡', '西伯利亚', - '新西伯利亚', '京俄', '杭俄', '廣俄', @@ -157,18 +193,13 @@ export function getFlag(name) { '沪俄', 'Moscow', ], - '🇸🇦': ['沙特'], - '🇸🇪': ['SE', 'Sweden', '瑞典'], - '🇲🇹': ['马耳他'], - '🇲🇦': ['MA', '摩洛哥'], - '🇸🇬': [ - 'SG', - 'Singapore', - 'SINGAPORE', - '新加坡', + '🇸🇦': ['SA', 'SAU', 'Saudi', '沙特阿拉伯', '沙特'], + '🇸🇪': ['SE', 'SWE', 'Sweden', '瑞典'], + '🇸🇬': ['SG', 'SGP', 'Singapore', '新加坡', '狮城', '沪新', '京新', + '中新', '泉新', '穗新', '深新', @@ -177,13 +208,12 @@ export function getFlag(name) { '廣新', '滬新', ], - '🇹🇭': ['TH', 'Thailand', '泰国', '泰國', '曼谷'], - '🇹🇷': ['TR', 'Turkey', '土耳其', '伊斯坦布尔'], - '🇹🇼': [ - 'TW', - 'Taiwan', - 'TAIWAN', - '台湾', + '🇸🇮': ['SI', 'Slovenia', '斯洛文尼亚'], + '🇸🇰': ['SK', 'Slovakia', '斯洛伐克'], + '🇹🇭': ['TH', 'THA', 'Thailand', '泰国', '泰國', '曼谷'], + '🇹🇳': ['TN', 'Tunisia', '突尼斯'], + '🇹🇷': ['TR', 'TUR', 'Turkey', '土耳其', '伊斯坦布尔'], + '🇹🇼': ['TW', 'TWN', 'Taiwan', '台湾', '台北', '台中', '新北', @@ -193,12 +223,9 @@ export function getFlag(name) { 'HINET', 'Taipei', ], - '🇺🇸': [ - 'US', - 'USA', + '🇺🇦': ['UA', 'UKR', 'Ukraine', '乌克兰', '烏克蘭'], + '🇺🇸': ['US', 'USA', 'United States', '美国', 'America', - 'United States', - '美国', '美', '京美', '波特兰', @@ -221,91 +248,37 @@ export function getFlag(name) { 'San Jose', 'Sillicon Valley', 'Michigan', + 'LAX', + 'SFO' ], - '🇻🇳': ['VN', '越南', '胡志明市'], - '🇻🇪': ['VE', '委内瑞拉'], - '🇮🇹': ['Italy', 'IT', 'Nachash', '意大利', '米兰', '義大利'], - '🇿🇦': ['South Africa', '南非'], - '🇦🇪': ['United Arab Emirates', '阿联酋', '迪拜', 'AE'], - '🇧🇷': ['BR', 'Brazil', '巴西', '圣保罗'], - '🇯🇵': [ - 'JP', - 'Japan', - 'JAPAN', - '日本', - '东京', - '大阪', - '埼玉', - '沪日', - '穗日', - '川日', - '中日', - '泉日', - '杭日', - '深日', - '辽日', - '广日', - '大坂', - 'Osaka', - 'Tokyo', - ], - '🇦🇷': ['AR', '阿根廷'], - '🇳🇴': ['Norway', '挪威', 'NO'], - '🇨🇳': [ - 'CN', - 'China', - '回国', - '中国', - '中國', - '江苏', - '北京', - '上海', - '广州', - '深圳', - '杭州', - '徐州', - '青岛', - '宁波', - '镇江', - 'back', - ], - '🇵🇱': ['PL', 'POL', '波兰', '波蘭'], - '🇨🇱': ['智利'], - '🇳🇿': ['新西蘭', '新西兰'], - '🇬🇷': ['希腊', '希臘'], - '🇪🇬': ['埃及'], - '🇨🇾': ['CY', '塞浦路斯'], - '🇨🇷': ['CR', '哥斯达黎加'], - '🇸🇮': ['SI', '斯洛文尼亚'], - '🇱🇹': ['LT', '立陶宛'], - '🇵🇦': ['PA', '巴拿马'], - '🇹🇳': ['TN', '突尼斯'], - '🇮🇲': ['马恩岛', '馬恩島'], - '🇵🇹': ['葡萄牙'], - '🇰🇪': ['KE', '肯尼亚'], - '🇰🇬': ['KG', '吉尔吉斯坦'], - '🇯🇴': ['JO', '约旦'], - '🇺🇾': ['UY', '乌拉圭'], - '🇲🇳': ['蒙古'], - '🇮🇷': ['IR', '伊朗'], - '🇵🇪': ['秘鲁', '祕魯'], - '🇨🇴': ['哥伦比亚'], - '🇪🇪': ['爱沙尼亚'], - '🇪🇨': ['EC', '厄瓜多尔'], - '🇲🇰': ['马其顿', '馬其頓'], - '🇧🇦': ['波黑共和国', '波黑'], - '🇬🇪': ['格魯吉亞', '格鲁吉亚'], - '🇦🇱': ['阿爾巴尼亞', '阿尔巴尼亚'], - '🏳️‍🌈': ['流量', '时间', '应急', '过期', 'Bandwidth', 'expire'], + '🇺🇾': ['UY', 'Uruguay', '乌拉圭'], + '🇻🇪': ['VE', 'Venezuela', '委内瑞拉'], + '🇻🇳': ['VN', 'VNM', 'Vietnam', '越南', '胡志明'], + '🇿🇦': ['ZA', 'ZAF', 'South Africa', '南非'] }; - for (let k of Object.keys(flags)) { - if (flags[k].some((item) => name.indexOf(item) !== -1)) { - return k; + // 原旗帜或空 + let Flag = name.match(/[\uD83C][\uDDE6-\uDDFF][\uD83C][\uDDE6-\uDDFF]/)?.[0] || '🏴‍☠️' + // 旗帜匹配 + for (let flag of Object.keys(Flags)) { + const keywords = Flags[flag] + //console.log(`keywords = ${keywords}`) + // 精确匹配(两侧均有分割) + if (keywords.some(keyword => RegExp(`[^a-zA-Z]${keyword}[^a-zA-Z]`, "i").test(name))) { + //console.log(`new Flag1 = ${flag}`) + Flag = flag; + break; // 这里及时跳出,避免被之后的匹配覆盖结果 + // 半精确匹配(至少一侧有分隔符) + } else if (keywords.some(keyword => + RegExp(`[^a-zA-Z]${keyword}`, "i").test(name) || RegExp(`${keyword}[^a-zA-Z]`, "i").test(name) + )) { + //console.log(`new Flag2 = ${flag}`) + Flag = flag; + // 不精确匹配(只要包含就算) + } else if (keywords.some(keyword => RegExp(`${keyword}`, "i").test(name))) { + //console.log(`new Flag3 = ${flag}`) + Flag = flag; } } - // no flag found - const oldFlag = (name.match( - /[\uD83C][\uDDE6-\uDDFF][\uD83C][\uDDE6-\uDDFF]/, - ) || [])[0]; - return oldFlag || '🏴‍☠️'; + //console.log(`Final Flag = ${Flag}`) + return Flag }