Skip to content

Commit

Permalink
feat: Add subscription formats for software like ShadowRocket.
Browse files Browse the repository at this point in the history
  • Loading branch information
vvbbnn00 committed Feb 22, 2024
1 parent f03a140 commit efd3db6
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 3 deletions.
39 changes: 38 additions & 1 deletion services/subscription.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import base64
import configparser
import copy
import json
import random
import string
import tempfile

import urllib.parse
import yaml
from flask import request

Expand Down Expand Up @@ -191,3 +192,39 @@ def generateSurgeSubFile(account: Account = None,
surge_ini = SURGE_SUB.replace("{PUBLIC_URL}", public_url) + surge_ini

return surge_ini


def generateShadowRocketSubFile(account: Account = None,
logger=logging.getLogger(__name__),
best=False,
random_name=False):
"""
Generate ShadowRocket subscription file
:param account:
:param logger:
:param best: Whether to use the best entrypoints
:param random_name: Whether to use random name
:return:
"""
account = getCurrentAccount(logger) if account is None else account
entrypoints = getEntrypoints()
random_points = random.sample(entrypoints, RANDOM_COUNT) if not best else getBestEntrypoints(RANDOM_COUNT)

# Initialize NodeNameGenerator
node_name_generator = NodeNameGenerator(random_name)

url_list = []
# Use len() instead of RANDOM_COUNT because the entrypoints may be less than RANDOM_COUNT
for i in range(len(random_points)):
point = random_points[i]
country = GEOIP.lookup(point.ip)
country_emoji = GEOIP.lookup_emoji(point.ip)
name = node_name_generator.next(country_emoji, country)
url = f"wg://{point.ip}:{point.port}?publicKey={CF_CONFIG.get('publicKey')}&privateKey={account.private_key}" \
f"&ip=172.16.0.2&udp=1&flag={country}#{urllib.parse.quote(name)}"
url_list.append(url)

sub_data = "\n".join(url_list)
sub_data = base64.b64encode(sub_data.encode("utf-8")).decode("utf-8")

return sub_data
15 changes: 13 additions & 2 deletions services/web_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

from flask import Flask, request, make_response, current_app, render_template
from config import SECRET_KEY, REQUEST_RATE_LIMIT
from services.subscription import generateClashSubFile, generateWireguardSubFile, generateSurgeSubFile
from services.subscription import generateClashSubFile, generateWireguardSubFile, generateSurgeSubFile, \
generateShadowRocketSubFile
from services.common import *
from faker import Faker

Expand Down Expand Up @@ -91,7 +92,9 @@ def httpAutoSub():
if "clash" in user_agent: # Clash
return httpSubscription("clash")
elif "shadowrocket" in user_agent: # Shadowrocket
return httpSubscription("clash")
return httpSubscription("shadowrocket")
elif "v2ray" in user_agent: # V2Ray
return httpSubscription("shadowrocket")
elif "quantumult" in user_agent: # Quantumult
return httpSubscription("clash")
elif "surge" in user_agent: # Surge
Expand Down Expand Up @@ -141,6 +144,14 @@ def httpSubscription(sub_type: str):
"Subscription-Userinfo": f"upload=0; download={account.usage}; total={account.quota}; "
f"expire=253388144714"
}
elif sub_type == 'shadowrocket': # Shadowrocket
fileData = generateShadowRocketSubFile(account, logger, best=best, random_name=random_name)
headers = {
'Content-Type': 'text/plain; charset=utf-8',
'Content-Disposition': 'attachment; filename=Shadowrocket.txt',
"Subscription-Userinfo": f"upload=0; download={account.usage}; total={account.quota}; "
f"expire=253388144714"
}
elif sub_type == "only_proxies": # Only proxies
fileData = generateClashSubFile(account, logger, best=best, only_proxies=True, random_name=random_name)
headers = {
Expand Down
13 changes: 13 additions & 0 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ <h2>自动判断订阅类型</h2>
<h2>Clash</h2>
<textarea id="subscriptionLink" rows="1" readonly onclick="copyText('subscriptionLink')"></textarea>
<div id="qrcode_clash"></div>
<h2>ShadowRocket</h2>
<textarea id="subShadowRocketSubscriptionLink" rows="1" readonly
onclick="copyText('subShadowRocketSubscriptionLink')"></textarea>
<div id="qrcode_sr"></div>
<h2>Surge</h2>
<textarea id="subSurgeScriptionLink" rows="1" readonly onclick="copyText('subSurgeScriptionLink')"></textarea>
<h2>Wireguard</h2>
Expand Down Expand Up @@ -163,6 +167,7 @@ <h2>账户信息</h2>

document.getElementById('autoSubscriptionLink').textContent = baseUrl + "sub?" + queryParams.toString();
document.getElementById('subscriptionLink').textContent = baseUrl + "api/clash?" + queryParams.toString();
document.getElementById('subShadowRocketSubscriptionLink').textContent = baseUrl + "api/shadowrocket?" + queryParams.toString();
document.getElementById('subSurgeScriptionLink').textContent = baseUrl + "api/surge?" + queryParams.toString();
document.getElementById('WireguardLink').textContent = baseUrl + "api/wireguard?" + queryParams.toString();
document.getElementById('AccountLink').href = baseUrl + "api/account?" + queryParams.toString();
Expand All @@ -184,6 +189,14 @@ <h2>账户信息</h2>
height: 200
});

const qrcodeContainerSr = document.getElementById('qrcode_sr');
qrcodeContainerSr.innerHTML = '';
const qrcodeSr = new QRCode(qrcodeContainerSr, {
text: document.getElementById('subShadowRocketSubscriptionLink').textContent,
width: 200,
height: 200
});

getQrCodeWg();
}

Expand Down

0 comments on commit efd3db6

Please sign in to comment.