hiddifypanel 10.11.0__py3-none-any.whl → 10.11.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. hiddifypanel/VERSION +1 -1
  2. hiddifypanel/VERSION.py +2 -2
  3. hiddifypanel/hutils/proxy/shared.py +2 -0
  4. hiddifypanel/hutils/proxy/singbox.py +30 -30
  5. hiddifypanel/hutils/proxy/xray.py +353 -11
  6. hiddifypanel/panel/admin/SettingAdmin.py +22 -11
  7. hiddifypanel/panel/init_db.py +1 -1
  8. hiddifypanel/panel/user/templates/base_xray_config.json.j2 +125 -0
  9. hiddifypanel/panel/user/user.py +9 -1
  10. hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
  11. hiddifypanel/translations/en/LC_MESSAGES/messages.po +3 -6
  12. hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
  13. hiddifypanel/translations/fa/LC_MESSAGES/messages.po +3 -6
  14. hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
  15. hiddifypanel/translations/pt/LC_MESSAGES/messages.po +0 -3
  16. hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
  17. hiddifypanel/translations/ru/LC_MESSAGES/messages.po +3 -6
  18. hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
  19. hiddifypanel/translations/zh/LC_MESSAGES/messages.po +0 -3
  20. hiddifypanel/translations.i18n/en.json +3 -4
  21. hiddifypanel/translations.i18n/fa.json +3 -4
  22. hiddifypanel/translations.i18n/pt.json +0 -1
  23. hiddifypanel/translations.i18n/ru.json +3 -4
  24. hiddifypanel/translations.i18n/zh.json +0 -1
  25. {hiddifypanel-10.11.0.dist-info → hiddifypanel-10.11.1.dist-info}/METADATA +1 -1
  26. {hiddifypanel-10.11.0.dist-info → hiddifypanel-10.11.1.dist-info}/RECORD +30 -29
  27. {hiddifypanel-10.11.0.dist-info → hiddifypanel-10.11.1.dist-info}/LICENSE.md +0 -0
  28. {hiddifypanel-10.11.0.dist-info → hiddifypanel-10.11.1.dist-info}/WHEEL +0 -0
  29. {hiddifypanel-10.11.0.dist-info → hiddifypanel-10.11.1.dist-info}/entry_points.txt +0 -0
  30. {hiddifypanel-10.11.0.dist-info → hiddifypanel-10.11.1.dist-info}/top_level.txt +0 -0
hiddifypanel/VERSION CHANGED
@@ -1 +1 @@
1
- 10.11.0
1
+ 10.11.1
hiddifypanel/VERSION.py CHANGED
@@ -1,3 +1,3 @@
1
- __version__='10.11.0'
1
+ __version__='10.11.1'
2
2
  from datetime import datetime
3
- __release_date__= datetime.strptime('2024-03-15','%Y-%m-%d')
3
+ __release_date__= datetime.strptime('2024-03-16','%Y-%m-%d')
@@ -317,6 +317,8 @@ def make_proxy(hconfigs: dict, proxy: Proxy, domain_db: Domain, phttp=80, ptls=4
317
317
  base['cipher'] = hconfigs[ConfigEnum.shadowsocks2022_method]
318
318
  base['password'] = f'{hutils.encode.do_base_64(hconfigs[ConfigEnum.shared_secret].replace("-",""))}:{hutils.encode.do_base_64(g.account.uuid.replace("-",""))}'
319
319
 
320
+ if base['proto'] == 'trojan':
321
+ base['password'] = base['uuid']
320
322
  if base["proto"] == "ssr":
321
323
  base["ssr-obfs"] = "tls1.2_ticket_auth"
322
324
  base["ssr-protocol"] = "auth_sha1_v4"
@@ -6,7 +6,7 @@ from hiddifypanel.models import ProxyProto, ProxyTransport, Domain, ConfigEnum,
6
6
  from hiddifypanel.panel.hiddify import is_hiddify_next_version
7
7
 
8
8
 
9
- def make_full_singbox_config(domains: list[Domain], **kwargs) -> str:
9
+ def configs_as_json(domains: list[Domain], **kwargs) -> str:
10
10
  ua = hutils.flask.get_user_agent()
11
11
  base_config = json.loads(render_template('base_singbox_config.json.j2'))
12
12
  allphttp = [p for p in request.args.get("phttp", "").split(',') if p]
@@ -60,32 +60,32 @@ def to_singbox(proxy: dict) -> list[dict] | dict:
60
60
  base["server_port"] = int(proxy["port"])
61
61
  # base['alpn'] = proxy['alpn'].split(',')
62
62
  if proxy["proto"] == "ssr":
63
- add_singbox_ssr(base, proxy)
63
+ add_ssr(base, proxy)
64
64
  return all_base
65
65
  if proxy["proto"] == ProxyProto.wireguard:
66
- add_singbox_wireguard(base, proxy)
66
+ add_wireguard(base, proxy)
67
67
  return all_base
68
68
 
69
69
  if proxy["proto"] in ["ss", "v2ray"]:
70
- add_singbox_shadowsocks_base(all_base, proxy)
70
+ add_shadowsocks_base(all_base, proxy)
71
71
  return all_base
72
72
  if proxy["proto"] == "ssh":
73
- add_singbox_ssh(all_base, proxy)
73
+ add_ssh(all_base, proxy)
74
74
  return all_base
75
75
 
76
76
  if proxy["proto"] == "trojan":
77
- base["password"] = proxy["uuid"]
77
+ base["password"] = proxy["password"]
78
78
 
79
79
  if proxy['proto'] in ['vmess', 'vless']:
80
80
  base["uuid"] = proxy["uuid"]
81
81
 
82
82
  if proxy['proto'] in ['vmess', 'vless', 'trojan']:
83
- add_singbox_multiplex(base)
83
+ add_multiplex(base)
84
84
 
85
- add_singbox_tls(base, proxy)
85
+ add_tls(base, proxy)
86
86
 
87
87
  if g.user_agent.get('is_hiddify'):
88
- add_singbox_tls_tricks(base, proxy)
88
+ add_tls_tricks(base, proxy)
89
89
 
90
90
  if proxy.get('flow'):
91
91
  base["flow"] = proxy['flow']
@@ -100,16 +100,16 @@ def to_singbox(proxy: dict) -> list[dict] | dict:
100
100
  base["packet_encoding"] = "xudp" # udp packet encoding
101
101
 
102
102
  if proxy["proto"] == "tuic":
103
- add_singbox_tuic(base, proxy)
103
+ add_tuic(base, proxy)
104
104
  elif proxy["proto"] == "hysteria2":
105
- add_singbox_hysteria(base, proxy)
105
+ add_hysteria(base, proxy)
106
106
  else:
107
- add_singbox_transport(base, proxy)
107
+ add_transport(base, proxy)
108
108
 
109
109
  return all_base
110
110
 
111
111
 
112
- def add_singbox_multiplex(base: dict):
112
+ def add_multiplex(base: dict):
113
113
  if not hconfig(ConfigEnum.mux_enable):
114
114
  return
115
115
  base['multiplex'] = {
@@ -125,10 +125,10 @@ def add_singbox_multiplex(base: dict):
125
125
  base['multiplex']['max_connections'] = int(hconfig(ConfigEnum.mux_max_connections))
126
126
  base['multiplex']['min_streams'] = int(hconfig(ConfigEnum.mux_min_streams))
127
127
 
128
- add_singbox_tcp_brutal(base)
128
+ add_tcp_brutal(base)
129
129
 
130
130
 
131
- def add_singbox_tcp_brutal(base: dict):
131
+ def add_tcp_brutal(base: dict):
132
132
  if 'multiplex' in base:
133
133
  base['multiplex']['brutal'] = {
134
134
  "enabled": hconfig(ConfigEnum.mux_brutal_enable),
@@ -137,14 +137,14 @@ def add_singbox_tcp_brutal(base: dict):
137
137
  }
138
138
 
139
139
 
140
- def add_singbox_udp_over_tcp(base: dict):
140
+ def add_udp_over_tcp(base: dict):
141
141
  base['udp_over_tcp'] = {
142
142
  "enabled": True,
143
143
  "version": 2
144
144
  }
145
145
 
146
146
 
147
- def add_singbox_tls(base: dict, proxy: dict):
147
+ def add_tls(base: dict, proxy: dict):
148
148
  if not ("tls" in proxy["l3"] or "reality" in proxy["l3"]):
149
149
  return
150
150
  base["tls"] = {
@@ -170,7 +170,7 @@ def add_singbox_tls(base: dict, proxy: dict):
170
170
  # }
171
171
 
172
172
 
173
- def add_singbox_tls_tricks(base: dict, proxy: dict):
173
+ def add_tls_tricks(base: dict, proxy: dict):
174
174
  if proxy.get('tls_fragment_enable'):
175
175
  base['tls_fragment'] = {
176
176
  'enabled': True,
@@ -188,7 +188,7 @@ def add_singbox_tls_tricks(base: dict, proxy: dict):
188
188
  base['tls']['tls_tricks']['mixedcase_sni'] = True
189
189
 
190
190
 
191
- def add_singbox_transport(base: dict, proxy: dict):
191
+ def add_transport(base: dict, proxy: dict):
192
192
  if proxy['l3'] == 'reality' and proxy['transport'] not in ["grpc"]:
193
193
  return
194
194
  base["transport"] = {}
@@ -213,10 +213,10 @@ def add_singbox_transport(base: dict, proxy: dict):
213
213
  base["transport"] = {
214
214
  "type": "http",
215
215
  "path": proxy.get("path", ""),
216
- # "method": "",
217
- # "headers": {},
218
216
  "idle_timeout": "15s",
219
217
  "ping_timeout": "15s"
218
+ # "method": "",
219
+ # "headers": {},
220
220
  }
221
221
 
222
222
  if 'host' in proxy:
@@ -232,7 +232,7 @@ def add_singbox_transport(base: dict, proxy: dict):
232
232
  }
233
233
 
234
234
 
235
- def add_singbox_ssr(base: dict, proxy: dict):
235
+ def add_ssr(base: dict, proxy: dict):
236
236
 
237
237
  base["method"] = proxy["cipher"]
238
238
  base["password"] = proxy["uuid"]
@@ -242,7 +242,7 @@ def add_singbox_ssr(base: dict, proxy: dict):
242
242
  base["protocol-param"] = proxy["fakedomain"]
243
243
 
244
244
 
245
- def add_singbox_wireguard(base: dict, proxy: dict):
245
+ def add_wireguard(base: dict, proxy: dict):
246
246
 
247
247
  base["local_address"] = f'{proxy["wg_ipv4"]}/32'
248
248
  base["private_key"] = proxy["wg_pk"]
@@ -255,13 +255,13 @@ def add_singbox_wireguard(base: dict, proxy: dict):
255
255
  base["fake_packets"] = proxy["wg_noise_trick"]
256
256
 
257
257
 
258
- def add_singbox_shadowsocks_base(all_base: list[dict], proxy: dict):
258
+ def add_shadowsocks_base(all_base: list[dict], proxy: dict):
259
259
  base = all_base[0]
260
260
  base["type"] = "shadowsocks"
261
261
  base["method"] = proxy["cipher"]
262
262
  base["password"] = proxy["password"]
263
- add_singbox_udp_over_tcp(base)
264
- add_singbox_multiplex(base)
263
+ add_udp_over_tcp(base)
264
+ add_multiplex(base)
265
265
  if proxy["transport"] == "faketls":
266
266
  base["plugin"] = "obfs-local"
267
267
  base["plugin_opts"] = f'obfs=tls;obfs-host={proxy["fakedomain"]}'
@@ -290,13 +290,13 @@ def add_singbox_shadowsocks_base(all_base: list[dict], proxy: dict):
290
290
  # "alpn": proxy['alpn'].split(',')
291
291
  }
292
292
  }
293
- # add_singbox_utls(shadowtls_base)
293
+ # add_utls(shadowtls_base)
294
294
  del base['server']
295
295
  del base['server_port']
296
296
  all_base.append(shadowtls_base)
297
297
 
298
298
 
299
- def add_singbox_ssh(all_base: list[dict], proxy: dict):
299
+ def add_ssh(all_base: list[dict], proxy: dict):
300
300
  base = all_base[0]
301
301
  # base["client_version"]= "{{ssh_client_version}}"
302
302
  base["user"] = proxy['uuid']
@@ -317,7 +317,7 @@ def add_singbox_ssh(all_base: list[dict], proxy: dict):
317
317
  all_base.append(socks_front)
318
318
 
319
319
 
320
- def add_singbox_tuic(base: dict, proxy: dict):
320
+ def add_tuic(base: dict, proxy: dict):
321
321
  base['congestion_control'] = "cubic"
322
322
  base['udp_relay_mode'] = 'native'
323
323
  base['zero_rtt_handshake'] = True
@@ -326,7 +326,7 @@ def add_singbox_tuic(base: dict, proxy: dict):
326
326
  base['uuid'] = proxy['uuid']
327
327
 
328
328
 
329
- def add_singbox_hysteria(base: dict, proxy: dict):
329
+ def add_hysteria(base: dict, proxy: dict):
330
330
  base['up_mbps'] = int(hconfig(ConfigEnum.hysteria_up_mbps))
331
331
  base['down_mbps'] = int(hconfig(ConfigEnum.hysteria_down_mbps))
332
332
  # TODO: check the obfs should be empty or not exists at all
@@ -1,10 +1,13 @@
1
1
  import datetime
2
2
  import json
3
- from flask import request, g
3
+ import copy
4
+ from flask import render_template, request, g
4
5
  from hiddifypanel import hutils
5
6
  from hiddifypanel.models import Proxy, ProxyTransport, ProxyL3, ProxyCDN, ProxyProto, Domain, hconfig, ConfigEnum, DomainType
6
7
  from flask_babel import gettext as _
7
8
 
9
+ OUTBOUND_LEVEL = 8
10
+
8
11
 
9
12
  def to_link(proxy: dict) -> str | dict:
10
13
  if 'error' in proxy:
@@ -180,10 +183,343 @@ def make_v2ray_configs(user, user_activate, domains: list[Domain], expire_days,
180
183
  return "\n".join(res)
181
184
 
182
185
 
183
- def add_tls_tricks_to_link(proxy: dict) -> str:
184
- out = {}
185
- add_tls_tricks_to_dict(out, proxy)
186
- return hutils.encode.convert_dict_to_url(out)
186
+ def configs_as_json(domains: list[Domain], remarks: str) -> str:
187
+ '''Returns xray configs as json'''
188
+ outbounds = []
189
+ for proxy in hutils.proxy.get_valid_proxies(domains):
190
+ outbound = to_xray(proxy)
191
+ if 'msg' not in outbound:
192
+ outbounds.append(outbound)
193
+
194
+ outbounds_len = len(outbounds)
195
+ # reutrn no outbound
196
+ if outbounds_len < 1:
197
+ return ''
198
+
199
+ all_configs = []
200
+ base_config = json.loads(render_template('base_xray_config.json.j2', remarks=remarks))
201
+ # multiple outbounds needs multiple whole base config not just one with multiple outbounds (at least for v2rayng)
202
+ # https://github.com/2dust/v2rayNG/pull/2827#issue-2127534078
203
+ if outbounds_len > 1:
204
+ for out in outbounds:
205
+ base_config['remarks'] = out['tag']
206
+ base_config['outbounds'].insert(0, out)
207
+ all_configs.append(copy.deepcopy(base_config))
208
+ del base_config['outbounds'][0]
209
+ else: # single outbound
210
+ base_config['outbounds'].insert(0, outbounds[0])
211
+ all_configs = base_config
212
+
213
+ json_configs = json.dumps(all_configs, indent=2, cls=hutils.proxy.ProxyJsonEncoder)
214
+ return json_configs
215
+
216
+
217
+ def to_xray(proxy: dict) -> dict:
218
+ outbound = {
219
+ 'tag': f'{proxy["extra_info"]} {proxy["name"]} § {proxy["port"]} {proxy["dbdomain"].id}',
220
+ 'protocol': str(proxy['proto']),
221
+ 'settings': {},
222
+ 'streamSettings': {},
223
+ 'mux': { # default value
224
+ 'enabled': False,
225
+ 'concurrency': -1
226
+ }
227
+ }
228
+ # add multiplex to outbound
229
+ add_multiplex(outbound)
230
+
231
+ # add stream setting to outbound
232
+ add_stream_settings(outbound, proxy)
233
+
234
+ # add protocol settings to outbound
235
+ add_proto_settings(outbound, proxy)
236
+
237
+ return outbound
238
+
239
+ # region proto settings
240
+
241
+
242
+ def add_proto_settings(base: dict, proxy: dict):
243
+ if proxy['proto'] == ProxyProto.wireguard:
244
+ add_wireguard_settings(base, proxy)
245
+ elif proxy['proto'] == ProxyProto.ss:
246
+ add_shadowsocks_settings(base, proxy)
247
+ elif proxy['proto'] == ProxyProto.vless:
248
+ add_vless_settings(base, proxy)
249
+ elif proxy['proto'] == ProxyProto.vmess:
250
+ add_vmess_settings(base, proxy)
251
+ elif proxy['proto'] == ProxyProto.trojan:
252
+ proxy['password'] = proxy['uuid']
253
+ add_trojan_settings(base, proxy)
254
+
255
+
256
+ def add_wireguard_settings(base: dict, proxy: dict):
257
+
258
+ base['settings']['secretKey'] = proxy['wg_pk']
259
+ base['settings']['reversed'] = [0, 0, 0]
260
+ base['settings']['mtu'] = 1380 # optional
261
+ base['settings']['peers'] = [{
262
+ 'endpoint': f'{proxy["server"]}:{int(proxy["port"])}',
263
+ 'publicKey': proxy["wg_server_pub"]
264
+ # 'allowedIPs':'', 'preSharedKey':'', 'keepAlive':'' # optionals
265
+ }]
266
+
267
+ # optionals
268
+ # base['settings']['address'] = [f'{proxy["wg_ipv4"]}/32',f'{proxy["wg_ipv6"]}/128']
269
+ # base['settings']['workers'] = 4
270
+ # base['settings']['domainStrategy'] = 'ForceIP' # default
271
+
272
+
273
+ def add_vless_settings(base: dict, proxy: dict):
274
+ base['settings']['vnext'] = [
275
+ {
276
+ 'address': proxy['server'],
277
+ 'port': proxy['port'],
278
+ "users": [
279
+ {
280
+ 'id': proxy['uuid'],
281
+ 'encryption': 'none',
282
+ # 'security': 'auto',
283
+ 'flow': 'xtls-rprx-vision' if (proxy['transport'] == ProxyTransport.XTLS or base['streamSettings']['security'] == 'reality') else '',
284
+ 'level': OUTBOUND_LEVEL
285
+ }
286
+ ]
287
+ }
288
+ ]
289
+
290
+
291
+ def add_vmess_settings(base: dict, proxy: dict):
292
+ base['settings']['vnext'] = [
293
+ {
294
+ "address": proxy['server'],
295
+ "port": proxy['port'],
296
+ "users": [
297
+ {
298
+ "id": proxy['uuid'],
299
+ "security": proxy['cipher'],
300
+ "level": OUTBOUND_LEVEL
301
+ }
302
+ ]
303
+ }
304
+ ]
305
+
306
+
307
+ def add_trojan_settings(base: dict, proxy: dict):
308
+ base['settings']['servers'] = [
309
+ {
310
+ # 'email': proxy['uuid'], optional
311
+ 'address': proxy['server'],
312
+ 'port': proxy['port'],
313
+ 'password': proxy['password'],
314
+ 'level': OUTBOUND_LEVEL
315
+ }
316
+ ]
317
+
318
+
319
+ def add_shadowsocks_settings(base: dict, proxy: dict):
320
+ base['settings']['servers'] = [
321
+ {
322
+ 'address': proxy['server'],
323
+ 'port': proxy['port'],
324
+ 'method': proxy['cipher'],
325
+ 'password': proxy['password'],
326
+ 'uot': True,
327
+ 'level': OUTBOUND_LEVEL
328
+ # 'email': '', optional
329
+ }
330
+ ]
331
+
332
+ # endregion
333
+
334
+
335
+ # region stream settings
336
+
337
+ def add_stream_settings(base: dict, proxy: dict):
338
+ ss = base['streamSettings']
339
+ ss['security'] = 'none' # default
340
+
341
+ # security
342
+ if proxy['l3'] == ProxyL3.reality:
343
+ ss['security'] = 'reality'
344
+ elif proxy['l3'] in [ProxyL3.tls, ProxyL3.tls_h2, ProxyL3.tls_h2_h1]:
345
+ ss['security'] = 'tls'
346
+
347
+ # network and transport settings
348
+ if ss['security'] == 'tls' or 'xtls':
349
+ ss['tlsSettings'] = {
350
+ 'serverName': proxy['sni'],
351
+ 'allowInsecure': proxy['allow_insecure'],
352
+ 'fingerprint': proxy['fingerprint'],
353
+ 'alpn': [proxy['alpn']],
354
+ # 'minVersion': '1.2',
355
+ # 'disableSystemRoot': '',
356
+ # 'enableSessionResumption': '',
357
+ # 'pinnedPeerCertificateChainSha256': '',
358
+ # 'certificates': '',
359
+ # 'maxVersion': '1.3', # Go lang sets
360
+ # 'cipherSuites': '', # Go lang sets
361
+ # 'rejectUnknownSni': '', # default is false
362
+ }
363
+ if ss['security'] == 'reality':
364
+ ss['network'] = proxy['transport']
365
+ add_reality_stream(ss, proxy)
366
+ if proxy['l3'] == ProxyL3.kcp:
367
+ ss['network'] = 'kcp'
368
+ add_kcp_stream(ss, proxy)
369
+
370
+ if proxy['l3'] == ProxyL3.h3_quic:
371
+ add_quic_stream(ss, proxy)
372
+
373
+ if proxy['transport'] == 'tcp' or ss['security'] == 'reality' or (ss['security'] == 'none' and proxy['transport'] not in [ProxyTransport.httpupgrade, ProxyTransport.WS]):
374
+ ss['network'] = proxy['transport']
375
+ add_tcp_stream(ss, proxy)
376
+ if proxy['transport'] == ProxyTransport.h2 and ss['security'] == 'none' and ss['security'] != 'reality':
377
+ ss['network'] = proxy['transport']
378
+ add_http_stream(ss, proxy)
379
+ if proxy['transport'] == ProxyTransport.grpc:
380
+ ss['network'] = proxy['transport']
381
+ add_grpc_stream(ss, proxy)
382
+ if proxy['transport'] == ProxyTransport.httpupgrade:
383
+ ss['network'] = proxy['transport']
384
+ add_httpupgrade_stream(ss, proxy)
385
+ if proxy['transport'] == 'ws':
386
+ ss['network'] = proxy['transport']
387
+ add_ws_stream(ss, proxy)
388
+
389
+ # tls fragmentaion
390
+ add_tls_fragmentation_stream_settings(base)
391
+
392
+
393
+ def add_tcp_stream(ss: dict, proxy: dict):
394
+ if proxy['l3'] == ProxyL3.http:
395
+ ss['tcpSettings'] = {
396
+ 'header': {
397
+ 'type': 'http',
398
+ 'request': {
399
+ 'path': [proxy['path']]
400
+ }
401
+ }
402
+ # 'acceptProxyProtocol': False
403
+ }
404
+ else:
405
+ ss['tcpSettings'] = {
406
+ 'header': {
407
+ 'type': 'none'
408
+ }
409
+ # 'acceptProxyProtocol': False
410
+ }
411
+
412
+
413
+ def add_http_stream(ss: dict, proxy: dict):
414
+ ss['httpSettings'] = {
415
+ 'host': proxy['host'],
416
+ 'path': proxy['path'],
417
+ # 'read_idle_timeout': 10, # default disabled
418
+ # 'health_check_timeout': 15, # default is 15
419
+ # 'method': 'PUT', # default is 15
420
+ # 'headers': {
421
+
422
+ # }
423
+ }
424
+
425
+
426
+ def add_ws_stream(ss: dict, proxy: dict):
427
+ ss['wsSettings'] = {
428
+ 'path': proxy['path'],
429
+ 'headers': {
430
+ "Host": proxy['host']
431
+ }
432
+ # 'acceptProxyProtocol': False,
433
+ }
434
+
435
+
436
+ def add_grpc_stream(ss: dict, proxy: dict):
437
+ ss['grpcSettings'] = {
438
+ 'serviceName': proxy['path'], # proxy['path'] is equal toproxy['grpc_service_name']
439
+ 'idle_timeout': 115, # by default, the health check is not enabled. may solve some "connection drop" issues
440
+ 'health_check_timeout': 20, # default is 20
441
+ # 'initial_windows_size': 0, # 0 means disabled. greater than 65535 means Dynamic Window mechanism will be disabled
442
+ # 'permit_without_stream': False, # health check performed when there are no sub-connections
443
+ # 'multiMode': false, # experimental
444
+ }
445
+
446
+
447
+ def add_httpupgrade_stream(ss: dict, proxy: dict):
448
+ ss['httpupgradeSettings'] = {
449
+ 'path': proxy['path'],
450
+ 'host': proxy['host'],
451
+ # 'acceptProxyProtocol': '', for inbounds only
452
+ }
453
+
454
+
455
+ def add_kcp_stream(ss: dict, proxy: dict):
456
+ # TODO: fix server side configs first
457
+ ss['kcpSettings'] = {}
458
+ return
459
+ ss['kcpSettings'] = {
460
+ 'seed': proxy['path'],
461
+ # 'mtu': 1350, # optional, default value is written
462
+ # 'tti': 50, # optional, default value is written
463
+ # 'uplinkCapacity': 5, # optional, default value is written
464
+ # 'downlinkCapacity': 20, # optional, default value is written
465
+ # 'congestion':False, # optional, default value is written
466
+ # 'readBufferSize': 2,# optional, default value is written
467
+ # 'writeBufferSize':2 # optional, default value is written
468
+ # 'header': { # must be same as server (hiddify doesn't use yet)
469
+ # 'type': 'none' # choices: none(default), srtp, utp, wechat-video, dtls, wireguards
470
+ # }
471
+ }
472
+
473
+
474
+ def add_quic_stream(ss: dict, proxy: dict):
475
+ # TODO: fix server side configs first
476
+ ss['quicSettings'] = {}
477
+ return
478
+ ss['quicSettings'] = {
479
+ 'security': 'chacha20-poly1305',
480
+ 'key': proxy['path'],
481
+ 'header': {
482
+ 'type': 'none'
483
+ }
484
+ }
485
+
486
+
487
+ def add_reality_stream(ss: dict, proxy: dict):
488
+ ss['realitySettings'] = {
489
+ 'serverName': proxy['sni'],
490
+ 'fingerprint': proxy['fingerprint'],
491
+ 'shortId': proxy['reality_short_id'],
492
+ 'publicKey': proxy['reality_pbk'],
493
+ 'show': False,
494
+ }
495
+
496
+
497
+ def add_tls_fragmentation_stream_settings(base: dict):
498
+ '''Adds tls fragment in the outbounds if tls fragmentation is enabled'''
499
+ if base['streamSettings']['security'] in ['tls', 'reality']:
500
+ if hconfig(ConfigEnum.tls_fragment_enable):
501
+ base['streamSettings']['sockopt'] = {
502
+ 'dialerProxy': 'fragment',
503
+ 'tcpKeepAliveIdle': 100,
504
+ 'tcpNoDelay': True, # recommended to be enabled with "tcpMptcp": true.
505
+ "mark": 255
506
+ # 'tcpFastOpen': True, # the system default setting be used.
507
+ # 'tcpKeepAliveInterval': 0, # 0 means default GO lang settings, -1 means not enable
508
+ # 'tcpcongestion': bbr, # Not configuring means using the system default value
509
+ # 'tcpMptcp': True, # need to be enabled in both server and client configuration (not supported by panel yet)
510
+ }
511
+
512
+ # endregion
513
+
514
+
515
+ def add_multiplex(base: dict):
516
+ if hconfig(ConfigEnum.mux_enable):
517
+ concurrency = hutils.convert.to_int(hconfig(ConfigEnum.mux_max_connections))
518
+ if concurrency and concurrency > 0:
519
+ base['mux']['enabled'] = True
520
+ base['mux']['concurrency'] = concurrency
521
+ base['mux']['xudpConcurrency'] = concurrency
522
+ base['mux']['xudpProxyUDP443'] = 'reject'
187
523
 
188
524
 
189
525
  def add_tls_tricks_to_dict(d: dict, proxy: dict):
@@ -199,12 +535,6 @@ def add_tls_tricks_to_dict(d: dict, proxy: dict):
199
535
  d['padsize'] = proxy["tls_padding_length"]
200
536
 
201
537
 
202
- def add_mux_to_link(proxy: dict) -> str:
203
- out = {}
204
- add_mux_to_dict(out, proxy)
205
- return hutils.encode.convert_dict_to_url(out)
206
-
207
-
208
538
  def add_mux_to_dict(d: dict, proxy):
209
539
  if proxy.get('mux_enable'):
210
540
  # according to github.com/hiddify/ray2sing/
@@ -217,3 +547,15 @@ def add_mux_to_dict(d: dict, proxy):
217
547
  if proxy.get('mux_brutal_enable'):
218
548
  d['muxup'] = proxy["mux_brutal_up_mbps"]
219
549
  d['muxdown'] = proxy["mux_brutal_down_mbps"]
550
+
551
+
552
+ def add_tls_tricks_to_link(proxy: dict) -> str:
553
+ out = {}
554
+ add_tls_tricks_to_dict(out, proxy)
555
+ return hutils.encode.convert_dict_to_url(out)
556
+
557
+
558
+ def add_mux_to_link(proxy: dict) -> str:
559
+ out = {}
560
+ add_mux_to_dict(out, proxy)
561
+ return hutils.encode.convert_dict_to_url(out)
@@ -122,7 +122,6 @@ class SettingAdmin(FlaskView):
122
122
 
123
123
 
124
124
  def get_config_form():
125
-
126
125
  strconfigs = StrConfig.query.filter(StrConfig.child_id == Child.current.id).all()
127
126
  boolconfigs = BoolConfig.query.filter(BoolConfig.child_id == Child.current.id).all()
128
127
  bool_types = {c.key: 'bool' for c in boolconfigs}
@@ -154,7 +153,8 @@ def get_config_form():
154
153
  if c.key in bool_types:
155
154
  field = SwitchField(_(f'config.{c.key}.label'), default=c.value, description=_(f'config.{c.key}.description'))
156
155
  elif c.key == ConfigEnum.core_type:
157
- field = wtf.SelectField(_(f"config.{c.key}.label"), choices=[("xray", _("Xray")), ("singbox", _("SingBox"))], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
156
+ field = wtf.SelectField(_(f"config.{c.key}.label"), choices=[("xray", _("Xray")), ("singbox", _(
157
+ "SingBox"))], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
158
158
  elif c.key == ConfigEnum.warp_mode:
159
159
  field = wtf.SelectField(
160
160
  _(f"config.{c.key}.label"), choices=[("disable", _("Disable")), ("all", _("All")), ("custom", _("Only Blocked and Local websites"))],
@@ -168,7 +168,8 @@ def get_config_form():
168
168
  description=_(f"config.{c.key}.description"),
169
169
  default=hconfig(c.key))
170
170
  elif c.key == ConfigEnum.country:
171
- field = wtf.SelectField(_(f"config.{c.key}.label"), choices=[("ir", _("Iran")), ("zh", _("China")), ("other", _("Others"))], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
171
+ field = wtf.SelectField(_(f"config.{c.key}.label"), choices=[("ir", _("Iran")), ("zh", _(
172
+ "China")), ("other", _("Others"))], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
172
173
  elif c.key == ConfigEnum.package_mode:
173
174
  package_modes = [("release", _("Release")), ("beta", _("Beta"))]
174
175
  if hconfig(c.key) == "develop":
@@ -193,9 +194,14 @@ def get_config_form():
193
194
  elif c.key == ConfigEnum.telegram_lib:
194
195
  # if hconfig(ConfigEnum.telegram_lib)=='python':
195
196
  # continue6
196
- libs = [("python", _("lib.telegram.python")), ("tgo", _("lib.telegram.go")),
197
- ("orig", _("lib.telegram.orignal")), ("erlang", _("lib.telegram.erlang"))]
198
- field = wtf.SelectField(_("config.telegram_lib.label"), choices=libs, description=_("config.telegram_lib.description"), default=hconfig(ConfigEnum.telegram_lib))
197
+ libs = [
198
+ ("erlang", _("lib.telegram.erlang")),
199
+ ("python", _("lib.telegram.python")),
200
+ ("tgo", _("lib.telegram.go")),
201
+ # ("orig", _("lib.telegram.orignal")),
202
+ ]
203
+ field = wtf.SelectField(_("config.telegram_lib.label"), choices=libs, description=_(
204
+ "config.telegram_lib.description"), default=hconfig(ConfigEnum.telegram_lib))
199
205
  elif c.key == ConfigEnum.mux_protocol:
200
206
  choices = [("smux", 'smux'), ("yamux", "yamux"), ("h2mux", "h2mux")]
201
207
  field = wtf.SelectField(_(f"config.{c.key}.label"), choices=choices, description=_(f"config.{c.key}.description"), default=hconfig(c.key))
@@ -203,11 +209,13 @@ def get_config_form():
203
209
  elif c.key == ConfigEnum.warp_sites:
204
210
  validators = [wtf.validators.Length(max=2048)]
205
211
  render_kw = {'class': "ltr", 'maxlength': 2048}
206
- field = wtf.TextAreaField(_(f'config.{c.key}.label'), validators, default=c.value, description=_(f'config.{c.key}.description'), render_kw=render_kw)
212
+ field = wtf.TextAreaField(_(f'config.{c.key}.label'), validators, default=c.value,
213
+ description=_(f'config.{c.key}.description'), render_kw=render_kw)
207
214
  elif c.key == ConfigEnum.branding_freetext:
208
215
  validators = [wtf.validators.Length(max=2048)]
209
216
  render_kw = {'class': "ltr", 'maxlength': 2048}
210
- field = custom_widgets.CKTextAreaField(_(f'config.{c.key}.label'), validators, default=c.value, description=_(f'config.{c.key}.description'), render_kw=render_kw)
217
+ field = custom_widgets.CKTextAreaField(_(f'config.{c.key}.label'), validators, default=c.value,
218
+ description=_(f'config.{c.key}.description'), render_kw=render_kw)
211
219
  else:
212
220
  render_kw = {'class': "ltr"}
213
221
  validators = []
@@ -239,11 +247,13 @@ def get_config_form():
239
247
  if c.key == ConfigEnum.telegram_bot_token:
240
248
  validators.append(wtf.validators.Regexp("()|^([0-9]{8,12}:[a-zA-Z0-9_-]{30,40})|$", re.IGNORECASE, _("config.Invalid telegram bot token")))
241
249
  if c.key == ConfigEnum.branding_site:
242
- validators.append(wtf.validators.Regexp("()|(http(s|)://([A-Za-z0-9\\-\\.]+\\.[a-zA-Z]{2,})/?.*)", re.IGNORECASE, _("config.Invalid brand link")))
250
+ validators.append(wtf.validators.Regexp(
251
+ "()|(http(s|)://([A-Za-z0-9\\-\\.]+\\.[a-zA-Z]{2,})/?.*)", re.IGNORECASE, _("config.Invalid brand link")))
243
252
  # render_kw['required']=""
244
253
 
245
254
  if 'secret' in c.key:
246
- validators.append(wtf.validators.Regexp("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", re.IGNORECASE, _('config.invalid uuid')))
255
+ validators.append(wtf.validators.Regexp(
256
+ "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", re.IGNORECASE, _('config.invalid uuid')))
247
257
  render_kw['required'] = ""
248
258
 
249
259
  if c.key == ConfigEnum.proxy_path:
@@ -274,7 +284,8 @@ def get_config_form():
274
284
  if c.key == ConfigEnum.reality_public_key and g.account.mode in [AdminMode.super_admin]:
275
285
  extra_info = f" <a href='{hurl_for('admin.Actions:change_reality_keys')}'>{_('Change')}</a>"
276
286
 
277
- field = wtf.StringField(_(f'config.{c.key}.label'), validators, default=c.value, description=_(f'config.{c.key}.description') + extra_info, render_kw=render_kw)
287
+ field = wtf.StringField(_(f'config.{c.key}.label'), validators, default=c.value,
288
+ description=_(f'config.{c.key}.description') + extra_info, render_kw=render_kw)
278
289
  setattr(CategoryForm, f'{c.key}', field)
279
290
 
280
291
  multifield = wtf.FormField(CategoryForm, Markup('<i class="fa-solid fa-plus"></i>&nbsp' + _(f'config.{cat}.label')))
@@ -371,7 +371,7 @@ def _v7():
371
371
  Proxy.query.filter(Proxy.name == 'tls XTLSVision direct trojan').delete()
372
372
  except BaseException:
373
373
  pass
374
- add_config_if_not_exist(ConfigEnum.telegram_lib, "python")
374
+ add_config_if_not_exist(ConfigEnum.telegram_lib, "erlang")
375
375
  add_config_if_not_exist(ConfigEnum.admin_lang, hconfig(ConfigEnum.lang))
376
376
  add_config_if_not_exist(ConfigEnum.branding_title, "")
377
377
  add_config_if_not_exist(ConfigEnum.branding_site, "")
@@ -0,0 +1,125 @@
1
+ {
2
+ "remarks": "{{remarks}}",
3
+ "log": {
4
+ "access": "",
5
+ "error": "",
6
+ "loglevel": "warning"
7
+ },
8
+ "inbounds": [
9
+ {
10
+ "tag": "socks",
11
+ "port": 10808,
12
+ "listen": "127.0.0.1",
13
+ "protocol": "socks",
14
+ "sniffing": {
15
+ "enabled": true,
16
+ "destOverride": [
17
+ "http",
18
+ "tls"
19
+ ],
20
+ "routeOnly": false
21
+ },
22
+ "settings": {
23
+ "auth": "noauth",
24
+ "udp": true,
25
+ "allowTransparent": false
26
+ }
27
+ },
28
+ {
29
+ "tag": "http",
30
+ "port": 10809,
31
+ "listen": "127.0.0.1",
32
+ "protocol": "http",
33
+ "sniffing": {
34
+ "enabled": true,
35
+ "destOverride": [
36
+ "http",
37
+ "tls"
38
+ ],
39
+ "routeOnly": false
40
+ },
41
+ "settings": {
42
+ "auth": "noauth",
43
+ "udp": true,
44
+ "allowTransparent": false
45
+ }
46
+ }
47
+ ],
48
+ "outbounds": [
49
+ {
50
+ "tag": "fragment",
51
+ "protocol": "freedom",
52
+ "settings": {
53
+ "domainStrategy": "AsIs",
54
+ {% if hconfig(ConfigEnum.tls_fragment_enable) %}
55
+ "fragment": {
56
+ "packets": "tlshello",
57
+ "length": "{{ hconfig(ConfigEnum.tls_fragment_size) }}",
58
+ "interval": "{{ hconfig(ConfigEnum.tls_fragment_sleep) }}"
59
+ }
60
+ {% endif %}
61
+ },
62
+ "streamSettings": {
63
+ "sockopt": {
64
+ "tcpNoDelay": true,
65
+ "tcpKeepAliveIdle": 100
66
+ }
67
+ }
68
+ },
69
+ {
70
+ "tag": "direct",
71
+ "protocol": "freedom",
72
+ "settings": {}
73
+ },
74
+ {
75
+ "tag": "block",
76
+ "protocol": "blackhole",
77
+ "settings": {
78
+ "response": {
79
+ "type": "http"
80
+ }
81
+ }
82
+ }
83
+ ],
84
+ "routing": {
85
+ "domainStrategy": "AsIs",
86
+ "rules": [
87
+ {
88
+ "type": "field",
89
+ "inboundTag": [
90
+ "api"
91
+ ],
92
+ "outboundTag": "api",
93
+ "enabled": true
94
+ },
95
+ {
96
+ "id": "5465425548310166497",
97
+ "type": "field",
98
+ "outboundTag": "direct",
99
+ "domain": [
100
+ "domain:ir",
101
+ "geosite:cn"
102
+ ],
103
+ "enabled": true
104
+ },
105
+ {
106
+ "id": "5425034033205580637",
107
+ "type": "field",
108
+ "outboundTag": "direct",
109
+ "ip": [
110
+ "geoip:private",
111
+ "geoip:cn",
112
+ "geoip:ir"
113
+ ],
114
+ "enabled": true
115
+ },
116
+ {
117
+ "id": "5627785659655799759",
118
+ "type": "field",
119
+ "port": "0-65535",
120
+ "outboundTag": "proxy",
121
+ "enabled": true
122
+ }
123
+ ]
124
+ }
125
+ }
@@ -54,6 +54,14 @@ class UserView(FlaskView):
54
54
  def sub64(self):
55
55
  return self.all_configs(base64=True)
56
56
 
57
+ @route("/xray/")
58
+ @route("/xray")
59
+ @login_required(roles={Role.user})
60
+ def xray(self):
61
+ c = c = get_common_data(g.account.uuid, mode="new")
62
+ configs = hutils.proxy.xray.configs_as_json(c['domains'], c['profile_title'])
63
+ return add_headers(configs, c, 'application/json')
64
+
57
65
  @route("/singbox/")
58
66
  @route("/singbox")
59
67
  @login_required(roles={Role.user})
@@ -189,7 +197,7 @@ class UserView(FlaskView):
189
197
  if request.method == 'HEAD':
190
198
  resp = ""
191
199
  else:
192
- resp = hutils.proxy.singbox.make_full_singbox_config(**c)
200
+ resp = hutils.proxy.singbox.configs_as_json(**c)
193
201
 
194
202
  return add_headers(resp, c, 'application/json')
195
203
 
@@ -2263,16 +2263,13 @@ msgid "lang.zh"
2263
2263
  msgstr "🇨🇳 Chinese چینی 简体中文"
2264
2264
 
2265
2265
  msgid "lib.telegram.erlang"
2266
- msgstr "☑️ Erlang : Medium Performance"
2266
+ msgstr "✴️ Erlang : Good Performance"
2267
2267
 
2268
2268
  msgid "lib.telegram.go"
2269
- msgstr "✴️ Go : High Performance - No ad Support"
2270
-
2271
- msgid "lib.telegram.orignal"
2272
- msgstr "⛔️ Not Working - Original : High Performance"
2269
+ msgstr " Go : Nornal Performance - No ad Support"
2273
2270
 
2274
2271
  msgid "lib.telegram.python"
2275
- msgstr " Python : Low Performance"
2272
+ msgstr "☑️ Python : Low Performance"
2276
2273
 
2277
2274
  msgid "log"
2278
2275
  msgstr "📄 Log"
@@ -2262,16 +2262,13 @@ msgid "lang.zh"
2262
2262
  msgstr "🇨🇳 Chinese چینی 简体中文"
2263
2263
 
2264
2264
  msgid "lib.telegram.erlang"
2265
- msgstr "☑️ Erlang : عملکرد متوسط"
2265
+ msgstr "✴️ Erlang : عملکرد خوب"
2266
2266
 
2267
2267
  msgid "lib.telegram.go"
2268
- msgstr "✴️ Go : عملکرد بالا - عدم پشتیبانی از تبلیغات"
2269
-
2270
- msgid "lib.telegram.orignal"
2271
- msgstr "⛔️ کار نمیکند - اصلی : عملکرد قوی"
2268
+ msgstr " Go : عملکرد معمولی - عدم پشتیبانی از تبلیغات"
2272
2269
 
2273
2270
  msgid "lib.telegram.python"
2274
- msgstr " پایتون : عملکرد ضعیف"
2271
+ msgstr "☑️ پایتون : عملکرد ضعیف"
2275
2272
 
2276
2273
  msgid "log"
2277
2274
  msgstr "📄 لاگ"
@@ -2197,9 +2197,6 @@ msgstr "⛔️ NÃO está funcionando - Erlang: desempenho médio"
2197
2197
  msgid "lib.telegram.go"
2198
2198
  msgstr "✅ Ir: alto desempenho - sem suporte de anúncios"
2199
2199
 
2200
- msgid "lib.telegram.orignal"
2201
- msgstr "⛔️ Não funciona - Original: alto desempenho"
2202
-
2203
2200
  msgid "lib.telegram.python"
2204
2201
  msgstr "✅ Python: baixo desempenho"
2205
2202
 
@@ -2210,16 +2210,13 @@ msgid "lang.zh"
2210
2210
  msgstr "🇨🇳 Chinese چینی 简体中文 Китайский"
2211
2211
 
2212
2212
  msgid "lib.telegram.erlang"
2213
- msgstr "☑️ Erlang: средняя производительность"
2213
+ msgstr "✴️ Erlang: хорошая производительность"
2214
2214
 
2215
2215
  msgid "lib.telegram.go"
2216
- msgstr "✴️ Go: высокая производительность – без поддержки рекламы"
2217
-
2218
- msgid "lib.telegram.orignal"
2219
- msgstr "⛔️ Не работает — оригинал: высокая производительность."
2216
+ msgstr " Go: Нормальный функционал – без поддержки рекламы"
2220
2217
 
2221
2218
  msgid "lib.telegram.python"
2222
- msgstr " Python: низкая производительность"
2219
+ msgstr "☑️ Python: низкая производительность"
2223
2220
 
2224
2221
  msgid "log"
2225
2222
  msgstr "📄 Журнал"
@@ -2067,9 +2067,6 @@ msgstr "⛔️ 不工作 - Erlang:中等性能"
2067
2067
  msgid "lib.telegram.go"
2068
2068
  msgstr "✴️ Go:高性能 - 无广告支持"
2069
2069
 
2070
- msgid "lib.telegram.orignal"
2071
- msgstr "⛔️ 不工作 - 原始:高性能"
2072
-
2073
2070
  msgid "lib.telegram.python"
2074
2071
  msgstr "✅ Python:低性能"
2075
2072
 
@@ -948,10 +948,9 @@
948
948
  },
949
949
  "lib": {
950
950
  "telegram": {
951
- "erlang": "☑️ Erlang : Medium Performance",
952
- "go": "✴️ Go : High Performance - No ad Support",
953
- "orignal": "⛔️ Not Working - Original : High Performance",
954
- "python": "✅ Python : Low Performance"
951
+ "erlang": "✴️ Erlang : Good Performance",
952
+ "go": " Go : Nornal Performance - No ad Support",
953
+ "python": "☑️ Python : Low Performance"
955
954
  }
956
955
  },
957
956
  "log": "📄 Log",
@@ -948,10 +948,9 @@
948
948
  },
949
949
  "lib": {
950
950
  "telegram": {
951
- "erlang": "☑️ Erlang : عملکرد متوسط",
952
- "go": "✴️ Go : عملکرد بالا - عدم پشتیبانی از تبلیغات",
953
- "orignal": "⛔️ کار نمیکند - اصلی : عملکرد قوی",
954
- "python": "✅ پایتون : عملکرد ضعیف"
951
+ "erlang": "✴️ Erlang : عملکرد خوب",
952
+ "go": " Go : عملکرد معمولی - عدم پشتیبانی از تبلیغات",
953
+ "python": "☑️ پایتون : عملکرد ضعیف"
955
954
  }
956
955
  },
957
956
  "log": "📄 لاگ",
@@ -950,7 +950,6 @@
950
950
  "telegram": {
951
951
  "erlang": "⛔️ NÃO está funcionando - Erlang: desempenho médio",
952
952
  "go": "✅ Ir: alto desempenho - sem suporte de anúncios",
953
- "orignal": "⛔️ Não funciona - Original: alto desempenho",
954
953
  "python": "✅ Python: baixo desempenho"
955
954
  }
956
955
  },
@@ -948,10 +948,9 @@
948
948
  },
949
949
  "lib": {
950
950
  "telegram": {
951
- "erlang": "☑️ Erlang: средняя производительность",
952
- "go": "✴️ Go: высокая производительность – без поддержки рекламы",
953
- "orignal": "⛔️ Не работает — оригинал: высокая производительность.",
954
- "python": "✅ Python: низкая производительность"
951
+ "erlang": "✴️ Erlang: хорошая производительность",
952
+ "go": " Go: Нормальный функционал – без поддержки рекламы",
953
+ "python": "☑️ Python: низкая производительность"
955
954
  }
956
955
  },
957
956
  "log": "📄 Журнал",
@@ -950,7 +950,6 @@
950
950
  "telegram": {
951
951
  "erlang": "⛔️ 不工作 - Erlang:中等性能",
952
952
  "go": "✴️ Go:高性能 - 无广告支持",
953
- "orignal": "⛔️ 不工作 - 原始:高性能",
954
953
  "python": "✅ Python:低性能"
955
954
  }
956
955
  },
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hiddifypanel
3
- Version: 10.11.0
3
+ Version: 10.11.1
4
4
  Summary: hiddifypanel multi proxy panel
5
5
  Home-page: https://github.com/hiddify/hiddify-manager/
6
6
  Author: hiddify
@@ -1,6 +1,6 @@
1
1
  hiddifypanel/Events.py,sha256=AlnRdjVul0jP-NCT4-zoaQgowoOo-JhdQB4ytetAFKA,723
2
- hiddifypanel/VERSION,sha256=Ap1SXhwnHlfSU3Yn92mfKgxk1TkAuv09fFMJYcAwbbs,8
3
- hiddifypanel/VERSION.py,sha256=mHqroium0b1iTQGr3JhkR-xBFE0w_skGhqvyn-EW8hU,113
2
+ hiddifypanel/VERSION,sha256=iAzb730bIvTuNyyJdxkGjNCHb-CWGg-gECGur6Dj64g,8
3
+ hiddifypanel/VERSION.py,sha256=CA401eGdvu7Z990IDSEjkIOJE5Yyvn3SkSQtJHPISrc,113
4
4
  hiddifypanel/__init__.py,sha256=aLukp3ORszdcH4G9J-MlxhjHN6yFlOuOE6mm-L3aG_g,266
5
5
  hiddifypanel/__main__.py,sha256=IVchnXpK6bm8T3N--mN17HBQNLMeLAjyP7iwzULexB4,218
6
6
  hiddifypanel/auth.py,sha256=ouAFprxAfsbeuC-YFGkMyA1Z4dtWzixv8DqB7nQXrtA,6640
@@ -31,9 +31,9 @@ hiddifypanel/hutils/network/auto_ip_selector.py,sha256=uSQjxnqI7NdJ6N_jCNtHAGLwj
31
31
  hiddifypanel/hutils/network/net.py,sha256=jgtKq_w8z9BbjoT2JQ4POdqNGblRj3v50Ti40iZdZ-g,12065
32
32
  hiddifypanel/hutils/proxy/__init__.py,sha256=I6p5SL8UbdqFd4yd82JlEgqOr7AwPy-FeYm4D9htrGA,83
33
33
  hiddifypanel/hutils/proxy/clash.py,sha256=ERyiuUZibOUYvkyC1HPLCRPNB1lrZpuuafey2St7XtI,5820
34
- hiddifypanel/hutils/proxy/shared.py,sha256=DHDRpbkngwfqPskumdBgYAA0k9K3qLqmiJIwTwgrTwM,19891
35
- hiddifypanel/hutils/proxy/singbox.py,sha256=imuef9NzvVOc0u3RRXFXLIOGwLj9mh7Zkr6XTUoRDHw,10984
36
- hiddifypanel/hutils/proxy/xray.py,sha256=yYp0Q92kflv3RSKc6cDc8rc5wbcQJJkT2eUUZflWggI,10413
34
+ hiddifypanel/hutils/proxy/shared.py,sha256=ozz1NnyOm6NQcLGCuHzliE1Ye6JYzm8HDZOppevc3xs,19965
35
+ hiddifypanel/hutils/proxy/singbox.py,sha256=qs3g-msv465jkZ2FIRv9QS8GH7SD9MA4IUaQ_mQA_JE,10771
36
+ hiddifypanel/hutils/proxy/xray.py,sha256=OeYUOH6ioD4iQH1vQXJ0Zkj5_qsXqlC-BKgmGrSaZSg,21874
37
37
  hiddifypanel/models/__init__.py,sha256=0tCXDeb3kBqCDBrczzEvuFKcALK2jJok6CioLxggPJQ,823
38
38
  hiddifypanel/models/admin.py,sha256=dtDck9W2GgdRUJ53Zld4t1BJVuIIZKMVUe4o5gdeG2k,6445
39
39
  hiddifypanel/models/base_account.py,sha256=u8l9BGLw2D57M7ADGf9ZbNQvlnhhXHmYOkxwhghq5ck,3054
@@ -57,7 +57,7 @@ hiddifypanel/panel/cli.py,sha256=stf6kNsfMGHFKrgeNeI9CqoFfSW_fGJZjIn6GcrRYjM,941
57
57
  hiddifypanel/panel/common.py,sha256=PLDWD8YSYs0j0mlp_v4UOMF_L35gz936PyUGLDG3MGY,7529
58
58
  hiddifypanel/panel/custom_widgets.py,sha256=9qI_fNX8NKqB1r8ljgcaisGZaDM89_PM_rOBZbGaTYs,2506
59
59
  hiddifypanel/panel/hiddify.py,sha256=Xf0l0niDXCeNB6XFGlOIkiN1MixYWd7WyrhNxif7Ef0,17298
60
- hiddifypanel/panel/init_db.py,sha256=BQYseZOpghTVjRFNnnduxmQ3gQiISZcXkUp7a5uoiKQ,31236
60
+ hiddifypanel/panel/init_db.py,sha256=G3bTx7ER9LNIrnERGByU2yF3-3rKczgjsUrpQjGirbo,31236
61
61
  hiddifypanel/panel/run_commander.py,sha256=D9y-My0xSe2adHWXKV5UPYGl-9WwKURzniq55MRu6tE,3259
62
62
  hiddifypanel/panel/usage.py,sha256=RBEuN4kDMbePFWRlRvFblAlFyLizdZhDHlW_AyxzXQ0,4141
63
63
  hiddifypanel/panel/admin/Actions.py,sha256=ErpMJi0AlvvtKoM0WqtZPYg5l41i7nfIyDpSAQIFHmM,8853
@@ -69,7 +69,7 @@ hiddifypanel/panel/admin/DomainAdmin.py,sha256=87-V8ajnymV-GoyMJ7JhUOFwxNjygp22b
69
69
  hiddifypanel/panel/admin/NodeAdmin.py,sha256=utJsYrZiK3hA1q3R0GMsEX03u-mxywsMr9z89_1bXjE,2995
70
70
  hiddifypanel/panel/admin/ProxyAdmin.py,sha256=3KcXjPPFQLtJpoW3P8jQMObA6yne2eUXZ5Dfmal9McM,5232
71
71
  hiddifypanel/panel/admin/QuickSetup.py,sha256=X8d492PLQu8vNtabh-X2R2IDZVs_5pmWeyn-Qz5_qXk,7560
72
- hiddifypanel/panel/admin/SettingAdmin.py,sha256=Sb3cbpKre9SPQu5KoC88rK8utHDpccI3AGzYOcGxDig,15903
72
+ hiddifypanel/panel/admin/SettingAdmin.py,sha256=UbakcS4hUQ78ejf3pWIoSV6pjAWltY0YcSF94e-X_PI,16229
73
73
  hiddifypanel/panel/admin/Terminal.py,sha256=fjLVLspXYHOwZGyMU_KbytWe1zf-m6KbmvBPEDps45w,1737
74
74
  hiddifypanel/panel/admin/UserAdmin.py,sha256=6BvvFFcbU62C2I0Xq-Ixk1OP4D9jhosTThI6koUrjc8,16932
75
75
  hiddifypanel/panel/admin/__init__.py,sha256=hb0A2HuK_nBZRCNPumwahXX-25FMxODKYlNbk2ItF08,3015
@@ -158,10 +158,11 @@ hiddifypanel/panel/common_bp/login.py,sha256=wNfH7rzYtmanrIityKQhhVvUJooC658QhSE
158
158
  hiddifypanel/panel/common_bp/templates/login.html,sha256=jDl9-Nh2qMuCsLQmXm7e5jvSaRAlBxReVVCbNSTTHJw,1312
159
159
  hiddifypanel/panel/user/__init__.py,sha256=E9RxA2YGc0eXLGjfJbyryeLG3bXEWJ3DoVOyIpVaDIo,1859
160
160
  hiddifypanel/panel/user/link_maker.html,sha256=g420NAm_fUI8asYjyfCiXyUOIwEQfDPonZA9xh3p0-8,177
161
- hiddifypanel/panel/user/user.py,sha256=Vg0vNopnxVjupOh8smyi4kDc5x1ckTTBXV_0mEQjBQs,13526
161
+ hiddifypanel/panel/user/user.py,sha256=nRYG9Wal67OxkLWmqkzwCD-5RADmz2DbKCFwtXNYId4,13823
162
162
  hiddifypanel/panel/user/templates/all_configs copy.txt,sha256=u5jhAgjhH07_0csdIisuXy2HNCC9SWlP0whBAGFXA78,564
163
163
  hiddifypanel/panel/user/templates/all_configs.txt,sha256=i8I6g9ujOr3RIuRoGRqY2Q75I89mbHko_JVPvQt4E_g,1260
164
164
  hiddifypanel/panel/user/templates/base_singbox_config.json.j2,sha256=xhvQpm0fp2w3VA8N7zXbYs8RWlRgdyApiedFH_sRTfM,7107
165
+ hiddifypanel/panel/user/templates/base_xray_config.json.j2,sha256=CiQVg5LNpLu-A2EQfj84P1NrRUMKXfVlhih1uyYl9cw,2491
165
166
  hiddifypanel/panel/user/templates/clash_config copy.yml,sha256=j_IWrvoAvCUPYULXlegDHmBobev5MObZkqeUoTPHGTc,7641
166
167
  hiddifypanel/panel/user/templates/clash_config.yml,sha256=MwdPGIkwS4TkitO0c6f7bIvxh6rL7QMF84DfbxUJjPs,5169
167
168
  hiddifypanel/panel/user/templates/clash_proxies copy.yml,sha256=j98fCeMP4-qZlAma8a9noChUqc84djM6apINgNZLPjU,12365
@@ -798,24 +799,24 @@ hiddifypanel/templates/redirect.html,sha256=K9x_O4P96vEkqBhOXIhoGrWw1KIqd2bL0BjI
798
799
  hiddifypanel/templates/static.html,sha256=jp6q4wtx-k2A_cjqJoNiMS7Ee30arE45qI3ev4d5ky4,165
799
800
  hiddifypanel/templates/hiddify-flask-admin/actions.html,sha256=2NeITe2e-lPKCk_o511tCIqVtrPu8LYHE1wTCtrFUrI,1331
800
801
  hiddifypanel/templates/hiddify-flask-admin/list.html,sha256=MBGrTqZpzNLe4sZy0RozvXNr8seFUQc2C6v88BJtNWc,11095
801
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo,sha256=62z8sROPDLwmU7o9HKTph6Yguib9fT4wQLuKfamLrTk,71519
802
- hiddifypanel/translations/en/LC_MESSAGES/messages.po,sha256=PyJSj5cC98CIQ3PfJGvQ8uzGgKrdlCkidl0jjIocCGo,74586
803
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo,sha256=-fo-4-twFecwfabHL1alK_UtFmm1UlU4HDIwqvgG3ew,94934
804
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po,sha256=GqFknCZKm5jloxgNTcKmbcuFi_HmTQQrJwkYWCr-d2A,98485
805
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo,sha256=hJ1KV4zNBhX5vJ7UGtqGzVNgp3Vm-9BqUK-MUzGJg94,60425
806
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po,sha256=hpAzlu1XpXhTxUOWkobgrIUwPKJb2DNmMYpml797KDc,68398
807
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo,sha256=yXnd8WWnBI1Z_DC3sDfuH-kKNCQ7U-eR1XjAOhRf9yc,82252
808
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po,sha256=6OOb8Ar1R7py7LN10Uu7VAfkX_fEVN30Rie5LRZaWE0,90879
809
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo,sha256=45ioFi8D62iwzoKKJW3L9pPE9KzBWf70ETIs3drvV-I,56014
810
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po,sha256=z6-yfEjGGo_X0Q5gVDXauz7DQAn0ljIsx8RgZPdswIM,64053
811
- hiddifypanel/translations.i18n/en.json,sha256=AHC--Cj-qATmzwq925wP9M6tNFS57RaUs58UVfkSXu0,64947
812
- hiddifypanel/translations.i18n/fa.json,sha256=03HCClZO-p2LCErk8-AazWZuYlkksDY1e2DSEo4eg1M,88837
813
- hiddifypanel/translations.i18n/pt.json,sha256=hdehLrxpunQPkhpiGTnPI7DCCd0Egaxa2tmV9QlaBjU,59044
814
- hiddifypanel/translations.i18n/ru.json,sha256=WNEG6aOgvLwxdDIB5N6-Fc9xEAZLwiyFOanbpSj945U,81456
815
- hiddifypanel/translations.i18n/zh.json,sha256=Xqw6hXEg8hizR9ZGxYXN-Gu8hmUy43t_v87rkT_ihdk,55089
816
- hiddifypanel-10.11.0.dist-info/LICENSE.md,sha256=oDrt-cUsyiDGnRPjEJh-3dH2ddAuK_bIVBD8ntkOtZw,19807
817
- hiddifypanel-10.11.0.dist-info/METADATA,sha256=-GfKktWiNV3L6WxkZqjC3AOCSrfLtPJs_82wfNsZfok,3987
818
- hiddifypanel-10.11.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
819
- hiddifypanel-10.11.0.dist-info/entry_points.txt,sha256=Xzpqlh3nwBtZhoV9AANJykano056VJvYzaujxPztJaM,60
820
- hiddifypanel-10.11.0.dist-info/top_level.txt,sha256=rv-b3qFWUZQTBy0kyBfsr7L6tPpeO7AaQlLHXn-HI5M,13
821
- hiddifypanel-10.11.0.dist-info/RECORD,,
802
+ hiddifypanel/translations/en/LC_MESSAGES/messages.mo,sha256=GreZElrK_Zz9aE4H-m-LA8K9tPlsm2XQeGcbbn-Pcvc,71433
803
+ hiddifypanel/translations/en/LC_MESSAGES/messages.po,sha256=0jHqL7131-cESFcthPB2VTlnOA31YLlO1FAMnGOnnJo,74498
804
+ hiddifypanel/translations/fa/LC_MESSAGES/messages.mo,sha256=3U7_TLUEJf8xFyyv-JW0mW8-ZcNPnUlVTKiisaYzHNI,94837
805
+ hiddifypanel/translations/fa/LC_MESSAGES/messages.po,sha256=jSZxla6lfIydr63JqNzCWv1m3A05fV_IyYt-wMUL0As,98386
806
+ hiddifypanel/translations/pt/LC_MESSAGES/messages.mo,sha256=S7vpDPsZ-zFzdtG_wLhKBj4GvGDNMAVi2QT1O8_ObfA,60339
807
+ hiddifypanel/translations/pt/LC_MESSAGES/messages.po,sha256=trtOlrzKq6dJWGAZiBAu8JtIpaoyvPK3tTvFIJU08oI,68310
808
+ hiddifypanel/translations/ru/LC_MESSAGES/messages.mo,sha256=W4UMuRBu3GUcdhzK31Z9erZ8cySQTRdu1UI1dd55fNY,82101
809
+ hiddifypanel/translations/ru/LC_MESSAGES/messages.po,sha256=QLClIAmVVhZ_pusCBvrD3MQRrp7AIWii6dLmsaSvmSs,90726
810
+ hiddifypanel/translations/zh/LC_MESSAGES/messages.mo,sha256=6kUAzVm1-7D5lTd4pe6KmVBQo5ClmoX61vpchZc2AbY,55939
811
+ hiddifypanel/translations/zh/LC_MESSAGES/messages.po,sha256=8BN_nF-a6MYBEK8MSbtHcwMaZn8LcpSa6DJYbxuK1UA,63976
812
+ hiddifypanel/translations.i18n/en.json,sha256=PSwFUWJ9IaaZHJ5SWfbG6W6dFSX0eA49WZqR-UNbZC0,64878
813
+ hiddifypanel/translations.i18n/fa.json,sha256=lONgrL_C_pVi8dqU3xg3d0QYMeJiPZ-jmiIXGyHZEIE,88757
814
+ hiddifypanel/translations.i18n/pt.json,sha256=310-yPpFxT-qCW-2szZm9zu9Ep_wnhRdCKW6Ypzk0B8,58975
815
+ hiddifypanel/translations.i18n/ru.json,sha256=dV1qg18o8E4x98-R7wuIwWbXhakToZ-ddiufZeNInEA,81322
816
+ hiddifypanel/translations.i18n/zh.json,sha256=RWnhmYJ-ywuWLHSIDaJfwpskdwigLn9vxSTEI-i2Vnc,55031
817
+ hiddifypanel-10.11.1.dist-info/LICENSE.md,sha256=oDrt-cUsyiDGnRPjEJh-3dH2ddAuK_bIVBD8ntkOtZw,19807
818
+ hiddifypanel-10.11.1.dist-info/METADATA,sha256=6ja2bRo5CnGKvd4vsZbPei9MP8tXEjJU2AqqDJIEx6o,3987
819
+ hiddifypanel-10.11.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
820
+ hiddifypanel-10.11.1.dist-info/entry_points.txt,sha256=Xzpqlh3nwBtZhoV9AANJykano056VJvYzaujxPztJaM,60
821
+ hiddifypanel-10.11.1.dist-info/top_level.txt,sha256=rv-b3qFWUZQTBy0kyBfsr7L6tPpeO7AaQlLHXn-HI5M,13
822
+ hiddifypanel-10.11.1.dist-info/RECORD,,