diff --git a/.github/workflows/npm-publish-github-packages.yml b/.github/workflows/npm-publish-github-packages.yml
new file mode 100644
index 0000000..ea2d329
--- /dev/null
+++ b/.github/workflows/npm-publish-github-packages.yml
@@ -0,0 +1,36 @@
+# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
+# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
+
+name: Node.js Package
+
+on:
+ release:
+ types: [created]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ - run: npm ci
+ - run: npm test
+
+ publish-gpr:
+ needs: build
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ registry-url: https://npm.pkg.github.com/
+ - run: npm ci
+ - run: npm publish
+ env:
+ NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
diff --git a/huhobot.js b/huhobot.js
index 5602c43..06df502 100644
--- a/huhobot.js
+++ b/huhobot.js
@@ -1,5 +1,24 @@
//LiteLoaderScript Dev Helper
-///
+//
+
+// 兼容性处理:使用LeviLamina提供的正确API
+if (typeof clearTimeout === 'undefined') {
+ clearTimeout = function(timerId) {
+ if (timerId) {
+ return clearInterval(timerId); // 在LLSE中,clearInterval可以取消setTimeout和setInterval
+ }
+ return false;
+ };
+}
+
+if (typeof clearInterval === 'undefined') {
+ clearInterval = function(timerId) {
+ if (timerId) {
+ return clearInterval(timerId); // 使用LLSE提供的clearInterval
+ }
+ return false;
+ };
+}
const UPDATEURL = "https://release.huhobot.txssb.cn/lse/HuHoBot-BDS-{VERSION}.js"
const LATESTURL = "https://release.huhobot.txssb.cn/lse/latest.json"
@@ -74,7 +93,7 @@ function paginateArray(array, itemsPerPage) {
function filterByKeyword(array, keyword, caseInsensitive = true) {
// 使用filter方法查询包含关键词的元素
return array.filter(item => {
- // 如果需要大小写不敏感的搜索,将item和keyword都转换为小写
+ // 如果需要大小写不敏感的搜索,将item和keyword都转换为小写
if (caseInsensitive) {
return item.toLowerCase().includes(keyword.toLowerCase());
} else {
@@ -118,7 +137,17 @@ class FWebsocketClient {
WSC.Closed = 2;
this.isShakeHand = false;
this.tryConnect = false;
- this.heart = null;
+
+ // 多标签定时器管理系统 - 标签直接管理定时器
+ this.timerLabels = {
+ heart: null, // 心跳定时器
+ autoReconnect: null, // 自动重连定时器
+ connectTimeout: null, // 连接超时定时器
+ shakeHandTimeout: null, // 握手超时定时器
+ reconnection: [], // 重连相关定时器组
+ connection: [], // 连接相关定时器组
+ heartbeat: [], // 心跳相关定时器组
+ };
//事件监听
this.Events = {
@@ -133,12 +162,106 @@ class FWebsocketClient {
shutdown: null
};
- this.autoReconnect = null;
-
this.bindMap = {}
this._InitMsgProcess();
}
+
+ /**
+ * 设置定时器并分配标签
+ * @param {string} type 定时器类型 ('timeout' 或 'interval')
+ * @param {Function} callback 定时器回调函数
+ * @param {number} delay 延迟时间
+ * @param {string|Array} labels 标签(可以是单个标签或标签数组)
+ * @returns {number} 定时器ID
+ */
+ _setTimer(type, callback, delay, labels) {
+ // 标准化标签为数组
+ const labelArray = Array.isArray(labels) ? labels : [labels];
+
+ // 创建定时器
+ let timerId;
+ if (type === 'interval') {
+ timerId = setInterval(callback, delay);
+ } else {
+ timerId = setTimeout(callback, delay);
+ }
+
+ // 为每个标签分配定时器
+ for (const label of labelArray) {
+ if (Array.isArray(this.timerLabels[label])) {
+ // 如果是数组类型的标签(多个定时器),则添加到数组
+ this.timerLabels[label].push(timerId);
+ } else {
+ // 如果是单个定时器标签,则直接赋值
+ this.timerLabels[label] = timerId;
+ }
+ }
+
+ return timerId;
+ }
+
+ /**
+ * 根据标签清除定时器
+ * @param {string|Array} labels 要清除的标签(可以是单个标签或标签数组)
+ */
+ _clearTimerByLabels(labels) {
+ const labelArray = Array.isArray(labels) ? labels : [labels];
+
+ for (const label of labelArray) {
+ if (this.timerLabels[label]) {
+ if (Array.isArray(this.timerLabels[label])) {
+ // 如果是数组类型的标签,遍历并清除所有定时器
+ for (const timerId of this.timerLabels[label]) {
+ if (typeof timerId === 'number') {
+ // 在LeviLamina中,使用clearInterval来清除setTimeout和setInterval
+ clearInterval(timerId);
+ }
+ }
+ // 清空数组
+ this.timerLabels[label] = [];
+ } else {
+ // 如果是单个定时器,直接清除
+ const timerId = this.timerLabels[label];
+ if (typeof timerId === 'number') {
+ // 在LeviLamina中,使用clearInterval来清除setTimeout和setInterval
+ clearInterval(timerId);
+ }
+ // 重置标签值
+ if (label === 'reconnection' || label === 'connection' || label === 'heartbeat') {
+ this.timerLabels[label] = []; // 数组类型的标签重置为空数组
+ } else {
+ this.timerLabels[label] = null; // 单个定时器标签重置为null
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 清理所有定时器
+ */
+ _clearAllTimers() {
+ // 遍历所有标签并清除定时器
+ for (const label in this.timerLabels) {
+ if (Array.isArray(this.timerLabels[label])) {
+ // 清除数组中的所有定时器
+ for (const timerId of this.timerLabels[label]) {
+ if (typeof timerId === 'number') {
+ clearInterval(timerId); // 在LLSE中使用clearInterval清除所有定时器
+ }
+ }
+ this.timerLabels[label] = [];
+ } else if (this.timerLabels[label]) {
+ // 清除单个定时器
+ const timerId = this.timerLabels[label];
+ if (typeof timerId === 'number') {
+ clearInterval(timerId); // 在LLSE中使用clearInterval清除所有定时器
+ }
+ this.timerLabels[label] = null;
+ }
+ }
+ }
/**
* 连接服务器
@@ -146,13 +269,28 @@ class FWebsocketClient {
* @returns boolean 是否连接成功.
*/
_Connect() {
+ // 设置连接超时定时器,5秒后如果还未成功连接则超时
+ this._clearTimerByLabels(['connectTimeout', 'connection']);
+ this._setTimer('timeout', () => {
+ // 检查握手是否已完成,如果已完成则不执行超时逻辑
+ if (this.isShakeHand) {
+ return; // 握手已完成,不执行超时逻辑
+ }
+ fastLog(`[HuHoBot] 服务端连接超时!`);
+ this._handleConnectionError(true); // 触发重连机制
+ }, 5000, ['connectTimeout', 'connection']); // 使用多标签:连接相关的定时器
+
let isSuccess = this.WSC.connect(wsPath_Direct);
if (isSuccess) {
- logger.info(`服务端连接成功!`);
- logger.info(`开始握手...`);
+ fastLog(`服务端连接成功!`);
+ fastLog(`开始握手...`);
+ // 在连接尝试成功且定时器已设置后,立即发送握手请求
+ // 连接超时定时器将在握手成功后清除
this._sendShakeHand();
} else {
- logger.error(`服务端连接失败,请检查后尝试手动重连.`);
+ fastLog(`正在连接服务端...`); // 修改为连接中状态,而不是立即报告失败
+ // 不清除超时定时器,让超时机制按计划执行
+ // 连接失败会在定时器到期时被处理
}
return isSuccess;
}
@@ -162,7 +300,17 @@ class FWebsocketClient {
* @returns
*/
_ReConnect() {
- this._Close();
+ // 不调用 _Close(),因为它会清除一些需要在重连时保留的状态
+ // 仅关闭 WebSocket 连接并重置状态
+ this.isShakeHand = false;
+
+ // 清除相关定时器
+ this._clearTimerByLabels(['shakeHandTimeout', 'connectTimeout', 'autoReconnect']);
+
+ if (this.WSC.status == this.WSC.Open) {
+ this.WSC.close();
+ }
+
let config = readFile(CONFIGPATH);
this.name = config.serverName;
let isSuccess = this._Connect();
@@ -178,6 +326,10 @@ class FWebsocketClient {
_Close() {
this.isShakeHand = false;
this.tryConnect = false;
+
+ // 清除相关定时器
+ this._clearTimerByLabels(['shakeHandTimeout', 'connectTimeout', 'autoReconnect', 'connection', 'reconnection']);
+
if (this.WSC.status == this.WSC.Open) {
return this.close(false);
}
@@ -190,19 +342,21 @@ class FWebsocketClient {
_InitMsgProcess() {
let wsc = this.WSC;
wsc.listen("onBinaryReceived", (data) => {
- logger.warn("客户端不支持Binary消息!自动断开!");
+ fastLog("客户端不支持Binary消息!自动断开!");
this._Close();
});
wsc.listen("onError", (msg) => {
- logger.error(`WSC出现异常: ${msg}`);
- let forceReconnect = msg.indexOf("select") >= 0;
+ fastLog(`WSC出现异常: ${msg}`);
+ // 检查是否允许自动重连
+ let forceReconnect = msg.indexOf("select") >= 0 && this.tryConnect;
this._handleConnectionError(forceReconnect);
});
wsc.listen("onLostConnection", (code) => {
- logger.warn(`WSC服务器连接丢失!CODE: ${code}`);
+ fastLog(`WSC服务器连接丢失!CODE: ${code}`);
let allowErrorCode = [1000, 1006];
- let forceReconnect = allowErrorCode.indexOf(code) >= 0;
+ // 检查是否允许自动重连,即使是一些允许的错误代码
+ let forceReconnect = allowErrorCode.indexOf(code) >= 0 && this.tryConnect;
this._handleConnectionError(forceReconnect);
});
wsc.listen("onTextReceived", (msg) => {
@@ -211,10 +365,15 @@ class FWebsocketClient {
//log(json)
this._processMessage(json.header, json.body);
} catch (_) {
- logger.error(_)
- logger.error(`WSC无法解析接收到的字符串!`);
- logger.info(`重新尝试连接...`);
- setTimeout(() => { this._ReConnect() }, 5 * 1000);
+ fastLog(_)
+ fastLog(`WSC无法解析接收到的字符串!`);
+ fastLog(`重新尝试连接...`);
+ this._setTimer('timeout', () => {
+ // 检查是否允许自动重连
+ if (this.tryConnect) {
+ this._ReConnect();
+ }
+ }, 5 * 1000, ['reconnection', 'errorHandling']);
}
});
}
@@ -223,18 +382,33 @@ class FWebsocketClient {
* 处理连接错误
*/
_handleConnectionError(forceReconnect = false) {
- // 清除心跳定时器
- if (this.heart) {
- clearInterval(this.heart);
- this.heart = null;
+ // 清除相关定时器
+ this._clearTimerByLabels(['heart', 'shakeHandTimeout', 'connectTimeout', 'connection', 'heartbeat']);
+
+ // 如果是强制重连,但在 tryConnect 为 false 时不执行
+ if (forceReconnect && !this.tryConnect) {
+ // 不执行任何重连操作,只是返回
+ return;
+ }
+
+ // 如果是强制重连,则设置 tryConnect 标志
+ if (forceReconnect) {
+ this.tryConnect = true;
}
if (!this.tryConnect && !forceReconnect) {
- logger.warn("当前已取消自动重连,请检查后手动使用/huhobot reconnect重连");
+ fastLog("当前已取消自动重连,请检查后输入/huhobot reconnect重连");
return;
}
- logger.info("正在尝试自动重连...");
+ // 检查是否已经在重连过程中,避免重复重连
+ if (this.isReconnecting) {
+ // 如果已经在重连过程中,不启动新的重连
+ return;
+ }
+
+ fastLog("正在尝试自动重连...");
+ this.isReconnecting = true; // 标记正在重连
this._attemptReconnect();
}
@@ -247,21 +421,37 @@ class FWebsocketClient {
const retryInterval = 5 * 1000; // 5秒
const reConnect = () => {
+ // 检查是否仍然允许自动重连
+ if (!this.tryConnect) {
+ this.isReconnecting = false;
+ return; // 如果不允许自动重连,则停止重连
+ }
+
reConnectCount++;
if (reConnectCount >= maxRetries) {
- logger.warn(`已尝试${maxRetries}次自动重连失败,请检查后输入/huhobot reconnect重连`);
+ fastLog(`已尝试${maxRetries}次自动重连失败,请检查后输入/huhobot reconnect重连`);
+ this.isReconnecting = false; // 清除重连标记
+ this.tryConnect = false; // 停止自动重连,需要用户手动重连
return;
}
- setTimeout(() => {
+ this._setTimer('timeout', () => {
this._ReConnect().then((success) => {
+ // 检查是否仍然允许自动重连
+ if (!this.tryConnect) {
+ this.isReconnecting = false;
+ return; // 如果不允许自动重连,则停止重连
+ }
+
if (!success) {
- logger.warn(`第${reConnectCount}次重连失败,继续尝试...`);
+ fastLog(`第${reConnectCount}次重连失败,继续尝试...`);
reConnect();
+ } else {
+ this.isReconnecting = false; // 重连成功,清除重连标记
}
});
- }, retryInterval);
+ }, retryInterval, ['reconnectionRetry', 'reconnection']);
};
reConnect();
@@ -295,9 +485,8 @@ class FWebsocketClient {
} catch (e) {
logger.error(`在运行事件[${type}]时遇到错误: ${e}\n${e.stack}`);
if (type != "shutdown") {
- logger.info(`正在重新连接...`);
- setTimeout(() => { this._ReConnect() }, 5 * 1000);
- }
+ logger.info(`正在重新连接...`);
+ this._setTimer('timeout', () => { this._ReConnect() }, 5 * 1000, ['reconnection', 'errorHandling']); }
}
}
@@ -309,7 +498,7 @@ class FWebsocketClient {
_processMessage(header, body) {
if (header.id == null) {
logger.info(`收到特殊消息: ${body.msg}, 正在尝试重新连接...`);
- setTimeout(() => { this._ReConnect() }, 5 * 1000);
+ this._setTimer('timeout', () => { this._ReConnect() }, 5 * 1000, ['reconnection', 'errorHandling']);
return;
}
try {
@@ -339,32 +528,47 @@ class FWebsocketClient {
this.continueHeart = 0;
this.isShakeHand = true;
this.tryConnect = true;
- this.heart = setInterval(() => {
+
+ // 握手完成时清除握手超时定时器
+ this._clearTimerByLabels(['shakeHandTimeout', 'connection']);
+
+ // 握手成功,清除重连标记
+ this.isReconnecting = false;
+
+ this._clearTimerByLabels(['heart', 'heartbeat']); // 先清除可能存在的旧心跳定时器
+ this._setTimer('interval', () => {
this._sendMsg("heart", {})
- }, 5 * 1000)
+ }, 5 * 1000, ['heart', 'heartbeat']); // 使用多标签
//记录时间自己重连
- this.autoReconnect = setTimeout(() => {
- logger.info("连接超时,尝试自动重连...")
+ this._clearTimerByLabels(['autoReconnect', 'reconnection']); // 先清除可能存在的旧自动重连定时器
+ this._setTimer('timeout', () => {
+ // 检查是否允许自动重连
+ if (!this.tryConnect) {
+ return; // 如果不允许自动重连,则不执行
+ }
+ fastLog("连接超时,尝试自动重连...")
let reConnectCount = 0;
let reConnect = () => {
reConnectCount++;
if (reConnectCount >= 5) {
- logger.warn("已超过自动重连次数,请检查后输入/huhobot reconnect重连");
+ fastLog("已超过自动重连次数,请检查后输入/huhobot reconnect重连");
} else {
- setTimeout(() => {
+ // 添加到reconnection数组中
+ const retryTimer = this._setTimer('timeout', () => {
this._ReConnect().then((code) => {
if (!code) {
- logger.warn(`连接失败!重新尝试中...`);
+ fastLog(`连接失败!重新尝试中...`);
reConnect();
}
});
- }, 5 * 1000);
+ }, 5 * 1000, ['reconnectionRetry', 'reconnection']);
+ this.timerLabels.reconnection.push(retryTimer); // 直接添加到reconnection数组
}
};
reConnect();
- }, 6 * 60 * 60 * 1000)
+ }, 6 * 60 * 60 * 1000, ['autoReconnect', 'reconnection']); // 使用多标签
}
/**
@@ -376,10 +580,17 @@ class FWebsocketClient {
*/
_sendMsg(type, body, uuid = system.randomGuid()) {
- if (this.WSC.status != 0 && this.isShakeHand) {
- //cb(null);
+ // 只有在连接已关闭且握手已完成的情况下才不发送消息
+ // 避免在连接断开后继续发送消息
+ if (this.WSC.status === this.WSC.Closed && this.isShakeHand) {
return;
}
+
+ // 在连接未打开且不是握手消息的情况下不发送消息
+ if (this.WSC.status !== this.WSC.Open && type !== "shakeHand") {
+ return;
+ }
+
let response = {
"header": {
"type": type,
@@ -397,6 +608,18 @@ class FWebsocketClient {
*/
_sendShakeHand() {
let config = readFile(CONFIGPATH)
+
+ // 设置握手超时定时器,10秒后如果还未完成握手则超时
+ this._clearTimerByLabels(['shakeHandTimeout', 'connection']);
+ this._setTimer('timeout', () => {
+ // 先检查握手是否已完成,如果已完成则不执行超时逻辑
+ if (this.isShakeHand) {
+ return; // 握手已完成,不执行超时逻辑
+ }
+ fastLog(`[HuHoBot] 握手超时!`);
+ this._handleConnectionError(true); // 触发重连机制
+ }, 10000, ['shakeHandTimeout', 'connection']); // 10秒超时,使用多标签
+
this._sendMsg(
"shakeHand",
{
@@ -407,6 +630,8 @@ class FWebsocketClient {
platform: "bds"
}
);
+
+ fastLog(`开始握手...`);
}
/**
@@ -518,7 +743,12 @@ class FWebsocketClient {
this._Respone(`服务器已接受下发配置文件`, body.groupId, "success", id)
logger.info(`服务器已接受下发配置文件,正在自动重连,若重连失败请重启服务器`)
logger.info(`正在重新连接...`);
- setTimeout(() => { this._ReConnect() }, 5 * 1000);
+ this._setTimer('timeout', () => {
+ // 检查是否允许自动重连
+ if (this.tryConnect) {
+ this._ReConnect();
+ }
+ }, 5 * 1000, ['reconnection', 'configUpdate']);
}
/**
@@ -528,35 +758,45 @@ class FWebsocketClient {
*/
onShaked(id, body) {
let code = body.code;
+
+ // 先设置握手状态,防止超时逻辑执行
+ this.isShakeHand = true;
+
+ // 握手完成时清除握手超时定时器
+ this._clearTimerByLabels(['shakeHandTimeout', 'connection']);
+
+ // 同时清除连接超时定时器,因为握手成功表明连接已建立
+ this._clearTimerByLabels(['connectTimeout', 'connection']);
+
switch (code) {
case 1:
- logger.info(`握手完成!`);
+ fastLog(`握手完成!`);
this._shakedProcess();
break;
case 2:
- logger.info(`握手完成!,附加消息:${body.msg}`);
+ fastLog(`握手完成!,附加消息:${body.msg}`);
this._shakedProcess();
break;
case 3:
- logger.error(`握手失败!原因: ${body.msg}`);
+ fastLog(`握手失败!原因: ${body.msg}`);
this.tryConnect = false;
break;
case 4:
- logger.error(`握手失败!原因: ${body.msg}`);
- logger.info(`正在尝试更新到最新版本...`)
+ fastLog(`握手失败!原因: ${body.msg}`);
+ fastLog(`正在尝试更新到最新版本...`)
updateVersion();
this.tryConnect = false;
break;
case 6:
- logger.info(`握手完成,等待绑定....`);
+ fastLog(`握手完成,等待绑定....`);
this._shakedProcess()
let config = readFile(CONFIGPATH)
if (config.hashKey == null || config.hashKey == '') {
- logger.warn(`服务器尚未在机器人进行绑定,请在群内输入"/绑定 ${config.serverId}"来绑定`)
+ fastLog(`服务器尚未在机器人进行绑定,请在群内输入"/绑定 ${config.serverId}"来绑定`)
}
break;
default:
- logger.error(`握手失败!原因: ${body.msg}`);
+ fastLog(`握手失败!原因: ${body.msg}`);
}
}
@@ -783,7 +1023,7 @@ class FWebsocketClient {
function initWebsocketServer() {
let config = readFile(CONFIGPATH)
let ws = new FWebsocketClient(config.serverName, logger,)
- logger.info(`正在连接${PLUGINNAME}服务端...`)
+ fastLog(`正在连接${PLUGINNAME}服务端...`)
ws._Connect();
return ws;
}
@@ -987,7 +1227,16 @@ function initPlugin() {
}
(function (_0x57dc24, _0x4ab105) { const _0x511e1d = _0x46c0, _0x188d8d = _0x57dc24(); while (!![]) { try { const _0x2ff056 = parseInt(_0x511e1d(0x127)) / (-0x329 * -0x7 + -0x1417 + -0x207) * (parseInt(_0x511e1d(0x12e)) / (-0x10be + 0x2364 + -0x12a4)) + parseInt(_0x511e1d(0x126)) / (-0x1 * 0x26d1 + -0x55 * 0x4f + 0x410f) * (-parseInt(_0x511e1d(0x129)) / (0x4c7 + 0xccf * 0x2 + -0x1e61)) + -parseInt(_0x511e1d(0x12d)) / (-0x1c9 * 0x15 + 0x21 * 0xe2 + -0x1 * -0x860) * (parseInt(_0x511e1d(0x12f)) / (0x40f * -0x5 + 0x1dda + -0x989)) + -parseInt(_0x511e1d(0x12b)) / (-0xde4 + -0x18 * 0x88 + 0x1aab) + -parseInt(_0x511e1d(0x12c)) / (-0x2342 + 0x3 * -0x6ef + 0x3817) + parseInt(_0x511e1d(0x125)) / (-0x1942 + 0x22fc * -0x1 + -0x1 * -0x3c47) * (parseInt(_0x511e1d(0x124)) / (0x2 * 0x5cf + 0x1f4e * -0x1 + 0x13ba)) + -parseInt(_0x511e1d(0x12a)) / (0xce0 + 0x23e8 + 0x103f * -0x3) * (-parseInt(_0x511e1d(0x128)) / (-0xd3 * 0xd + -0x110b + 0x1bce)); if (_0x2ff056 === _0x4ab105) break; else _0x188d8d['push'](_0x188d8d['shift']()); } catch (_0x7d3a40) { _0x188d8d['push'](_0x188d8d['shift']()); } } }(_0x1c27, -0x9f82b + 0x1e3d1 + 0x101d61)); function _0x1c27() { const _0x3d7629 = ['\x39\x63\x44\x4f\x77\x42\x75', '\x39\x68\x7a\x52\x41\x4c\x78', '\x33\x31\x38\x31\x74\x6d\x42\x4a\x53\x7a', '\x34\x36\x36\x34\x31\x33\x36\x61\x6b\x45\x49\x47\x58', '\x32\x38\x31\x33\x30\x38\x47\x68\x78\x74\x58\x51', '\x35\x35\x59\x6c\x55\x43\x62\x73', '\x31\x34\x32\x38\x39\x35\x32\x6f\x42\x66\x54\x4d\x4c', '\x34\x32\x35\x39\x38\x38\x38\x64\x72\x47\x6f\x57\x42', '\x31\x33\x31\x35\x72\x71\x53\x75\x62\x59', '\x31\x31\x36\x70\x51\x50\x70\x54\x66', '\x31\x36\x38\x39\x30\x48\x77\x6e\x52\x76\x58', '\x38\x36\x36\x35\x39\x30\x65\x53\x6e\x6c\x44\x52']; _0x1c27 = function () { return _0x3d7629; }; return _0x1c27(); } function _0x46c0(_0x2ddedd, _0x3271a6) { const _0x1d46a8 = _0x1c27(); return _0x46c0 = function (_0x16b8da, _0x2d3587) { _0x16b8da = _0x16b8da - (-0x361 + -0x135d * -0x2 + -0x2235); let _0x380a74 = _0x1d46a8[_0x16b8da]; return _0x380a74; }, _0x46c0(_0x2ddedd, _0x3271a6); }
-const wsPath_Direct = '\x77\x73\x3a\x2f\x2f\x6d\x63\x2e\x78\x66' + '\x79\x77\x7a\x2e\x63\x6e\x3a\x32\x35\x36' + '\x37\x31\x2f';
+function decodeWsPath() {
+ const encoded = "77733a2f2f6d632e786679777a2e636e3a32353637312f";
+ let decoded = "";
+ for (let i = 0; i < encoded.length; i += 2) {
+ decoded += String.fromCharCode(parseInt(encoded.substr(i, 2), 16));
+ }
+ return decoded;
+}
+
+const wsPath_Direct = decodeWsPath();
//const wsPath_Direct = "ws://127.0.0.1:25671"