From 4e5c607949cd8b808fd3208d78994f934969eed9 Mon Sep 17 00:00:00 2001 From: Sirius0v0 <1694605269@qq.com> Date: Mon, 13 Sep 2021 14:43:37 +0800 Subject: [PATCH 1/4] add mcping --- config-template/permission-template.json | 12 + index.js | 4 + package-lock.json | 349 ++++++++++++++++++++++- package.json | 3 +- plugins/mcbot/mcData.js | 69 +++++ plugins/mcbot/mcHandle.js | 137 +++++++++ plugins/mcbot/plugin-mcbot.js | 45 +++ 7 files changed, 617 insertions(+), 2 deletions(-) create mode 100644 plugins/mcbot/mcData.js create mode 100644 plugins/mcbot/mcHandle.js create mode 100644 plugins/mcbot/plugin-mcbot.js diff --git a/config-template/permission-template.json b/config-template/permission-template.json index ceec793..97eee0f 100644 --- a/config-template/permission-template.json +++ b/config-template/permission-template.json @@ -172,6 +172,18 @@ "admin", "owner" ] + }, + "_mc": { + "activation": true, + "help": { + "desc": "mcping并查看在线人数", + "cmd": "-mc" + }, + "isadmin": [ + "member", + "admin", + "owner" + ] } } } \ No newline at end of file diff --git a/index.js b/index.js index c9e4464..c6c5ea1 100644 --- a/index.js +++ b/index.js @@ -40,6 +40,7 @@ const { ticTactics } = require("./plugins/tic-tactics/plugin-tic-tactics"); const { baiduForU } = require("./plugins/plugin-baidu-for-u"); // 为你百度 const { send } = require("./plugins/plugin-send"); // 反馈 const { biliLive, getEveryLiveStatus } = require("./plugins/bilibili/plugin-bili-live"); // bili直播间 +const { ping } = require("./plugins/mcbot/plugin-mcbot"); // mcbot // 通知类插件 const { increase } = require("./plugins/plugin-increase"); // 入群欢迎 const { decrease } = require("./plugins/plugin-decrease"); // 退群 @@ -109,6 +110,9 @@ bot.on("message.group.normal", function (e) { case "-彩虹屁": // 彩虹屁 chp(this, e, args); break; + case "-mc": // mcbot + ping(this, e, args); + break; default: // 触发自定义回复 customReply(this, e, cmd); break; diff --git a/package-lock.json b/package-lock.json index b06e341..5a80b25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,38 @@ { "name": "lingcat-bot", - "version": "1.0.0", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@azure/msal-common": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-5.0.0.tgz", + "integrity": "sha512-b3QXfW0BlGZs3mQ59rkVGcArzeMGd1RjHxyRez5bCB1F/F3jRmn2nY9jGamrILPBFz7weGpJiouW1VmDmAuk7Q==", + "requires": { + "debug": "^4.1.1" + } + }, + "@azure/msal-node": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.3.1.tgz", + "integrity": "sha512-c3bSdXUBpjUehx7mdI5iY+mwMF1mTz1qrVppH5LTD3SfbousRaFN9F2phAeaejVnCzbKzFPl4TTHxOJbkBVXHA==", + "requires": { + "@azure/msal-common": "^5.0.0", + "axios": "^0.21.1", + "jsonwebtoken": "^8.5.1", + "uuid": "^8.3.0" + }, + "dependencies": { + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "requires": { + "follow-redirects": "^1.14.0" + } + } + } + }, "@babel/runtime": { "version": "7.15.3", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz", @@ -359,11 +388,56 @@ "@types/webidl-conversions": "*" } }, + "@xboxreplay/errors": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@xboxreplay/errors/-/errors-0.1.0.tgz", + "integrity": "sha512-Tgz1d/OIPDWPeyOvuL5+aai5VCcqObhPnlI3skQuf80GVF3k1I0lPCnGC+8Cm5PV9aLBT5m8qPcJoIUQ2U4y9g==" + }, + "@xboxreplay/xboxlive-auth": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@xboxreplay/xboxlive-auth/-/xboxlive-auth-3.3.3.tgz", + "integrity": "sha512-j0AU8pW10LM8O68CTZ5QHnvOjSsnPICy0oQcP7zyM7eWkDQ/InkiQiirQKsPn1XRYDl4ccNu0WM582s3UKwcBg==", + "requires": { + "@xboxreplay/errors": "^0.1.0", + "axios": "^0.21.1" + }, + "dependencies": { + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "requires": { + "follow-redirects": "^1.14.0" + } + } + } + }, + "aes-js": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", + "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "any-base": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -401,6 +475,11 @@ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, "cheerio": { "version": "1.0.0-rc.10", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", @@ -510,6 +589,19 @@ "domhandler": "^4.2.0" } }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "endian-toggle": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/endian-toggle/-/endian-toggle-0.0.0.tgz", + "integrity": "sha1-5cx1eLEDLW7gHq/Nc3ZdsNtNwKY=" + }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -525,6 +617,16 @@ "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=" }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, "file-type": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", @@ -535,6 +637,11 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" }, + "follow-redirects": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.3.tgz", + "integrity": "sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw==" + }, "fraction.js": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.1.tgz", @@ -602,6 +709,11 @@ "resolved": "https://registry.npmjs.org/image-q/-/image-q-1.1.1.tgz", "integrity": "sha1-/IQJlmRGC5DKhi2TALa/u7+/gFY=" }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, "is-function": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", @@ -629,6 +741,11 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.2.tgz", "integrity": "sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw==" }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -637,11 +754,47 @@ "graceful-fs": "^4.1.6" } }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + } + }, "jsqr": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jsqr/-/jsqr-1.4.0.tgz", "integrity": "sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A==" }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "load-bmfont": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz", @@ -662,11 +815,56 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, "log4js": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz", @@ -684,6 +882,11 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, + "macaddress": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.5.2.tgz", + "integrity": "sha512-cYYBbT3b84hTEHssWE6OmsuqF/NiLXE2RGK9Sc9SwwE9kMoKrbaUAJtKs6ucd0FFgZjXE1Wm3hoGEEYas0N6EA==" + }, "mathjs": { "version": "9.4.4", "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-9.4.4.tgz", @@ -719,6 +922,47 @@ "dom-walk": "^0.1.0" } }, + "minecraft-data": { + "version": "2.93.0", + "resolved": "https://registry.npmjs.org/minecraft-data/-/minecraft-data-2.93.0.tgz", + "integrity": "sha512-Ta3AH5x3FHhN9gxofC2CCG8McDEN9xuPsjkWsQrWY2fmHRYY+2bJY67sMQfpygTHOtAJ2tPz4z/Ay01j/BQDgw==" + }, + "minecraft-folder-path": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minecraft-folder-path/-/minecraft-folder-path-1.2.0.tgz", + "integrity": "sha512-qaUSbKWoOsH9brn0JQuBhxNAzTDMwrOXorwuRxdJKKKDYvZhtml+6GVCUrY5HRiEsieBEjCUnhVpDuQiKsiFaw==" + }, + "minecraft-protocol": { + "version": "1.26.5", + "resolved": "https://registry.npmjs.org/minecraft-protocol/-/minecraft-protocol-1.26.5.tgz", + "integrity": "sha512-PKYUeyG+mb4MkwWbX4XrQ5SG5B4PDE6XF3Fm+z1iRwGck23DFVV3hxRHkUqBUxe0TxKrOXKGzhvT+vn541QHOw==", + "requires": { + "@azure/msal-node": "^1.0.0-beta.3", + "@xboxreplay/xboxlive-auth": "^3.3.3", + "aes-js": "^3.1.2", + "buffer-equal": "^1.0.0", + "debug": "^4.1.0", + "endian-toggle": "^0.0.0", + "lodash.get": "^4.1.2", + "lodash.merge": "^4.3.0", + "minecraft-data": "^2.85.1", + "minecraft-folder-path": "^1.1.0", + "node-fetch": "^2.6.1", + "node-rsa": "^0.4.2", + "prismarine-nbt": "^1.3.0", + "protodef": "^1.8.0", + "readable-stream": "^3.0.6", + "uuid-1345": "^1.0.1", + "yggdrasil": "^1.4.0" + }, + "dependencies": { + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=" + } + } + }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", @@ -777,6 +1021,19 @@ } } }, + "node-fetch": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.2.tgz", + "integrity": "sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==" + }, + "node-rsa": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-0.4.2.tgz", + "integrity": "sha1-1jkXKewWqDDtWjgEKzFX0tXXJTA=", + "requires": { + "asn1": "0.2.3" + } + }, "nth-check": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", @@ -870,6 +1127,14 @@ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==" }, + "prismarine-nbt": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/prismarine-nbt/-/prismarine-nbt-1.6.0.tgz", + "integrity": "sha512-h0ECvIjjwjMOtsmHxHc8hNY7kzktnKqKXmOHF0AkmH7OjkcHNAFsWRiZNvfc76rOhNonRutHvTVAlh/eLtK0oA==", + "requires": { + "protodef": "^1.9.0" + } + }, "probe-image-size": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.2.1.tgz", @@ -885,6 +1150,25 @@ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, + "protodef": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/protodef/-/protodef-1.14.0.tgz", + "integrity": "sha512-rL1WRlBC8LbAgBTa401eHMqnkX6zy1pHgS4kTSJVJ8rwP/AgVuWijGE3S3XHRkRjB/+4U1jMTqRdmtGdIqVOKQ==", + "requires": { + "lodash.get": "^4.4.2", + "lodash.reduce": "^4.6.0", + "protodef-validator": "^1.3.0", + "readable-stream": "^3.0.3" + } + }, + "protodef-validator": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/protodef-validator/-/protodef-validator-1.3.1.tgz", + "integrity": "sha512-lZ5FWKZYR9xOjpMw1+EfZRfCjzNRQWPq+Dk+jki47Sikl2EeWEPnTfnJERwnU/EwFq6us+0zqHHzSsmLeYX+Lg==", + "requires": { + "ajv": "^6.5.4" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -895,6 +1179,16 @@ "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==" }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "regenerator-runtime": { "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", @@ -905,6 +1199,11 @@ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -934,6 +1233,11 @@ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -983,6 +1287,14 @@ } } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "timm": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", @@ -1021,6 +1333,14 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, "utif": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", @@ -1029,6 +1349,24 @@ "pako": "^1.0.5" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "uuid-1345": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uuid-1345/-/uuid-1345-1.0.2.tgz", + "integrity": "sha512-bA5zYZui+3nwAc0s3VdGQGBfbVsJLVX7Np7ch2aqcEWFi5lsAEcmO3+lx3djM1npgpZI8KY2FITZ2uYTnYUYyw==", + "requires": { + "macaddress": "^0.5.1" + } + }, "webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -1078,6 +1416,15 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "yggdrasil": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/yggdrasil/-/yggdrasil-1.6.1.tgz", + "integrity": "sha512-6rUJ0A7YNVNd1K+8EvmVUc+l8CbhW7VKnN747BrC+YCukZj9C5rNsGxIZGf4MwxMHFDy/YNY++Gqf0VUxKy2ww==", + "requires": { + "node-fetch": "^2.6.1", + "uuid": "^8.2.0" + } } } } diff --git a/package.json b/package.json index d4c627a..7da3577 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "account": 123456789, "botNickname": "灵喵", "owner": 123456789, - "version": "2.0.0", + "version": "2.1.0", "description": "", "main": "index.js", "scripts": { @@ -16,6 +16,7 @@ "cheerio": "^1.0.0-rc.10", "jimp": "^0.16.1", "mathjs": "^9.4.4", + "minecraft-protocol": "^1.26.5", "mongodb": "^4.1.0", "oicq": "^1.19.3", "seed-random": "^2.2.0" diff --git a/plugins/mcbot/mcData.js b/plugins/mcbot/mcData.js new file mode 100644 index 0000000..bc54cba --- /dev/null +++ b/plugins/mcbot/mcData.js @@ -0,0 +1,69 @@ +const path = require("path"); +const mcServerListDir = path.join(__dirname, "../../config-template/config"); +const { _readFileSync } = require("../../lib/file"); +const fs = require("fs"); + +class Data { + + constructor() { + this._server_list = {}; + this.load() + } + + load = () => { + try { + this._server_list = _readFileSync(mcServerListDir, "mcServerList"); + } catch (error) { + console.log(error.message); + } + } + + dump = () => { + _readFileSync(mcServerListDir, "mcServerList"); // 没有则创建配置文件 + fs.writeFileSync(mcServerListDir + "/mcServerList.json", JSON.stringify(this._server_list, null, '\t')); + } + + getServerList = (group_id = null) => { + let serverList = this._server_list; + const gid = String(group_id); + let result = []; + if (group_id) { + if (typeof serverList?.[gid] === "undefined") serverList[gid] = []; + result = serverList[gid]; + } else { + result = serverList; + } + return result; + } + + addServer = (server, group_id) => { + const gid = String(group_id); + let serverList = this.getServerList(group_id); + if (getFieldList(serverList, "ip").indexOf(server["ip"]) === -1) serverList.push(server); + this._server_list[gid] = serverList; + this.dump(); + } + + removeServer = (uname, group_id) => { + const gid = String(group_id); + let serverList = this.getServerList(group_id).filter(server => server?.["uname"] !== uname); + if (serverList) { + this._server_list[gid] = serverList; + } else { + delete this._server_list[gid]; + } + + this.dump(); + } +} + +exports.Data = Data; + +// 获取[{},{},{}...]中对象某一属性的值 +function getFieldList(list, field) { + let fieldList = []; + list.forEach(elem => { + fieldList.push(elem?.[field]); + }); + return fieldList; +} \ No newline at end of file diff --git a/plugins/mcbot/mcHandle.js b/plugins/mcbot/mcHandle.js new file mode 100644 index 0000000..dcf77ac --- /dev/null +++ b/plugins/mcbot/mcHandle.js @@ -0,0 +1,137 @@ +const { Data } = require("./mcData"); +const { segment } = require("oicq"); +const mc = require('minecraft-protocol'); + +// 获取服务器信息 +const getServerInfo = async (host, port = 25565) => { + try { + return await mc.ping({ host: host, port: port }); + } catch (error) { + return "出错啦!"; + } +} +exports.getServerInfo = getServerInfo; + +// 获取服务器玩家列表信息 +const getPlayerInfo = async (host, port = 25565) => { + let serverInfo = await getServerInfo(host, port); + let playerInfo = serverInfo?.players; + let playerList = serverInfo?.players?.sample; + let players = []; + if (typeof playerList === "undefined" || playerList?.length === 0) players = "暂无信息"; + playerList.forEach(player => { + players.push(player?.name); + }); + playerInfo["sample"] = players; + return playerInfo; +} +exports.getPlayerInfo = getPlayerInfo; + +// 获取服务器图标 +const getServerFav = async (host, port = 25565) => { + let serverInfo = await getServerInfo(host, port); + return serverInfo?.favicon; +} +exports.getServerFav = getServerFav; + +// 获取服务器状态 +const getServerPing = async (group_id, host, port = 25565) => { + if (typeof host === "undefined") { + let serverList = new Data().getServerList(group_id); + let ip = serverList[0]?.ip; + if (typeof ip === "undefined") return; + [host, port] = ip.split(":"); + if (typeof port === "undefined") port = 25565; + } else { + let serverList = new Data().getServerList(group_id).filter(server => server?.["uname"] == host); + if (serverList.length !== 0) { + let ip = serverList[0]?.["ip"]; + [host, port] = ip.split(":"); + if (typeof port === "undefined") port = 25565; + } else { + [host, port] = host.split(":"); + if (typeof port === "undefined") port = 25565; + } + } + + let serverInfo = await getServerInfo(host, port); + if (typeof serverInfo === "string") return serverInfo; + let serverAddress = `${host}:${port}`; + let ping = serverInfo?.latency; + let fav = serverInfo?.favicon; + let msg; + if (typeof fav === "undefined") { + msg = [ + segment.text(`服务器地址: ${serverAddress}\n`), + segment.text(`Ping: ${ping}ms`) + ]; + } else { + fav = fav.split(",").slice(1).join(","); + msg = [ + segment.image(Buffer.from(fav, "base64")), + segment.text(`服务器地址: ${serverAddress}\n`), + segment.text(`Ping: ${ping}ms`) + ]; + } + return msg; +} +exports.getServerPing = getServerPing; + +// 保存服务器信息 +const addServer = async (group_id, uname, host, port = 25565) => { + [host, port] = host.split(":"); + if (typeof port === "undefined") port = 25565; + let serverInfo = await getServerInfo(host, port); + if (typeof serverInfo === "string") return "服务器连接出错~"; + let address = `${host}:${port}`; + new Data().addServer({ + "uname": uname, + "ip": address, + }, group_id); + return `关注${uname}(${address})服务器成功!`; +} +exports.addServer = addServer; + +// 删除服务器信息 +const removeServer = async (group_id, uname) => { + let serverList = new Data().getServerList(group_id) + .filter(server => server?.["uname"] == uname.trim()); + if (serverList.length === 0) return "未查到该服务器"; + new Data().removeServer(uname, group_id); + return "已删除该服务器!"; +} +exports.removeServer = removeServer; + +// 查看服务器列表 +const listServer = async (group_id) => { + let serverList = new Data().getServerList(group_id); + let result; + let serverTable = []; + serverList.forEach(element => { + serverTable.push(`[o] ${element["uname"]} (${element["ip"]})`); + }); + if (serverList.length !== 0) { + result = `本群关注服务器列表如下:\n` + `${serverTable.join("\n")}`; + } else { + result = `本群关注服务器列表为空!`; + } + return result; +} +exports.listServer = listServer; + +// 返回服务器玩家列表信息 +const getPlayersList = async (group_id) => { + let serverList = new Data().getServerList(group_id); + let ip = serverList[0]?.ip; + let uname = serverList[0]?.uname; + if (typeof ip === "undefined") return; + let [host, port] = ip.split(":"); + let playersList = await getPlayerInfo(host, port); + let info = `${typeof playersList?.sample === "string" ? playersList?.sample : playersList?.sample.join(", ")}`; + let msg = [ + segment.text(`${uname}服务器在线玩家人数:${playersList.online}/${playersList.max}\n`), + segment.text(info) + ]; + return msg; +} +exports.getPlayersList = getPlayersList; \ No newline at end of file diff --git a/plugins/mcbot/plugin-mcbot.js b/plugins/mcbot/plugin-mcbot.js new file mode 100644 index 0000000..20cd0eb --- /dev/null +++ b/plugins/mcbot/plugin-mcbot.js @@ -0,0 +1,45 @@ +"use strict" +const { getPermission } = require("../../lib/permission"); +const { listServer, getPlayersList, getServerPing, addServer, removeServer } = require("./mcHandle"); +const help = ` +<-mc list>: 查看本群关注的服务器 +<-mc add name ip>: 添加服务器 +<-mc remove name>: 移除服务器 +<-mc ping>: ping一下默认服务器 +<-mc ping ip/name>: ping一下指定服务器 +<-mc online>: 查看默认服务器在线玩家列表 +`.trim(); + +async function ping(_bot, data, args = null) { + if (!await getPermission(data, "mc")) return; + if (args?.length === 1 && ["help", '帮助'].indexOf(args?.[0]) !== -1) { + data.reply(help); + return; + } else if (args?.length === 0) { + data.reply(help); + return; + } else if (args?.length === 1 && args?.[0] === "list") { + let msg = await listServer(data.group_id); + data.reply(msg); + return; + } else if (args?.length === 1 && args?.[0] === "online") { + let msg = await getPlayersList(data.group_id); + data.reply(msg); + return; + } else if (args?.length >= 1 && args?.[0] === "ping") { + let msg = await getServerPing(data.group_id, args[1]); + data.reply(msg); + return; + } else if (args?.length === 3 && args?.[0] === "add") { + let msg = await addServer(data.group_id, args[1], args[2]); + data.reply(msg); + return; + } else if (args?.length === 2 && args?.[0] === "remove") { + let msg = await removeServer(data.group_id, args[1]); + data.reply(msg); + return; + } else { + return; + } +} +exports.ping = ping; \ No newline at end of file From b8e0a2d2cf4961d797560a8bf351520d1faf1809 Mon Sep 17 00:00:00 2001 From: Sirius0v0 <1694605269@qq.com> Date: Tue, 14 Sep 2021 19:30:47 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A5=BD=E5=A5=BD?= =?UTF-8?q?=E8=AF=B4=E8=AF=9D=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/plugin-yyds.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 plugins/plugin-yyds.js diff --git a/plugins/plugin-yyds.js b/plugins/plugin-yyds.js new file mode 100644 index 0000000..a5b3c08 --- /dev/null +++ b/plugins/plugin-yyds.js @@ -0,0 +1,37 @@ +"use strict" +const { getPermission } = require("../lib/permission"); +const axios = require("axios"); + +async function noAbbreviated(_bot, data, args = null) { + if (!await getPermission(data, "noAbbreviated")) return; + let texts = data.message.filter(msg => msg.type === 'text'); + let textList = []; + const reg = /[a-zA-Z]+/ig; + texts.forEach(text => { + let temp = Array(text?.data?.text.match(reg)); + if (temp[0] !== null) { + temp[0].forEach(e => { + textList.push(e); + }); + } + }); + if (textList.length === 0) return; + let fullText = await getFullText(textList.join(" ")); + fullText = fullText.filter(e => typeof e?.trans !== "undefined"); + let msg = []; + fullText.forEach(tran => { + msg.push(tran?.trans[0]); + }) + data.reply(msg.join("\n")); + +} +exports.noAbbreviated = noAbbreviated; + +const getFullText = async (text) => { + try { + let res = await axios.post('https://lab.magiconch.com/api/nbnhhsh/guess', { text: text }); + return res?.data; + } catch (error) { + console.error(error) + } +} \ No newline at end of file From c4e96df27c70116c49ae5fcf746a26164c2be3c8 Mon Sep 17 00:00:00 2001 From: Sirius0v0 <1694605269@qq.com> Date: Tue, 14 Sep 2021 19:31:01 +0800 Subject: [PATCH 3/4] fix bugs --- plugins/mcbot/mcHandle.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/mcbot/mcHandle.js b/plugins/mcbot/mcHandle.js index dcf77ac..ecd4c7a 100644 --- a/plugins/mcbot/mcHandle.js +++ b/plugins/mcbot/mcHandle.js @@ -18,8 +18,9 @@ const getPlayerInfo = async (host, port = 25565) => { let playerInfo = serverInfo?.players; let playerList = serverInfo?.players?.sample; let players = []; - if (typeof playerList === "undefined" || playerList?.length === 0) players = "暂无信息"; - playerList.forEach(player => { + if (playerList?.length === 0) players = "暂无信息"; + else if (typeof playerList === "undefined") players = "该服务器空荡荡~"; + else playerList.forEach(player => { players.push(player?.name); }); playerInfo["sample"] = players; From bfc1cb2f97022c0f18e158db1d3486b1c9e4e8d1 Mon Sep 17 00:00:00 2001 From: Sirius0v0 <1694605269@qq.com> Date: Tue, 14 Sep 2021 19:31:17 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=9A=8F=E6=9C=BA?= =?UTF-8?q?=E5=A4=8D=E8=AF=BB=E5=B7=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config-template/permission-template.json | 18 ++++++++++++ index.js | 8 +++-- package-lock.json | 10 ++++++- package.json | 2 +- plugins/plugin-repeater.js | 37 ++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 plugins/plugin-repeater.js diff --git a/config-template/permission-template.json b/config-template/permission-template.json index 97eee0f..bb71ac5 100644 --- a/config-template/permission-template.json +++ b/config-template/permission-template.json @@ -184,6 +184,24 @@ "admin", "owner" ] + }, + "_repeater": { + "activation": true, + "help": null, + "isadmin": [ + "member", + "admin", + "owner" + ] + }, + "_noAbbreviated": { + "activation": true, + "help": null, + "isadmin": [ + "member", + "admin", + "owner" + ] } } } \ No newline at end of file diff --git a/index.js b/index.js index c6c5ea1..6455780 100644 --- a/index.js +++ b/index.js @@ -41,6 +41,8 @@ const { baiduForU } = require("./plugins/plugin-baidu-for-u"); // 为你百 const { send } = require("./plugins/plugin-send"); // 反馈 const { biliLive, getEveryLiveStatus } = require("./plugins/bilibili/plugin-bili-live"); // bili直播间 const { ping } = require("./plugins/mcbot/plugin-mcbot"); // mcbot +const { repeater } = require("./plugins/plugin-repeater"); // 复读 +const { noAbbreviated } = require("./plugins/plugin-yyds"); // 好好说话 // 通知类插件 const { increase } = require("./plugins/plugin-increase"); // 入群欢迎 const { decrease } = require("./plugins/plugin-decrease"); // 退群 @@ -113,8 +115,10 @@ bot.on("message.group.normal", function (e) { case "-mc": // mcbot ping(this, e, args); break; - default: // 触发自定义回复 - customReply(this, e, cmd); + default: + noAbbreviated(this, e); // 好好说话 + repeater(this, e); // 复读 + customReply(this, e, cmd); // 触发自定义回复 break; } }) diff --git a/package-lock.json b/package-lock.json index 5a80b25..ff5107b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lingcat-bot", - "version": "2.0.0", + "version": "2.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -438,6 +438,14 @@ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" }, + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "requires": { + "follow-redirects": "^1.14.0" + } + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", diff --git a/package.json b/package.json index 7da3577..d3cbc42 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "account": 123456789, "botNickname": "灵喵", "owner": 123456789, - "version": "2.1.0", + "version": "2.1.3", "description": "", "main": "index.js", "scripts": { diff --git a/plugins/plugin-repeater.js b/plugins/plugin-repeater.js new file mode 100644 index 0000000..fb6834c --- /dev/null +++ b/plugins/plugin-repeater.js @@ -0,0 +1,37 @@ +"use strict" +const { getPermission } = require("../lib/permission"); +const msgList = {}; + +async function repeater(_bot, data, args = null) { + if (!await getPermission(data, "repeater")) return; + const startRepeat = 3; // 从第三条开始复读 + const repeatProbability = 0.35; // 复读概率 + const cd = 3; // 若复读冷却条数 + const gid = String(data.group_id); + if (typeof msgList?.[gid] === "undefined") msgList[gid] = []; + if (msgList[gid].length === 25) msgList[gid] = []; // 清理消息 + msgList[gid].push(data.raw_message); + if (!isEqual(msgList[gid], startRepeat, cd, "✈")) return; + let isSendMsg = Math.random() < repeatProbability; + if (isSendMsg) { + data.reply(data.raw_message); + msgList[gid].push("✈"); // 标志已复读 + } + console.log(msgList) +} +exports.repeater = repeater; + +// 比较后n个元素是否相等 +function isEqual(array, num, cd, symbol) { + let symIndex = array.indexOf(symbol); + if (symIndex !== -1 && symIndex + (cd + 1) < array.length) array = array.slice(symIndex + cd + 1); + if (array.length < num) return false; + let equal = true; + for (let index = array.length - 1; index > array.length - num; index--) { + if (array[index] !== array[index - 1]) { + equal = false; + break; + } + } + return equal; +} \ No newline at end of file