diff --git a/assets/css/style.css b/assets/css/style.css index 044a13d..5a8b67c 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -285,7 +285,7 @@ img[alt="loader"] { } .xsWidth input, .xsWidth select { - width: 33%; + width: 33.33%; float: left; border-radius: 0; } @@ -299,6 +299,77 @@ img[alt="loader"] { border-left: transparent; border-radius: 0 3px 3px 0; } +.xsWidth.withSmallCenter select:first-child, +.xsWidth.withSmallCenter input:first-child { + width: 150px; +} +.xsWidth.withSmallCenter select:nth-child(2), +.xsWidth.withSmallCenter input:nth-child(2) { + width: calc(100% - 250px); +} +.xsWidth.withSmallCenter select:last-child, +.xsWidth.withSmallCenter input:last-child { + width: 100px; +} + +p { + font-size: 14px; +} +.orClass { + float: right; + width: 100%; + position: relative; + border-bottom: 1px solid #ededed; + margin: 20px 0; +} +.orClass small { + text-align: center; + display: flex; + align-items: center; + justify-content: center; + position: relative; + margin-bottom: -9px; + text-shadow: 0 0 7px #fff; +} + +.switch { + position: relative; + display: inline-block; + height: 26px; + float: left; + margin: 0 7px 10px 0; +} +.switch input { + opacity: 0; + width: 0; + height: 0; +} +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #fff; + border: 1px solid #aecede; + -webkit-transition: .4s; + transition: .4s; + border-radius: 25px; + cursor: pointer; +} +input:checked + .slider { + background-color: #d3e5ed; +} +.switch strong { + float: right; + margin: 3px 15px 0 15px; + position: relative; + z-index: 1; + font-weight: 400; + font-size: 13px; + cursor: pointer; +} footer { padding: 10px 0; diff --git a/assets/js/script.js b/assets/js/script.js index e179732..443788d 100644 --- a/assets/js/script.js +++ b/assets/js/script.js @@ -1,3 +1,198 @@ +const protocols = ["vless", "vmess"]; +const ports = ["443", "2053", "2083", "2087", "2096", "8443"]; + +function parser(protocol, config) { + if ( protocol === 'vmess' ) { + config = base64Decode(config); + config = Object.assign({ + 'protocol': protocol, + }, (config)); + } + else if ( protocol === 'vless' ) { + config = Object.assign({ + 'protocol': protocol, + 'id': getHashId(config), + 'address': getAddress(config)[0], + 'port': getAddress(config)[1], + }, parseQuery(config)); + } + return config; +} + +function parseQuery(config) { + let query = {}; + let protocol = getProtocol(config); + if ( protocol === 'vmess' ) { + query = base64Decode(config); + } + else { + let string = config.split("?"); + if ( typeof string[1] !== 'undefined' ) { + string = string[1].split("#"); + if ( typeof string[0] !== 'undefined' ) { + let pairs = string[0].split('&'); + for (let i = 0; i < pairs.length; i++) { + let pair = pairs[i].split('='); + query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || ''); + } + if ( typeof string[1] !== 'undefined' ) { + query['remark'] = decodeURIComponent(string[1]); + } + } + } + } + return query; +} + +function getProtocol(config) { + let string = config.split("://"); + if ( typeof string[0] !== 'undefined' ) { + return string[0]; + } + return ''; +} + +function getHashId(config) { + let string = config.split("@"); + if ( typeof string[0] !== 'undefined' ) { + let protocol = getProtocol(config); + return string[0].replace(protocol+"://", ""); + } + return ''; +} + +function getAddress(config) { + let protocol = getProtocol(config); + if ( protocol === 'vmess' ) { + config = base64Decode(config); + return [ + config.add, + String(config.port), + ] + } + else { + let string = config.split("@"); + if ( typeof string[1] !== 'undefined' ) { + string = string[1].split("?"); + if ( typeof string[0] !== 'undefined' ) { + string = string[0].split(":"); + if ( typeof string[0] !== 'undefined' && typeof string[1] !== 'undefined' ) { + return [ + string[0], + string[1].split("#")[0], + ] + } + } + } + } + return ['', '']; +} + +function base64Decode(config) { + try { + config = config.replace("vmess://", ""); + return JSON.parse(atob(config)); + } + catch { + return {}; + } +} + +$(document).on('keyup', '#defConfig', function(e) { + e.preventDefault(); + let config = $(this).val().trim(); + if ( config === '' ) { + console.clear(); + $('#protocol option').removeAttr('selected'); + $('#tls').prop('checked', true); + $('#early').prop('checked', true); + $('#uuid').val(""); + $('#port').val(""); + $('#sni').val(""); + $('#cleanIp').val(""); + $('#path').val(""); + $('#concurrency').val(""); + $('#packets').val('tlshello'); + $('#length').val('10-20'); + $('#interval').val('10-20'); + return false; + } + let protocol = getProtocol(config); + $('#protocol option').removeAttr('selected'); + $('#protocol option[value="'+protocol+'"]').attr('selected', 'selected'); + /*if ( ! protocols.includes(protocol) ) { + return false; + }*/ + $('#uuid').val(getHashId(config)); + $('#port').val(getAddress(config)[1]); + let defConfig = parser(protocol, config); + if ( (protocol === 'vmess' && defConfig.tls === "tls") || (protocol === 'vless' && defConfig.security === "tls") ) { + $('#tls').prop('checked', true); + $('#packets').val('tlshello'); + $('#length').val('10-20'); + $('#interval').val('10-20'); + } + else { + $('#tls').prop('checked', false); + $('#packets').val('1-1'); + $('#length').val('3-5'); + $('#interval').val('5'); + } + $('#sni').val(defConfig.host); + if ( protocol === 'vmess' ) { + $('#cleanIp').val(defConfig.add); + } + else { + $('#cleanIp').val(defConfig.address); + } + let early = $('#early').is(':checked'); + let path = defConfig.path; + if ( early ) { + path = path+'/?ed=2048'; + path = path.replace('//', '/'); + } + $('#path').val(path); +}); + +$(document).on('click', '#early', function(e) { + let early = $('#early').is(':checked'); + let path = $('#path').val(); + if ( !early ) { + $('#path').val(path.replace('/?ed=2048', '')); + } + else { + path = path+'/?ed=2048'; + path = path.replace('//', '/'); + $('#path').val(path); + } +}); + +$(document).on('click', '#tls', function(e) { + let tls = $('#tls').is(':checked'); + if ( tls ) { + $('#packets').val('tlshello'); + $('#length').val('10-20'); + $('#interval').val('10-20'); + } + else { + $('#packets').val('1-1'); + $('#length').val('3-5'); + $('#interval').val('5'); + } +}); + +$(document).on('click', '#mux', function(e) { + let mux = $('#mux').is(':checked'); + if ( mux ) { + $('#concurrency').val('8'); + $('#muxForm').removeClass('none'); + } + else { + $('#concurrency').val(''); + $('#muxForm').addClass('none'); + } +}); + function randomizeCase(inputString) { let resultString = ''; for (let i = 0; i < inputString.length; i++) { @@ -17,7 +212,7 @@ function cleanUrl(url) { $(document).on('click', '#getFile', function(e) { e.preventDefault(); let protocol = $('#protocol').val(); - let network = $('#network').val(); + //let network = $('#network').val(); let uuid = $('#uuid').val(); let sni = cleanUrl($('#sni').val()); let port = $('#port').val(); @@ -29,9 +224,12 @@ $(document).on('click', '#getFile', function(e) { if (path.endsWith("/")) { path = path.substring(0, path.length - 1); } + path = path.replace('//', '/'); } - let tls = $('#tls').val(); - let early = $('#early').val(); + let tls = $('#tls').is(':checked'); + let mux = $('#mux').is(':checked'); + let concurrency = $('#concurrency').val(); + //let early = $('#early').is(':checked'); let cleanIp = $('#cleanIp').val(); if ( cleanIp === '' ) { cleanIp = 'zula.ir'; @@ -44,29 +242,34 @@ $(document).on('click', '#getFile', function(e) { .then(response => response.json()) .then(data => { data.outbounds[0].protocol = protocol; - data.outbounds[0].streamSettings.network = network; - data.outbounds[0].streamSettings.tlsSettings.serverName = sni; - data.outbounds[0].streamSettings.wsSettings.headers.Host = sni; - if ( early === 'on' ) { - data.outbounds[0].streamSettings.wsSettings.path = path+'/?ed=2048'; + if ( mux ) { + data.outbounds[0].mux.enabled = true; + data.outbounds[0].mux.concurrency = Number(concurrency); } else { - data.outbounds[0].streamSettings.wsSettings.path = path; + data.outbounds[0].mux.enabled = false; + data.outbounds[0].mux.concurrency = Number(-1); } + data.outbounds[0].streamSettings.network = "ws"; + data.outbounds[0].streamSettings.tlsSettings.serverName = sni; + data.outbounds[0].streamSettings.wsSettings.headers.Host = sni; + data.outbounds[0].streamSettings.wsSettings.path = path; data.outbounds[0].settings.vnext[0].port = Number(port); data.outbounds[0].settings.vnext[0].users[0].id = uuid; data.outbounds[0].settings.vnext[0].address = cleanIp; - data.outbounds[0].streamSettings.security = tls; - if ( tls === 'tls' ) { + + if ( tls ) { data.outbounds[1].settings.fragment.packets = 'tlshello'; data.outbounds[1].settings.fragment.length = '10-20'; data.outbounds[1].settings.fragment.interval = '10-20'; + data.outbounds[0].streamSettings.security = "tls"; } else { data.outbounds[1].settings.fragment.packets = '1-1'; data.outbounds[1].settings.fragment.length = '3-5'; data.outbounds[1].settings.fragment.interval = '5'; delete data.outbounds[0].streamSettings.tlsSettings; + delete data.outbounds[0].streamSettings.security; } //console.log(data) downloadJsonFile(data, 'fragment [ircf.space].json'); diff --git a/index.html b/index.html index 907c114..8820f63 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - +
توسط ابزار فرگمنت میتونین دامنههای مردهتون رو مجدد زنده کنید!
یک کانفیگ VLESS/VMESS از نوع webSocket وارد کنین:
+ +یا تنظیمات زیر رو بهصورت دستی تکمیل کنین:
+