123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- <html lang="zh">
- <head>
- <meta charset="utf-8">
- <title>Grasscutters 网页控制台</title>
- <meta name="viewport" content="width=device-width">
- <meta name="apple-mobile-web-app-capable" content="yes">
- <meta name="apple-mobile-web-app-status-bar-style" content="black">
- <meta name="viewport"
- content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=5,user-scalable=yes"/>
- <link rel="stylesheet" href="css/mui.min.css">
- <script src="js/mui.min.js"></script>
- <script type="text/javascript" src="js/cheat.js"></script>
- <script type="text/javascript" src="js/cheat/item_data.js"></script>
- <script type="text/javascript" src="js/cheat/data.js"></script>
- <script type="text/javascript" src="js/cheat/quickcommand.js"></script>
- <script type="text/javascript" src="js/cheat/weapon.js"></script>
- <script type="text/javascript" src="js/cheat/avatar.js"></script>
- <script type="text/javascript" src="js/cheat/reli.js"></script>
- <script type="text/javascript" src="js/cheat/item.js"></script>
- <script type="text/javascript" src="js/cheat/monster.js"></script>
- <script type="text/javascript" src="js/cheat/scene.js"></script>
- <script type="text/javascript" src="js/cheat/quest.js"></script>
- <script type="text/javascript" src="js/qrcode.min.js"></script>
- <style>
- .hidden {
- display: none;
- }
- </style>
- <header class="mui-bar mui-bar-nav">
- <h1 class="mui-title">Grasscutters 网页工具箱</h1>
- </header>
- </head>
- <body>
- <div class="mui-content">
- <div class="mui-card" style="margin-bottom: 35px;">
- <div class="mui-card-header">扫描二维码也可以打开这个页面</div>
- <div id="qrcode"></div>
- </div>
- <div class="mui-card" style="margin-bottom: 35px;">
- <div class="mui-card-header">在线玩家 <br>传送前请先刷新一下列表
- <button type="button" data-loading-text="请稍后" class="mui-btn mui-btn-primary mui-btn-outlined"
- onclick="updatePlayerList()">刷新
- </button>
- </div>
- <ul class="mui-table-view" id="id-player-list">
- </ul>
- </div>
- <div class="mui-card" style="margin-bottom: 35px;">
- <div class="mui-card-header">传送点列表
- <button type="button" data-loading-text="请稍后" class="mui-btn mui-btn-outlined" onclick="addTransfer()">添加
- </button>
- <button type="button" data-loading-text="请稍后" class="mui-btn mui-btn-primary mui-btn-outlined"
- onclick="updateTransferList()">刷新
- </button>
- <button type="button" data-loading-text="请稍后" class="mui-btn mui-btn-danger mui-btn-outlined"
- onclick="delAllTransfer()">全部删除
- </button>
- </div>
- <ul class="mui-table-view" id="id-Transfer-list">
- </ul>
- </div>
- <div class="container">
- <div class="toolset">
- <div class="mui-card">
- <form class="mui-input-group">
- <div class="mui-input-row mui-radio">
- <label for='tab-1'>常用指令</label>
- <input id='tab-1' type='radio' name='tabgroupB' checked>
- </div>
- <div class="mui-input-row mui-radio">
- <label for='tab-2'>角色</label>
- <input id='tab-2' type='radio' name='tabgroupB'>
- </div>
- <div class="mui-input-row mui-radio">
- <label for='tab-3'>武器</label>
- <input id='tab-3' type='radio' name='tabgroupB'>
- </div>
- <div class="mui-input-row mui-radio">
- <label for='tab-4'>圣遗物</label>
- <input id='tab-4' type='radio' name='tabgroupB'>
- </div>
- <div class="mui-input-row mui-radio">
- <label for='tab-5'>道具</label>
- <input id='tab-5' type='radio' name='tabgroupB'>
- </div>
- <div class="mui-input-row mui-radio">
- <label for='tab-6'>怪物</label>
- <input id='tab-6' type='radio' name='tabgroupB'>
- </div>
- <div class="mui-input-row mui-radio">
- <label for='tab-7'>场景</label>
- <input id='tab-7' type='radio' name='tabgroupB'>
- </div>
- <div class="mui-input-row mui-radio">
- <label for='tab-8'>任务</label>
- <input id='tab-8' type='radio' name='tabgroupB'>
- </div>
- </form>
- </div>
- </div>
- </div>
- <div id="panel" class="mui-card" style="margin-bottom: 35px;">
- </div>
- </div>
- <script>
- mui.init();
- function getQueryVariable(variable) {
- const query = window.location.search.substring(1);
- const vars = query.split("&");
- for (let i = 0; i < vars.length; i++) {
- const pair = vars[i].split("=");
- if (pair[0] === variable) {
- return pair[1];
- }
- }
- return false;
- }
- let ServerAddress = getQueryVariable("server");
- let ServerKey = getQueryVariable("key");
- if (ServerAddress !== false) {
- //URL解码
- ServerAddress = decodeURIComponent(ServerAddress);
- console.log(ServerAddress);
- }
- if (ServerAddress === false || ServerKey === false) {
- mui.prompt("请输入服务器连接地址", "服务器连接地址", "提示", ["连接"], function (e) {
- const server_address = e.value;
- if (server_address.indexOf("ws://") < 0 && server_address.indexOf("wss://") < 0) {
- mui.alert("服务器地址不正确", "连接失败", "刷新", function () {
- location.reload();
- });
- } else {
- ServerAddress = server_address;
- }
- mui.prompt("请输入连接码", "连接码", "提示", ["连接"], function (e) {
- const server_key = e.value;
- if (server_key.length !== 8) {
- mui.alert("连接码不正确", "连接失败", "刷新", function () {
- location.reload();
- });
- } else {
- ServerKey = server_key;
- ContentServer();
- }
- });
- });
- } else {
- ContentServer();
- }
- var ws;
- function updatePlayerList() {
- sendCommand("0", "Player");
- }
- function updateTransferList() {
- sendCommand("0", "TPMList");
- }
- function delAllTransfer() {
- //询问是否删除
- mui.confirm("确定删除所有传送点?", "删除传送点", ["确定", "取消"], function (e) {
- if (e.index === 0) {
- sendCommand("tpm delall yes");
- updateTransferList();
- }
- });
- }
- function addTransfer() {
- mui.prompt("请输入传送点名称", "添加传送点", "提示", ["取消", "确定"], function (e) {
- if (e.index === 1) {
- const name = e.value;
- if (name.length === 0) {
- mui.alert("传送点名称不能为空", "添加失败", "确定", function () {
- });
- } else {
- sendCommand("tpm add " + name);
- updateTransferList();
- }
- }
- });
- }
- //心跳检测防止与服务器断开连接
- var heartCheck = {
- timeout: 10000, //10秒发一次心跳
- timeoutObj: null,
- serverTimeoutObj: null,
- reset: function () {
- clearTimeout(this.timeoutObj);
- clearTimeout(this.serverTimeoutObj);
- return this;
- },
- start: function () {
- this.timeoutObj = setTimeout(function () {
- updatePlayerList();
- updateTransferList();
- }, this.timeout)
- }
- }
- function deal_onmessage(event) {
- heartCheck.reset().start();
- const server_msg = JSON.parse(event.data);
- switch (server_msg['eventName']) {
- case 'error':
- mui.alert(server_msg['data'], "错误", "确定", function () {
- });
- break;
- case "auth":
- if (server_msg['data'] !== "连接成功") {
- mui.alert(server_msg['data'], "连接失败", "刷新", function () {
- location.reload();
- });
- }
- break;
- case "success":
- mui.toast(server_msg['data']);
- break;
- case 'TPMList':
- var tpm_list = server_msg['data'];
- var tpm_list_html = "";
- for (let i = 0; i < tpm_list.length; i++) {
- var tpm_list_data = tpm_list[i];
- tpm_list_html += "<li class=\"mui-table-view-cell\">\n" +
- " <div class=\"mui-slider-cell\">\n" +
- " <div class=\"mui-slider-cell-right\">\n" +
- " <p class=\"mui-ellipsis\">传送点名称:" + tpm_list_data['Name'] + "</p>\n" +
- " <p class=\"mui-ellipsis\">坐标:" + tpm_list_data['pos'] + "</p>\n" +
- " <p class=\"mui-ellipsis\">场景:" + tpm_list_data['SceneId'] + "</p>\n" +
- " <p class=\"mui-ellipsis\">UID:" + tpm_list_data['uid'] + "</p>\n" +
- " <button type=\"button\" data-loading-text=\"请稍后\" class=\"mui-btn \" onclick=\"sendCommand('tpm go " + tpm_list_data['Name'] + "')\">传送</button>" +
- " <button type=\"button\" data-loading-text=\"请稍后\" class=\"mui-btn \" onclick=\"sendCommand('tpm del " + tpm_list_data['Name'] + "');updateTransferList();\">删除</button>" +
- " </div>\n" +
- " </div>\n" +
- " </li>";
- }
- document.getElementById("id-Transfer-list").innerHTML = tpm_list_html;
- break;
- case 'PlayerList':
- var player_list = server_msg['data'];
- //遍历玩家列表
- var player_list_html = "";
- for (let i = 0; i < player_list.length; i++) {
- var player_data = player_list[i];
- var tp_str = player_data['pos'];
- tp_str = tp_str.replace("(", "");
- tp_str = tp_str.replace(")", "");
- tp_str = tp_str.replace(",", "");
- tp_str = tp_str.replace(",", "");
- tp_str = "tp " + tp_str + " " + player_data['SceneId'];
- player_list_html += "<li class=\"mui-table-view-cell\">\n" +
- " <div class=\"mui-slider-cell\">\n" +
- " <div class=\"mui-slider-cell-right\">\n" +
- " <p class=\"mui-ellipsis\">UID:" + player_data['uid'] + "</p>\n" +
- " <p class=\"mui-ellipsis\">昵称:" + player_data['nickname'] + "</p>\n" +
- " <p class=\"mui-ellipsis\">签名:" + player_data['signature'] + "</p>\n" +
- " <p class=\"mui-ellipsis\">等级:" + player_data['Level'] + "级</p>\n" +
- " <p class=\"mui-ellipsis\">世界等级:" + player_data['worldLevel'] + "级</p>\n" +
- " <p class=\"mui-ellipsis\">等级:" + player_data['Level'] + "级</p>\n" +
- " <p class=\"mui-ellipsis\">坐标:" + player_data['pos'] + "</p>\n" +
- " <p class=\"mui-ellipsis\">场景:" + player_data['SceneId'] + "</p>\n" +
- " <button type=\"button\" data-loading-text=\"请稍后\" class=\"mui-btn \" onclick=\"sendCommand('" + tp_str + "')\">传送</button>" +
- " </div>\n" +
- " </div>\n" +
- " </li>";
- }
- document.getElementById("id-player-list").innerHTML = player_list_html;
- break;
- default:
- break;
- }
- }
- function ContentServer() {
- //判断server_address是否是一个有效的websocket地址
- try {
- ws = new WebSocket(ServerAddress + "?key=" + ServerKey)
- ws.onopen = function () {
- new QRCode(document.getElementById("qrcode"), {
- text: "https://liujiaqi7998.github.io/GrasscuttersWebDashboard/webtools.html?server=" + ServerAddress + "&key=" + ServerKey,
- width: 180,
- height: 180,
- //居中
- colorDark : "#000000",
- colorLight : "#ffffff",
- correctLevel : QRCode.CorrectLevel.H
- });
- console.log("连接成功");
- heartCheck.reset().start();
- updatePlayerList();
- updateTransferList();
- }
- ws.onclose = () => {
- mui.alert("连接已断开", "提示", "确定", function () {
- });
- };
- ws.onmessage = deal_onmessage;
- } catch (e) {
- mui.alert(e.message, "连接失败", "刷新", function () {
- location.reload();
- });
- }
- }
- function sendCommand(cmd, method = "CMD", background = false, persistent = "auto") {
- if (ws.readyState === WebSocket.OPEN) {
- try {
- console.log("执行命令:" + cmd);
- const send_msg = {
- "type": method,
- "data": cmd
- };
- const send_msg_str = JSON.stringify(send_msg);
- ws.send(send_msg_str);
- } catch (e) {
- console.log(e);
- mui.toast("发送命令失败:" + e.message);
- }
- } else {
- mui.toast("发送命令失败:服务器连接已断开");
- }
- }
- </script>
- </body>
- </html>
|