Comments (12)
因为我没有plugin_opts节点,你试试下面这份ss解析代码是否可行。
def parse(data):
param = data[5:]
if not param or param.isspace():
return None
node = {
'tag':tool.genName(),
'type':'shadowsocks',
'server':None,
'server_port':0,
'method':None,
'password':None
}
if param.find('#') > -1:
remark = urllib.parse.unquote(param[param.find('#') + 1:])
node['tag'] = tool.rename(remark)
param = param[:param.find('#')]
if param.find('/?') > -1:
plugin = urllib.parse.unquote(param[param.find('/?') + 2:])
if plugin.startswith('obfs'):
node['plugin'] = 'obfs'
plugin_opts={}
param = param[:param.find('/?')]
for p in plugin.split(';'):
key_value = p.split('=')
kname = key_value[0]
pdict = {'obfs':'mode','obfs-host':'host'}
if kname in pdict.keys():
kname = pdict[kname]
plugin_opts[kname] = key_value[1]
node['plugin_opts']=re.sub(r"\{|\}", "", json.dumps(plugin_opts).replace(':','=').replace(',',';').replace('"',''))
if param.find('@') > -1:
matcher = re.match(r'(.*?)@(.*):(.*)', param)
if matcher:
param = matcher.group(1)
node['server'] = matcher.group(2)
node['server_port'] = matcher.group(3)
else:
return None
matcher = re.match(r'(.*?):(.*)', tool.urlDecode(param).decode('utf-8'))
if matcher:
node['method'] = matcher.group(1)
node['password'] = matcher.group(2)
else:
return None
else:
matcher = re.match(r'(.*?):(.*)@(.*):(.*)', tool.urlDecode(param).decode('utf-8'))
if matcher:
node['method'] = matcher.group(1)
node['password'] = matcher.group(2)
node['server'] = matcher.group(3)
node['server_port'] = matcher.group(4)
else:
return None
node['server_port'] = int(node['server_port'])
return node
上述代码有点臃肿,还是希望你能提供脱敏后的URI链接方便我改进代码。
from sing-box-subscribe.
刚看到,不好意思
试了这段代码,转换格式还是有点小问题
这是转换后的样子
"plugin_opts": "mode= http; host= FQ8W7pQAB7425fsdGjG.com"
有两处问题
= http还有= FQ8W7pQAB7425fsdGjG.com,这两个=后面多了空格
host=应该变成obfs-host= 和 mode= http应该变成obfs=http
我随便弄了一个SS的分享链接
ss://[email protected]:12345?plugin=obfs-local;obfs%3Dhttp;obfs-host%3DFQ8W7pQAB7425fsdGjG.com#TEST
可以试试这个SS链接,转换后正确的配置应该是这样子的
{
"tag": "TEST",
"type": "shadowsocks",
"server": "123456.com",
"server_port": 12345,
"method": "aes-128-gcm",
"password": "123456",
"plugin_opts": "obfs=http;obfs-host=FQ8W7pQAB7425fsdGjG.com"
},
期待最新的代码👍
from sing-box-subscribe.
刚看到,不好意思 试了这段代码,转换格式还是有点小问题 这是转换后的样子 "plugin_opts": "mode= http; host= FQ8W7pQAB7425fsdGjG.com" 有两处问题 = http还有= FQ8W7pQAB7425fsdGjG.com,这两个=后面多了空格 host=应该变成obfs-host= 和 mode= http应该变成obfs=http
我随便弄了一个SS的分享链接 ss://[email protected]:12345?plugin=obfs-local;obfs%3Dhttp;obfs-host%3DFQ8W7pQAB7425fsdGjG.com#TEST 可以试试这个SS链接,转换后正确的配置应该是这样子的
{ "tag": "TEST", "type": "shadowsocks", "server": "123456.com", "server_port": 12345, "method": "aes-128-gcm", "password": "123456", "plugin_opts": "obfs=http;obfs-host=FQ8W7pQAB7425fsdGjG.com" },
期待最新的代码👍
觉得你的URI链接有不规范的地方,'?'前面没有'/'吗?'?'后面确定是以plugin=开头的吗?如果是的话这是我根据你提供的改写的链接
ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTo4jRzMWY3YjFmNi1zY25vZGUtdHcwNy5iemx4emwuY29tOjU3MDI3?plugin=obfs-local;obfs%3Dhttp;obfs-host%3DFQ8W7pQAB7425fsdGjG.com#TEST
而且我查了一下singbox的 plugin还支持v2ray-plugin插件,方便的话你也给个v2ray-plugin的格式。我用小火箭导出的URI链接格式如下(居然不是?plugin=v2ray-plugin)
ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTo4jRzMWY3YjFmNi1zY25vZGUtdHcwNy5iemx4emwuY29tOjU3MDI3?v2ray-plugin=eyJ0bHMiOnRydWUsIm1vZGUiOiJodHRwMiIsImhvc3QiOiJjbG91ZC5jb20ifQ#%F0%9F%87%AD%F0%9F%87%B0%20%E9%A6%99%E6%B8%AF-20
那么代码里需要再加个判断
def parse(data):
param = data[5:]
if not param or param.isspace():
return None
node = {
'tag':tool.genName(),
'type':'shadowsocks',
'server':None,
'server_port':0,
'method':None,
'password':None
}
if param.find('#') > -1:
remark = urllib.parse.unquote(param[param.find('#') + 1:])
node['tag'] = tool.rename(remark)
param = param[:param.find('#')]
if param.find('?') > -1:
plugin = urllib.parse.unquote(param[param.find('?') + 1:])
if plugin.startswith('plugin'):
p1 = 0
node['plugin'] = plugin.split(';',1)[0].split('=')[1]
if plugin.startswith('v2ray-plugin'):
p1 =1
node['plugin'] = 'v2ray-plugin'
plugin = str(tool.b64Decode(plugin.split('=')[1]),'utf-8')
plugin_opts={}
param = param[:param.find('?')]
if p1 == 0 :
for p in plugin.split(';'):
key_value = p.split('=')
kname = key_value[0]
pdict = {'obfs':'mode','obfs-host':'host'}
if kname in pdict.keys():
#kname = pdict[kname]
plugin_opts[kname] = key_value[1]
if p1 == 1 :
plugin = eval(plugin.replace('true','1'))
for kname in plugin.keys():
pdict = {'mode':'obfs','host':'obfs-host'}
if kname in pdict.keys():
#kname = pdict[kname]
plugin_opts[kname] = plugin[kname]
node['plugin_opts']=re.sub(r"\{|\}|\s+", "", json.dumps(plugin_opts).replace(':','=').replace(',',';').replace('"',''))
if param.find('@') > -1:
matcher = re.match(r'(.*?)@(.*):(.*)', param)
if matcher:
param = matcher.group(1)
node['server'] = matcher.group(2)
node['server_port'] = matcher.group(3)
else:
return None
matcher = re.match(r'(.*?):(.*)', tool.urlDecode(param).decode('utf-8'))
if matcher:
node['method'] = matcher.group(1)
node['password'] = matcher.group(2)
else:
return None
else:
matcher = re.match(r'(.*?):(.*)@(.*):(.*)', tool.urlDecode(param).decode('utf-8'))
if matcher:
node['method'] = matcher.group(1)
node['password'] = matcher.group(2)
node['server'] = matcher.group(3)
node['server_port'] = matcher.group(4)
else:
return None
node['server_port'] = int(node['server_port'])
return node
from sing-box-subscribe.
之前给的那个是从NekoBox中导出的SS链接,可能不规范,我又从小火箭里导出了一遍,请试试这个链接
ss://[email protected]:123456?plugin=obfs-local;obfs=http;obfs-host=%7B%22Host%22:%22FQ8W7pQAAFX2Ho8y.com%22%7D;obfs-uri=/#TEST
新的代码我运行的时候会报错
Traceback (most recent call last):
File "E:\sing-box-subscribe\main.py", line 328, in
nodes = process_subscribes(providers["subscribes"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\sing-box-subscribe\main.py", line 38, in process_subscribes
_nodes = get_nodes(subscribe['url'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\sing-box-subscribe\main.py", line 97, in get_nodes
data = parse_content(content)
^^^^^^^^^^^^^^^^^^^^^^
File "E:\sing-box-subscribe\main.py", line 114, in parse_content
node = factory(t)
^^^^^^^^^^
File "E:\sing-box-subscribe\parsers\ss.py", line 69, in parse
node['server_port'] = int(node['server_port'])
^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: '12001/'
from sing-box-subscribe.
之前给的那个是从NekoBox中导出的SS链接,可能不规范,我又从小火箭里导出了一遍,请试试这个链接 ss://[email protected]:123456?plugin=obfs-local;obfs=http;obfs-host=%7B%22Host%22:%22FQ8W7pQAAFX2Ho8y.com%22%7D;obfs-uri=/#TEST
def parse(data):
param = data[5:]
if not param or param.isspace():
return None
node = {
'tag':tool.genName(),
'type':'shadowsocks',
'server':None,
'server_port':0,
'method':None,
'password':None
}
if param.find('#') > -1:
remark = urllib.parse.unquote(param[param.find('#') + 1:])
node['tag'] = tool.rename(remark)
param = param[:param.find('#')]
if param.find('?') > -1:
plugin = urllib.parse.unquote(param[param.find('?') + 1:])
if plugin.startswith('plugin'):
p1 = 0
node['plugin'] = plugin.split(';',1)[0].split('=')[1]
if plugin.startswith('v2ray-plugin'):
p1 =1
node['plugin'] = 'v2ray-plugin'
plugin = str(tool.b64Decode(plugin.split('=')[1]),'utf-8')
plugin_opts={}
param = param[:param.find('?')]
if p1 == 0 :
for p in plugin.split(';'):
key_value = p.split('=')
kname = key_value[0]
pdict = {'obfs':'mode','obfs-host':'host'}
if kname in pdict.keys():
#kname = pdict[kname]
plugin_opts[kname] = key_value[1]
if p1 == 1 :
plugin = eval(plugin.replace('true','1'))
for kname in plugin.keys():
pdict = {'mode':'obfs','host':'obfs-host'}
if kname in pdict.keys():
#kname = pdict[kname]
plugin_opts[kname] = plugin[kname]
node['plugin_opts']=re.sub(r"\{|\}|\"|\\|\:|\s+", "", json.dumps(plugin_opts).replace(':','=', 2).replace(',',';').replace('Host',''))
if param.find('@') > -1:
matcher = re.match(r'(.*?)@(.*):(.*)', param)
if matcher:
param = matcher.group(1)
node['server'] = matcher.group(2)
node['server_port'] = matcher.group(3)
else:
return None
matcher = re.match(r'(.*?):(.*)', tool.urlDecode(param).decode('utf-8'))
if matcher:
node['method'] = matcher.group(1)
node['password'] = matcher.group(2)
else:
return None
else:
matcher = re.match(r'(.*?):(.*)@(.*):(.*)', tool.urlDecode(param).decode('utf-8'))
if matcher:
node['method'] = matcher.group(1)
node['password'] = matcher.group(2)
node['server'] = matcher.group(3)
node['server_port'] = matcher.group(4)
else:
return None
node['server_port'] = int(node['server_port'])
return (node)
应该可以了
from sing-box-subscribe.
之前给的那个是从NekoBox中导出的SS链接,可能不规范,我又从小火箭里导出了一遍,请试试这个链接 ss://[email protected]:123456?plugin=obfs-local;obfs=http;obfs-host=%7B%22Host%22:%22FQ8W7pQAAFX2Ho8y.com%22%7D;obfs-uri=/#TEST
def parse(data): param = data[5:] if not param or param.isspace(): return None node = { 'tag':tool.genName(), 'type':'shadowsocks', 'server':None, 'server_port':0, 'method':None, 'password':None } if param.find('#') > -1: remark = urllib.parse.unquote(param[param.find('#') + 1:]) node['tag'] = tool.rename(remark) param = param[:param.find('#')] if param.find('?') > -1: plugin = urllib.parse.unquote(param[param.find('?') + 1:]) if plugin.startswith('plugin'): p1 = 0 node['plugin'] = plugin.split(';',1)[0].split('=')[1] if plugin.startswith('v2ray-plugin'): p1 =1 node['plugin'] = 'v2ray-plugin' plugin = str(tool.b64Decode(plugin.split('=')[1]),'utf-8') plugin_opts={} param = param[:param.find('?')] if p1 == 0 : for p in plugin.split(';'): key_value = p.split('=') kname = key_value[0] pdict = {'obfs':'mode','obfs-host':'host'} if kname in pdict.keys(): #kname = pdict[kname] plugin_opts[kname] = key_value[1] if p1 == 1 : plugin = eval(plugin.replace('true','1')) for kname in plugin.keys(): pdict = {'mode':'obfs','host':'obfs-host'} if kname in pdict.keys(): #kname = pdict[kname] plugin_opts[kname] = plugin[kname] node['plugin_opts']=re.sub(r"\{|\}|\"|\\|\:|\s+", "", json.dumps(plugin_opts).replace(':','=', 2).replace(',',';').replace('Host','')) if param.find('@') > -1: matcher = re.match(r'(.*?)@(.*):(.*)', param) if matcher: param = matcher.group(1) node['server'] = matcher.group(2) node['server_port'] = matcher.group(3) else: return None matcher = re.match(r'(.*?):(.*)', tool.urlDecode(param).decode('utf-8')) if matcher: node['method'] = matcher.group(1) node['password'] = matcher.group(2) else: return None else: matcher = re.match(r'(.*?):(.*)@(.*):(.*)', tool.urlDecode(param).decode('utf-8')) if matcher: node['method'] = matcher.group(1) node['password'] = matcher.group(2) node['server'] = matcher.group(3) node['server_port'] = matcher.group(4) else: return None node['server_port'] = int(node['server_port']) return (node)应该可以了
看图应该是OK了,但是我运行起来还是报错
PS E:\sing-box-subscribe> python main.py
1、config_template_groups_tun 2、config_template_tun
输入序号,载入对应config模板(直接回车默认选第一个配置模板):1
处理https://订阅链接
Traceback (most recent call last):
File "E:\sing-box-subscribe\main.py", line 328, in
nodes = process_subscribes(providers["subscribes"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\sing-box-subscribe\main.py", line 38, in process_subscribes
_nodes = get_nodes(subscribe['url'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\F\Sing-Box\sing-box-subscribe\main.py", line 97, in get_nodes
data = parse_content(content)
^^^^^^^^^^^^^^^^^^^^^^
File "E:\sing-box-subscribe\main.py", line 114, in parse_content
node = factory(t)
^^^^^^^^^^
File "E:\sing-box-subscribe\parsers\ss.py", line 68, in parse
node['server_port'] = int(node['server_port'])
^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: '10001/'
🤣🤣🤣
from sing-box-subscribe.
用你原始的订阅链接,只删除其中一些字符或修改给我。怎么确定删除的是不痛不痒的,请这样操作:
以这条URI链接为例:
ss://[email protected]:123456?plugin=obfs-local;obfs=http;obfs-host=%7B%22Host%22:%22FQ8W7pQAAFX2Ho8y.com%22%7D;obfs-uri=/#TEST
URI链接去掉ss://,剩下的部分拿去url解码,删掉你认为可以脱敏且不影响原链接的字符
@前面的长英文字符串拿去base64解码,得到 “加密方式:密码”。把密码修改后再重新base64编码得到新的长英文字符串
https://www.urldecoder.org/
https://www.base64decode.org/
修改后发给我链接
from sing-box-subscribe.
用你原始的订阅链接,只删除其中一些字符或修改给我。怎么确定删除的是不痛不痒的,请这样操作: 以这条URI链接为例:
ss://[email protected]:123456?plugin=obfs-local;obfs=http;obfs-host=%7B%22Host%22:%22FQ8W7pQAAFX2Ho8y.com%22%7D;obfs-uri=/#TEST
URI链接去掉ss://,剩下的部分拿去url解码,删掉你认为可以脱敏且不影响原链接的字符
@前面的长英文字符串拿去base64解码,得到 “加密方式:密码”。把密码修改后再重新base64编码得到新的长英文字符串
https://www.urldecoder.org/ https://www.base64decode.org/
修改后发给我链接
我这是从机场订阅中拿出来的节点,可能我改的不对吧,这是机场Clash订阅拿下来的原版配置,我就改了密码和server,我就不改了,怕又不行
- name: 🇭🇰 HKG 1
type: ss
server: hkg.com
port: "10119"
cipher: aes-128-gcm
password: hkgcom
udp: true
plugin: obfs
plugin-opts:
mode: http
host: FQ8W7pQAAFX2Ho8y.download.windowsupdate.com
from sing-box-subscribe.
我这是从机场订阅中拿出来的节点,可能我改的不对吧,这是机场Clash订阅拿下来的原版配置,我就改了密码和server,我就不改了,怕又不行
- name: 🇭🇰 HKG 1 type: ss server: hkg.com port: "10119" cipher: aes-128-gcm password: hkgcom udp: true plugin: obfs plugin-opts: mode: http host: FQ8W7pQAAFX2Ho8y.download.windowsupdate.com
clash格式不行,我这解析的是v2订阅。
请你复制机场提供的v2订阅到浏览器打开它,出现一串base64编码信息。全选复制到base64解码网站解码,找到ss://链接,然后进行我上述的脱敏操作。
from sing-box-subscribe.
我这是从机场订阅中拿出来的节点,可能我改的不对吧,这是机场Clash订阅拿下来的原版配置,我就改了密码和server,我就不改了,怕又不行
- name: 🇭🇰 HKG 1 type: ss server: hkg.com port: "10119" cipher: aes-128-gcm password: hkgcom udp: true plugin: obfs plugin-opts: mode: http host: FQ8W7pQAAFX2Ho8y.download.windowsupdate.com
clash格式不行,我这解析的是v2订阅。
请你复制机场提供的v2订阅到浏览器打开它,出现一串base64编码信息。全选复制到base64解码网站解码,找到ss://链接,然后进行我上述的脱敏操作。
这样这样应该没问题了,完全按照操作说明弄了一遍
c3M6Ly9ZV1Z6TFRFeU9DMW5ZMjA2Y0dGemMzZHZjbVE9QHRlc3QuY29tOjEwMDAwLz9wbHVnaW49b2Jmcy1sb2NhbDtvYmZzPWh0dHA7b2Jmcy1ob3N0PUZROFc3cFFBQUZYMkhvOHkuZG93bmxvYWQud2luZG93c3VwZGF0ZS5jb20mZ3JvdXA9VkVWVFZBPT0j8J+HrfCfh7AgSEtHIDAx
修改了server,端口,密码
from sing-box-subscribe.
def parse(data):
param = data[5:]
if not param or param.isspace():
return None
node = {
'tag':tool.genName(),
'type':'shadowsocks',
'server':None,
'server_port':0,
'method':None,
'password':None
}
if param.find('#') > -1:
remark = urllib.parse.unquote(param[param.find('#') + 1:])
node['tag'] = tool.rename(remark)
param = param[:param.find('#')]
if param.find('/?') > -1:
plugin = urllib.parse.unquote(param[param.find('/?') + 2:])
if plugin.startswith('plugin'):
p1 = 0
node['plugin'] = plugin.split(';',1)[0].split('=')[1]
if plugin.startswith('v2ray-plugin'):
p1 =1
node['plugin'] = 'v2ray-plugin'
plugin = str(tool.b64Decode(plugin.split('=')[1]),'utf-8')
plugin_opts={}
param = param[:param.find('/?')]
if p1 == 0 :
for p in plugin.split(';'):
key_value = p.split('=')
kname = key_value[0]
pdict = {'obfs':'mode','obfs-host':'host'}
if kname in pdict.keys():
#kname = pdict[kname]
plugin_opts[kname] = key_value[1]
if p1 == 1 :
plugin = eval(plugin.replace('true','1'))
for kname in plugin.keys():
pdict = {'mode':'obfs','host':'obfs-host'}
if kname in pdict.keys():
#kname = pdict[kname]
plugin_opts[kname] = plugin[kname]
node['plugin_opts']=re.sub(r"\{|\}|\"|\\|\:|\&|\s+", "", json.dumps(plugin_opts).replace(':','=', 2).replace(',',';').replace('Host','').replace('group',''))
if param.find('@') > -1:
matcher = re.match(r'(.*?)@(.*):(.*)', param)
if matcher:
param = matcher.group(1)
node['server'] = matcher.group(2)
node['server_port'] = matcher.group(3)
else:
return None
matcher = re.match(r'(.*?):(.*)', tool.urlDecode(param).decode('utf-8'))
if matcher:
node['method'] = matcher.group(1)
node['password'] = matcher.group(2)
else:
return None
else:
matcher = re.match(r'(.*?):(.*)@(.*):(.*)', tool.urlDecode(param).decode('utf-8'))
if matcher:
node['method'] = matcher.group(1)
node['password'] = matcher.group(2)
node['server'] = matcher.group(3)
node['server_port'] = matcher.group(4)
else:
return None
node['server_port'] = int(node['server_port'])
return node
根据你的显示,订阅链接格式应该是这样的(请和机场的链接对比看是不是无误):
ss://YWVzLTEyOC1nY206cGFzc3dvcmRAdGVzdC5jb206MTIzNDU2/?plugin%3Dobfs-local%3Bobfs%3Dhttp%3Bobfs-host%3DFQ8W7pQAAFX2Ho8y.download.windowsupdate.com%26group%3DVEVTVA%3D%3D#%F0%9F%87%AD%F0%9F%87%B0%20HKG%2001
我不知道&group=VEVTVA==
是什么就直接删了
你再试试
from sing-box-subscribe.
非常感谢,这次没有问题了,正常输出,导入到singbox中也没有报错了👍👍👍
from sing-box-subscribe.
Related Issues (20)
- 请问我的机场提供singbox订阅链接,可以把多个singbox订阅链接合并吗,提取出来节点用自己的规则 HOT 8
- 对于多个要转换的文件,其中一个若发生错误直接跳过并进行下一步,而不是只要其中一个文件转换错误就退出执行了 HOT 3
- 新更新的模板出现错误。需清理缓存 HOT 4
- clash格式的UoT配置在转换时丢失 HOT 6
- 请问可以使用cloudflare pages部署吗 HOT 1
- 请问使用本地部署怎样通过url进行转换 HOT 7
- parsers/clash2base64.py 的 wireguard 部分的修改建议 HOT 2
- 作者你好,网页端的默认 `providers.json` 信息需要在哪里修改?我直接修改 `providers.json` 并没有生效 HOT 6
- 相同的节点,转换完到客户端就会报错。 HOT 10
- 改进:能否考虑从机场导入节点时就排除一些协议。 HOT 1
- `enn`参数是排除关键词 HOT 2
- 刚刚更新的打不开网站 HOT 1
- 能做个本地分流模版么,就是把远程的srs文件下载到本地读取。 HOT 1
- 请大佬指点:指定名称,指定协议,参数写法。 HOT 2
- 不同类型订阅链接支持问题 HOT 7
- 下午突然就这样。 HOT 1
- 提供多个机场的URL时,如果其中有一个机场出错,程序在跳过该机场时会出错 HOT 4
- 咋回事捏?俺也500了
- 更新之后,转换失败了。 HOT 2
- 服务器部署,通过直链订阅,直链的配置文件并没有更新,但是服务端的config.json更新了 HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sing-box-subscribe.