Bc DGLAB

Connects to the DGLAB via official API.

// ==UserScript==
// @name Bc DGLAB
// @description Connects to the DGLAB via official API.
// @version Preview 4
// @namespace awaqwq_huzpsb
// @match *://*/*BondageClub*
// @grant GM_registerMenuCommand
// @license WTFPL
// ==/UserScript==

function loadScript(url, callback) {
    const script = document.createElement("script");
    script.type = "text/javascript";
    script.src = url;

    script.onload = function () {
        callback();
    };

    script.onerror = function () {
        alert("加载依赖失败,请检查网络连接!");
        window.location.reload();
    };

    document.head.appendChild(script);
}


var wsConn = null;
var connected = false;
var connectionId = null;
var targetWSId = null;

var limitA = 0;
var limitB = 0;
var nowA = 0;
var nowB = 0;

var taskEndA = 0;
var taskEndB = 0;

function sendWsMsg(messageObj) {
    messageObj.clientId = connectionId;
    messageObj.targetId = targetWSId;
    if (!messageObj.hasOwnProperty('type'))
        messageObj.type = "msg";
    wsConn.send(JSON.stringify((messageObj)));
}

function connectWs() {
    {
        const floatingImage = document.getElementById("floatingImage");
        if (floatingImage) {
            alert("请直接使用右下角的二维码连接设备!");
            return;
        }
        if (connected) {
            alert("已连接设备,请勿重复连接!");
            return;
        }
    }


    wsConn = new WebSocket("wss://ws.dungeon-lab.cn/");
    wsConn.onclose = function () {
        const floatingImage = document.getElementById("floatingImage");
        if (floatingImage) {
            floatingImage.remove();
        }
        connected = false;
        alert("连接已断开,请重新连接设备!");
    };

    wsConn.onmessage = function (event) {
        let message = null;
        try {
            message = JSON.parse(event.data);
        } catch (e) {
            console.log("收到设备回传:", event.data);
            return;
        }
        console.log("收到中继回传:", message);

        switch (message.type) {
            case 'bind':
                if (!message.targetId) {
                    connectionId = message.clientId;
                    const connectionUrl = "https://www.dungeon-lab.com/app-download.php#DGLAB-SOCKET#wss://ws.dungeon-lab.cn/" + connectionId;
                    const floatingImage = document.createElement("div");
                    floatingImage.id = "floatingImage";
                    floatingImage.style.position = "fixed";
                    floatingImage.style.width = "220px";
                    floatingImage.style.height = "220px";
                    floatingImage.style.bottom = "0";
                    floatingImage.style.right = "0";
                    floatingImage.style.zIndex = "1000";
                    floatingImage.style.backgroundColor = "darkgray";
                    document.body.appendChild(floatingImage);

                    const realImageDiv = document.createElement("div");
                    realImageDiv.style.margin = "10px";
                    realImageDiv.style.width = "200px";
                    realImageDiv.style.height = "200px";
                    floatingImage.appendChild(realImageDiv);


                    new QRCode(realImageDiv, {
                        text: connectionUrl,
                        width: 200,
                        height: 200,
                    });
                } else {
                    connected = true;
                    const floatingImage = document.getElementById("floatingImage");
                    if (floatingImage) {
                        floatingImage.remove();
                    }
                    targetWSId = message.targetId;
                }
                break;
            case 'break':
            case 'error':
                wsConn.close();
                break;
            case 'msg':
                // 定义一个空数组来存储结果
                const result = [];
                if (message.message.includes("strength")) {
                    const numbers = message.message.match(/\d+/g).map(Number);
                    result.push({type: "strength", numbers});

                    console.log("channel-a:", numbers[0]);
                    console.log("channel-b:", numbers[1]);
                    console.log("limit-a:", numbers[2]);
                    limitA = numbers[2];
                    console.log("limit-b:", numbers[3]);
                    limitB = numbers[3];
                }
                break;
            default:
                break;
        }
    };
}

const waveData = {
    "1": `["0A0A0A0A00000000","0A0A0A0A0A0A0A0A","0A0A0A0A14141414","0A0A0A0A1E1E1E1E","0A0A0A0A28282828","0A0A0A0A32323232","0A0A0A0A3C3C3C3C","0A0A0A0A46464646","0A0A0A0A50505050","0A0A0A0A5A5A5A5A","0A0A0A0A64646464"]`,
    "2": `["0A0A0A0A00000000","0D0D0D0D0F0F0F0F","101010101E1E1E1E","1313131332323232","1616161641414141","1A1A1A1A50505050","1D1D1D1D64646464","202020205A5A5A5A","2323232350505050","262626264B4B4B4B","2A2A2A2A41414141"]`,
    "3": `["4A4A4A4A64646464","4545454564646464","4040404064646464","3B3B3B3B64646464","3636363664646464","3232323264646464","2D2D2D2D64646464","2828282864646464","2323232364646464","1E1E1E1E64646464","1A1A1A1A64646464"]`
}

function setStrength(strength, channel) {
    if (!connected) {
        alert("请先连接设备!");
        return;
    }
    sendWsMsg({type: 4, message: `strength-${channel === 'A' ? 1 : 2}+2+${strength}`})
}

function play(waveId, duration, channel) {
    if (!connected) {
        alert("请先连接设备!");
        return;
    }
    const wave = waveData[waveId];
    if (!wave) {
        alert("无效的波形ID!");
        return;
    }
    sendWsMsg({type: "clientMsg", message: `${channel}:${wave}`, time: duration, channel: channel})
}


loadScript("https://cdn.bootcdn.net/ajax/libs/qrcodejs/1.0.0/qrcode.min.js", function () {
    connectWs();
});

GM_registerMenuCommand('重新连接设备', function () {
    if (wsConn) {
        wsConn.close();
    }
    connectWs();
})

function respond(msg) {
    const parts = msg.split(' ');
    if (parts[0] === '郊狼') {
        if (!connected) {
            return 'Bot故障:设备未连接。请先连接设备。';
        }
        if (parts.length < 2) {
            return '参数缺失。请输入“郊狼 帮助”查看帮助。';
        }
        const timeStamp = Math.floor(Date.now() / 1000);
        switch (parts[1]) {
            case '强度': {
                if (parts.length < 4) {
                    return '错误的语法。正确格式为“郊狼 强度 通道 数值”。';
                }
                let limit = 0;
                if (parts[2] === 'A') {
                    limit = limitA;
                } else if (parts[2] === 'B') {
                    limit = limitB;
                } else {
                    return '无效的通道。请使用“A”或“B”。';
                }
                const strength = parseInt(parts[3]);
                if (isNaN(strength) || strength < 0 || strength > limit) {
                    return `强度值必须在0到${limit}之间。`;
                }
                if (parts[2] === 'A') {
                    nowA = strength;
                } else {
                    nowB = strength;
                }
                setStrength(strength, parts[2]);
                return `已设置强度为 ${strength}。请不要忘了调整波形。`;
            }
            case '波形': {
                if (parts.length < 4) {
                    return '错误的语法。正确格式为“郊狼 波形 通道 波形ID 持续时间(秒)”。';
                }
                let now = 0;
                if (parts[2] === 'A') {
                    now = nowA;
                } else if (parts[2] === 'B') {
                    now = nowB;
                } else {
                    return '无效的通道。请使用“A”或“B”。';
                }
                if (!now) {
                    return `不能在通道强度为0时播放波形。请先设置强度。`;
                }
                const waveId = parts[3];
                if (!waveData[waveId]) {
                    return '无效的波形ID。可用波形ID:1, 2, 3。';
                }
                const duration = parseInt(parts[4]);
                if (isNaN(duration) || duration <= 0) {
                    return '持续时间必须是正整数。';
                }
                if (parts[2] === 'A') {
                    taskEndA = timeStamp + duration;
                } else if (parts[2] === 'B') {
                    taskEndB = timeStamp + duration;
                }
                play(waveId, duration, parts[2]);
                return `已在通道${parts[2]}播放波形${waveId},持续时间为${duration}秒。`;
            }
            case '状态':
                return `当前状态:\n` +
                    `通道A - 强度:${nowA},上限:${limitA},正在输出波形:${taskEndA > timeStamp ? '是' : '否'}\n` +
                    `通道B - 强度:${nowB},上限:${limitB},正在输出波形:${taskEndB > timeStamp ? '是' : '否'}`;
            case '帮助':
                return '郊狼bot命令列表:[强度] [波形] [状态] [帮助]\n' +
                    '如果你也想加入测试,请检查aw酱的bio...并不需要安装插件以外的什么东西,支持手机端。'
            default:
                return '未知命令。请输入“郊狼 帮助”查看帮助。';
        }
    }
    return null
}

ChatRoomMessageDisplay0 = ChatRoomMessageDisplay;
ChatRoomMessageDisplay = function (data, msg, SenderCharacter, metadata) {
    ChatRoomMessageDisplay0(data, msg, SenderCharacter, metadata);
    awHandleBot(SenderCharacter, msg);
}

AwBotLast = '';
awHandleBot = function (sender, message) {
    const msgAndSender = message + sender.Name;
    if (AwBotLast !== msgAndSender) {
        AwBotLast = msgAndSender;
        let response = respond(message);
        if (response) {
            ServerSend('ChatRoomChat', {
                Content: response,
                Type: 'Chat',
                Target: sender.MemberNumber,
            })
        }
    }
}

ChatRoomNotificationRaiseChatJoin = function (p) {
    ServerSend('ChatRoomChat', {
        Content: p.Name + ',你好!本房间是aw酱的郊狼bot插件测试房间,输入“郊狼 帮助”即可查看帮助。她把自己捆了,没法跟你聊天...',
        Type: 'Chat',
        Target: p.MemberNumber,
    })
    return true
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址