Skip to content
This repository has been archived by the owner on Feb 10, 2024. It is now read-only.

Commit

Permalink
Update index.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
vfarid committed Apr 28, 2023
1 parent f9ed4c0 commit b616708
Showing 1 changed file with 150 additions and 66 deletions.
216 changes: 150 additions & 66 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,88 @@
* Licensed under GPLv3 (https://github.com/vfarid/v2ray-worker-sub/blob/main/Licence.md)
*/

const MAX_CONFIGS = 1000
const MAX_CONFIGS = 500
const INCLUDE_ORIGINAL = true

const configProviders: Array<any> = [
{name: "freefq", type: "b64", url: "https://raw.githubusercontent.com/freefq/free/master/v2"},
{name: "pawdroid", type: "b64", url: "https://raw.githubusercontent.com/Pawdroid/Free-servers/main/sub"},
{name: "aiboboxx", type: "b64", url: "https://raw.githubusercontent.com/aiboboxx/v2rayfree/main/v2"},
{name: "vpei", type: "b64", url: "https://raw.githubusercontent.com/vpei/Free-Node-Merge/main/o/node.txt"},
{name: "mfuu", type: "b64", url: "https://raw.githubusercontent.com/mfuu/v2ray/master/v2ray"},
{name: "autoproxy", type: "b64", url: "https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription1"},
{name: "autoproxy", type: "b64", url: "https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription2"},
{name: "autoproxy", type: "b64", url: "https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription3"},
{name: "autoproxy", type: "b64", url: "https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription4"},
{name: "autoproxy", type: "b64", url: "https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription5"},
{name: "autoproxy", type: "b64", url: "https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription6"},
{name: "autoproxy", type: "b64", url: "https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription7"},
{name: "autoproxy", type: "b64", url: "https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription8"},
{name: "ermaozi", type: "b64", url: "https://raw.githubusercontent.com/ermaozi/get_subscribe/main/subscribe/v2ray.txt"},
{name: "ermaozi01", type: "b64", url: "https://raw.githubusercontent.com/ermaozi01/free_clash_vpn/main/subscribe/v2ray.txt"},
{name: "bardiafa", type: "raw", url: "https://raw.githubusercontent.com/Bardiafa/Free-V2ray-Config/main/configs.txt"},
{name: "mahdibland", type: "raw", url: "https://raw.githubusercontent.com/mahdibland/V2RayAggregator/master/sub/splitted/vmess.txt"},
{name: "mahdibland", type: "raw", url: "https://raw.githubusercontent.com/mahdibland/V2RayAggregator/master/sub/splitted/trojan.txt"},
{name: "peasoft", type: "raw", url: "https://raw.githubusercontent.com/peasoft/NoMoreWalls/master/list_raw.txt"},
{
name: "vpei",
type: "b64",
urls: [
"https://raw.githubusercontent.com/vpei/Free-Node-Merge/main/o/node.txt",
],
},
{
name: "mfuu",
type: "b64",
urls: [
"https://raw.githubusercontent.com/mfuu/v2ray/master/v2ray",
],
},
{
name: "peasoft",
type: "raw",
urls: [
"https://raw.githubusercontent.com/peasoft/NoMoreWalls/master/list_raw.txt",
],
},
{
name: "ermaozi",
type: "b64",
urls: [
"https://raw.githubusercontent.com/ermaozi/get_subscribe/main/subscribe/v2ray.txt",
],
},
{
name: "aiboboxx",
type: "b64",
urls: [
"https://raw.githubusercontent.com/aiboboxx/v2rayfree/main/v2",
],
},
{
name: "mahdibland",
type: "raw",
urls: [
"https://raw.githubusercontent.com/mahdibland/V2RayAggregator/master/sub/splitted/vmess.txt",
"https://raw.githubusercontent.com/mahdibland/V2RayAggregator/master/sub/splitted/trojan.txt",
],
},
{
name: "bardiafa",
type: "raw",
urls: [
"https://raw.githubusercontent.com/Bardiafa/Free-V2ray-Config/main/configs.txt",
],
},
{
name: "autoproxy",
type: "b64",
urls: [
"https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription1",
"https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription2",
"https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription3",
"https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription4",
"https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription5",
"https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription6",
"https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription7",
"https://raw.githubusercontent.com/w1770946466/Auto_proxy/main/Long_term_subscription8",
],
},
{
name: "freefq",
type: "b64",
urls: [
"https://raw.githubusercontent.com/freefq/free/master/v2",
],
},
{
name: "pawdroid",
type: "b64",
urls: [
"https://raw.githubusercontent.com/Pawdroid/Free-servers/main/sub",
],
},
]

const ipProviderLink = "https://raw.githubusercontent.com/vfarid/cf-clean-ips/main/list.json"
Expand Down Expand Up @@ -68,6 +127,8 @@ var cleanIP: string = ""
var maxConfigs: number = MAX_CONFIGS
var includeOriginalConfigs: boolean = INCLUDE_ORIGINAL

import { Buffer } from 'buffer'

export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url)
Expand All @@ -77,7 +138,8 @@ export default {
if (type === "sub") {
if (parts[1] !== undefined) {
if (parts[1].includes(".")) { // Subdomain or IP
cleanIP = parts[1].toLowerCase().trim()
cleanIPs = parts[1].toLowerCase().trim().split(",").map((ip: string) => {return {ip: ip, operator: "IP"}})
operators = ["IP"]
} else { // Operator code
try {
operators = parts[1].toUpperCase().trim().split(",")
Expand All @@ -101,23 +163,21 @@ export default {
includeOriginalConfigs = ["1", "true", "yes", "y"].includes(original.toLowerCase())
}

if (includeOriginalConfigs) {
maxConfigs = Math.floor(maxConfigs / 2)
}

var configList: Array<any> = []
var acceptableConfigList: Array<any> = []
var finalConfigList: Array<any> = []
var newConfigs: any

for (const sub of configProviders) {
try {
newConfigs = await fetch(sub.url)
.then(r => r.text())
if (sub.type === "b64") {
newConfigs = atob(newConfigs)
newConfigs = []
for (const link of sub.urls) {
newConfigs.push(await fetch(link).then(r => r.text()))
if (sub.type === "b64") {
newConfigs = Buffer.from(newConfigs, "base64").toString("utf-8")
}
}
newConfigs = newConfigs.split("\n")
newConfigs = newConfigs.join("\n").split("\n")
acceptableConfigList.push({
name: sub.name,
configs: newConfigs.filter((cnf: any) => cnf.match(/^(vmess|vless|trojan):\/\//i))
Expand All @@ -132,10 +192,6 @@ export default {
}

var ipList = []
if (cleanIP) {
operators = ["IP"]
cleanIPs = [{ip: cleanIP, operator: "IP"}]
}
if (!cleanIPs.length) {
operators = ["General"]
cleanIPs = [{ip: "", operator: "General"}]
Expand All @@ -158,18 +214,24 @@ export default {
)
)
}
if (includeOriginalConfigs) {
for (const el of configList) {
finalConfigList = finalConfigList.concat(
getMultipleRandomElements(
el.configs,
}
if (includeOriginalConfigs) {
for (const el of configList) {
finalConfigList = finalConfigList.concat(
getMultipleRandomElements(
el.configs
.map(decodeConfig)
.map((cnf: any) => renameConfig(cnf, el.name))
.filter((cnf: any) => (!!cnf && cnf.id))
.map(encodeConfig)
.filter((cnf: any) => !!cnf),
configPerList
)
)
}
)
}
}
return new Response(btoa(finalConfigList.join("\n")))
// return new Response(finalConfigList.join("\n"))
return new Response(Buffer.from(finalConfigList.join("\n"), "utf-8").toString("base64"))
} else if (path) {
var newUrl = new URL("https://" + url.pathname.replace(/^\/|\/$/g, ""))
return fetch(new Request(newUrl, request))
Expand All @@ -180,28 +242,49 @@ export default {
<h3><font color="green">همه چی درسته</font></h3>
<p />
<p>
این لینک sub را در اپ v2ray خود کپی کنید:
این لینک sub را همراه با کد اپراتور در اپ v2ray خود کپی کنید. برای مثال در همراه اول به شکل زیر خواهد بود:
</p>
<p>
<a href="https://${url.hostname}/sub">https://${url.hostname}/sub</a>
<a href="https://${url.hostname}/sub/mci">https://${url.hostname}/sub/mci</a>
</p>
<p>
و یا همین لینک را همراه آی‌پی تمیز در اپ خود اضافه کنید:
</p>
<p>
<a href="https://${url.hostname}/sub/1.2.3.4">https://${url.hostname}/sub/1.2.3.4</a>
</p>
<p>
می‌توانید چند آی‌پی تمیز را با کاما جدا کنید. در این صورت برای هر آی‌پی تمیز به تعداد قدید شده، کانفیک ترکیب شده با ورکر تحویل می دهد:
</p>
<p>
<a href="https://${url.hostname}/sub/1.2.3.4,9.8.7.6">https://${url.hostname}/sub/1.2.3.4,9.8.7.6</a>
</p>
<p>
دقیقا با همین مدل می‌توانید دامین آی‌پی تمیز نیز استفاده کنید:
</p>
<p>
<a href="https://${url.hostname}/sub/mci.ircf.space">https://${url.hostname}/sub/mci.ircf.space</a>
</p>
<p>
می‌توانید از چند سابدامنین آیءی تمیز نیز استفاده کنید:
</p>
<p>
<a href="https://${url.hostname}/sub/mci.ircf.space,my.domain.me">https://${url.hostname}/sub/mci.ircf.space,my.domain.me</a>
</p>
<p>
می‌توانید با متغیر max تعداد کانفیگ را مشخص کنید:
</p>
<p>
<a href="https://${url.hostname}/sub/1.2.3.4?max=200">https://${url.hostname}/sub/1.2.3.4?max=200</a>
</p>
<p>
همچنین می‌توانید با متغیر original مشخص کنید که کانفیگ‌های ترکیب نشده با ورکر هم در خروجی آورده شوند:
همچنین می‌توانید با متغیر original با عدد 0 یا 1 و یا با yes/no مشخص کنید که کانفیگ‌های اصلی (ترکیب نشده با ورکر) هم در خروجی آورده شوند یا نه:
</p>
<p>
<a href="https://${url.hostname}/sub/1.2.3.4?max=200&original=1">https://${url.hostname}/sub/1.2.3.4?max=200&original=1</a>
<a href="https://${url.hostname}/sub/1.2.3.4?max=200&original=yes">https://${url.hostname}/sub/1.2.3.4?max=200&original=yes</a>
</p>
<p>
<a href="https://${url.hostname}/sub/1.2.3.4?max=200&original=0">https://${url.hostname}/sub/1.2.3.4?max=200&original=0</a>
</p>
</body>`, {
headers: {
Expand All @@ -218,12 +301,12 @@ function encodeConfig(conf: any): string|null {
try {
if (conf.protocol === "vmess") {
delete conf.protocol
configStr = "vmess://" + btoa(JSON.stringify(conf))
configStr = "vmess://" + Buffer.from(JSON.stringify(conf), "utf-8").toString("base64")
} else if (["vless", "trojan"].includes(conf?.protocol)) {
configStr = `${conf.protocol}://${conf.id}@${conf.add}:${conf.port}?security=${conf.tls}&type=${conf.type}&path=${encodeURIComponent(conf.path)}&host=${encodeURIComponent(conf.host)}&tls=${conf.tls}&sni=${conf.sni}#${encodeURIComponent(conf.ps)}`;
}
} catch (e) {
console.log(`Failed to encode ${JSON.stringify(conf)}`, e)
// console.log(`Failed to encode ${JSON.stringify(conf)}`, e)
}

return configStr
Expand All @@ -233,7 +316,7 @@ function decodeConfig(configStr: string): any {
var match: any = null
var conf: any = null
if (configStr.startsWith("vmess://")) {
conf = JSON.parse(atob(configStr.substring(8)))
conf = JSON.parse(Buffer.from(configStr.substring(8), "base64").toString("utf-8"))
conf.protocol = "vmess"
} else if (match = configStr.match(/^(?<protocol>trojan|vless):\/\/(?<id>.*)@(?<add>.*):(?<port>\d+)\??(?<options>.*)#(?<ps>.*)$/)) {
try {
Expand All @@ -258,16 +341,16 @@ function decodeConfig(configStr: string): any {
alpn: optionsObj?.alpn,
}
} catch (e) {
console.log(`Failed to decode ${configStr}`, e)
// console.log(`Failed to decode ${configStr}`, e)
}
}
return conf
}

function mixConfig(conf: any, url: URL, ip: string, operator: string, provider = "") {
function mixConfig(conf: any, url: URL, ip: string, operator: string, provider: string) {
try {
if (conf.tls != "tls") {
console.log(`notls ${JSON.stringify(conf)}`)
// console.log(`notls ${JSON.stringify(conf)}`)
return {}
}

Expand All @@ -280,7 +363,7 @@ function mixConfig(conf: any, url: URL, ip: string, operator: string, provider =
}
}
if (!addr) {
console.log(`noaddress ${JSON.stringify(conf)}`)
// console.log(`noaddress ${JSON.stringify(conf)}`)
return {}
}

Expand Down Expand Up @@ -311,13 +394,14 @@ function mixConfig(conf: any, url: URL, ip: string, operator: string, provider =
conf.path = path
}

conf.ps = (Math.random() + 1).toString(36).substring(3) //conf?.ps ? conf.ps : conf.name
conf.ps = conf?.ps ? conf.ps : conf.name
if (provider) {
conf.ps = provider + "-" + conf.ps
}

conf.ps = conf.ps + "-worker-" + operator.toLocaleLowerCase()
conf.name = conf.ps
conf.host = url.hostname
conf.sni = url.hostname
if (ip) {
conf.add = ip
Expand All @@ -335,25 +419,25 @@ function mixConfig(conf: any, url: URL, ip: string, operator: string, provider =
conf.port = 443
return conf
} catch (e) {
console.log(`Failed to merge config ${JSON.stringify(conf)}`, e)
// console.log(`Failed to merge config ${JSON.stringify(conf)}`, e)
return {}
}
}

function renameConfig(conf: any, provider: string) {
try {
conf.ps = conf?.ps ? conf.ps : conf.name
conf.ps = provider + "-" + conf.ps
return conf
} catch (e) {
// console.log(`Failed to rename config ${JSON.stringify(conf)}`, e)
return {}
}
}

function getMultipleRandomElements(arr: Array<any>, num: number) {
var shuffled = [...arr].sort(() => 0.5 - Math.random())
return shuffled.slice(0, num)

const result: Array<any> = [];
const range = Array.from({length: arr.length}, (_, i) => i);

for (var i = 0; i < num; i++) {
const n = Math.floor(Math.random() * range.length);
const index = range.splice(n, 1)[0];
result.push(arr[index]);
}

return result;
}

function isIp(str: string) {
Expand Down

0 comments on commit b616708

Please sign in to comment.