Snorlax Ƶƶ( ̄▵—▵ ̄)

使用 Surge 的 Information Panel 編寫出口ip檢測腳本

如何使用 Surge 的 Information Panel 寫出出口 ip 檢測腳本?

Happy Lunar New Year 新年快樂,虎年順遂

Surge iOS 從 4.9.3 版本開始就支援了 information panel 這個功能,個人一直覺得是比較陽春的一個功能,實際能夠使用到的場景並不多,裝完 13 就沒用了。

动态模式原理(複製自 surge 論壇):

可通过脚本控制面板内容。

[Panel]
PanelB = title="Panel Title",content="Panel Content\nSecondLine",style=info,script-name=panel

[Script]
panel = script-path=panel.js,type=generic

这个版本同时引入了 generic 类型脚本,该类型脚本为泛用类型,可被多种功能所调用。

当用户点击刷新按钮时,脚本将被唤起,传入参数为

$input : {
    purpose: "panel",
    position: "policy-selection",
    panelName: "PanelB"
}

脚本应在 $done() 中返回 titlecontentstyle 字段。

在脚本被第一次运行前,面板内容为定义行中的静态内容,运行后 Surge 会自动缓存上一次脚本的返回结果,并在执行刷新前始终显示上一次的脚本结果。

脚本样例:

$httpClient.get("https://api.my-ip.io/ip", function (error, response, data) {
  $done({
    title: "External IP Address",
    content: data,
  });
});

更多自定义:

現有腳本的問題

在 GitHub 上逛了一圈發現大多數腳本(如這個)都是基於 ip-api 或者是 ipwhois 這類對於免費用戶僅支持 http 的 API 並且僅僅支持 IPv4。作爲 BGP Player (糊路由的),必須要來折騰一下。

從 0 開始成爲腳本小子

目前我找到的最合適的 API 是 ip.sb, 他們提供的接口支持免註冊獲取 IP Geo info,同時支援僅 IPv6/IPv4 請求 (https://api-ipv4.ip.sb/iphttps://api-ipv6.ip.sb/ip)

選好 API 以後就可以來看看返回的 json 格式了:

{
  "ip": "185.255.55.55",
  "country_code": "NL",
  "country": "Netherlands",
  "continent_code": "EU",
  "latitude": 52.3824,
  "longitude": 4.8995,
  "asn": "3214",
  "organization": "xTom Limited",
  "timezone": "Europe/Amsterdam"
}

我想要達成的效果是顯示 IP 地址和對應的 ASN 信息以及國家定位,地球 icon 會根據 IP 所在的大洲改變(🌍️🌎️🌏️)。我們需要 ip, country, country_code, continent_code, asnorganization 這五個值

let url = "https://api-ipv4.ip.sb/geoip";
//let url = "https://api-ipv6.ip.sb/geoip"

$httpClient.get(url, function (error, response, data) {
  let jsonData = JSON.parse(data);
  let ip = jsonData.ip;
  let country = jsonData.country;
  let emoji = getFlagEmoji(jsonData.country_code);
  let asn = jsonData.asn;
  let asOrg = jsonData.asn_organization;
  let continent = jsonData.continent_code;
  const icon = {
    AF: "globe.europe.africa.fill",
    AN: "globe",
    AS: "globe.asia.australia.fill",
    EU: "globe.europe.africa.fill",
    NA: "globe.americas.fill",
    OC: "globe.asia.australia.fill",
    SA: "globe.americas.fill",
    default: "globe",
  };

  body = {
    title: "IPv4 Info",
    content: `IPv4: ${ip}\nAS${asn} ${asOrg}\n${emoji} ${country}`,
    icon: icon[continent] || icon["default"],
  };
  $done(body);
});

function getFlagEmoji(countryCode) {
  const codePoints = countryCode
    .toUpperCase()
    .split("")
    .map((char) => 127397 + char.charCodeAt());
  return String.fromCodePoint(...codePoints);
}

之後將其上傳到 github(或者任何一個方便你更新的地方,並在 surge 配置中指向腳本地址即可):

[Panel]
IPv4 Network Info= script-name=IPv4 Network Info, title="IPv4 Network Info", content="Refresh", style=info, update-interval=60
IPv6 Network Info= script-name=IPv6 Network Info, title="IPv6 Network Info", content="Refresh", style=info, update-interval=60

[Script]
IPv4 Network Info= type=generic,timeout=3,script-path=https://raw.githubusercontent.com/Mr-Sheep/Random-Rules/master/Surge/Script/ipcheck-v4.js
IPv6 Network Info= type=generic,timeout=3,script-path=https://raw.githubusercontent.com/Mr-Sheep/Random-Rules/master/Surge/Script/ipcheck-v6.js

#Surge