From 362598fdc5cdcc52694228d8e01987e4a41bac36 Mon Sep 17 00:00:00 2001 From: jiansyuan Date: Thu, 6 Jul 2023 17:34:15 +0800 Subject: [PATCH 01/13] modify --- .gitignore | 8 +- NIAHttpBOT/src/NIAHttpBOT.cpp | 281 +++++++++++++++------------------- 2 files changed, 134 insertions(+), 155 deletions(-) diff --git a/.gitignore b/.gitignore index 0566ee1..8a3b399 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,10 @@ !CHANGELOG.md !LICENSE !README-EN.md -!README.md \ No newline at end of file +!README.md + +/NIAHttpBOT/* +!/NIAHttpBOT/header/ +!/NIAHttpBOT/src/ +!/NIAHttpBOT/CMakeLists.txt + diff --git a/NIAHttpBOT/src/NIAHttpBOT.cpp b/NIAHttpBOT/src/NIAHttpBOT.cpp index aa13ffd..cfba914 100644 --- a/NIAHttpBOT/src/NIAHttpBOT.cpp +++ b/NIAHttpBOT/src/NIAHttpBOT.cpp @@ -1,35 +1,37 @@ -#include +#include #include #include #include -#include "httplib.h" -#include "rapidjson/document.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/writer.h" -#include "rapidjson/prettywriter.h" + +#include +#include +#include +#include #include #include - -void GetTime() -{ - time_t timep; - struct tm* p; - - time(&timep); - p = localtime(&timep); - - printf("[%d/%d/%d %02d:%02d:%02d] ", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);//2019/2/28 14:18:31 - +#define INFO(a) GetTime(), std::cout<<"[INFO] "< writer(buffer); + writer.SetIndent(' ', 4); + fileContent.Accept(writer); + // 检测${fileName}文件是否存在,如果不存在,就创建一个新的文件,并写入内容 + std::ifstream file(fileName); + if(file){ + res.status = 200; + res.set_content("The target file already exists and cannot be regenerated.", "text/plain"); + return ; } - else { - //初始化文件名称 - std::string fileName = ""; - //读取键为fileName的内容 - if (NewFileData.HasMember("fileName")) { - //读取文件名称 - fileName = NewFileData["fileName"].GetString(); - //读取文件内容 - rapidjson::Value& fileContent = NewFileData["fileContent"]; - //将文件内容转换为字符串,便于后续写入文件 - rapidjson::StringBuffer buffer; - rapidjson::PrettyWriter writer(buffer); - writer.SetIndent(' ', 4); - fileContent.Accept(writer); - // 检测${fileName}文件是否存在,如果不存在,就创建一个新的文件,并写入内容 - std::ifstream file(fileName); - if (!file) { - file.close(); - std::ofstream out(fileName); - out << buffer.GetString(); - out.close(); - res.status = 200; - res.set_content("success", "text/plain"); - } - else { - res.status = 200; - res.set_content("The target file already exists and cannot be regenerated.", "text/plain"); - }; - file.close(); - } - else { - res.status = 200; - res.set_content("Incorrect data format, please recheck and send again.", "text/plain"); - } - - }; - - }); + file.close(); + std::ofstream out(fileName); + out << buffer.GetString(); + out.close(); + res.status = 200; + res.set_content("success", "text/plain"); + file.close(); + }); //获取json文件数据 svr.Post("/GetJsonFileData", [](const httplib::Request& req, httplib::Response& res) { - GetTime(); - std::cout << "接收到获取文件数据的请求,请求获取的文件名称为: " << req.body << std::endl; + INFO("接收到获取文件数据的请求,请求获取的文件名称为: " << req.body); //初始化文件名称 std::string fileName = req.body; //判断文件存不存在 std::ifstream file(fileName); - if (file) { - //文件打开成功,并创建文件流对象 - rapidjson::IStreamWrapper isw(file); - //创建json对象 - rapidjson::Document doc; - //从文件流中解析数据 - doc.ParseStream(isw); - //将文件内容转换为字符串,便于后续写入文件 - rapidjson::StringBuffer buffer; - rapidjson::Writer writer(buffer); - doc.Accept(writer); - std::string jsonStr = buffer.GetString(); - res.status = 200; - res.set_content(jsonStr, "text/plain"); - } - else { + if(!file) { //文件打开失败 res.status = 200; res.set_content("The target file does not exist", "text/plain"); - }; + return ; + } + //文件打开成功,并创建文件流对象 + rapidjson::IStreamWrapper isw(file); + //创建json对象 + rapidjson::Document doc; + //从文件流中解析数据 + doc.ParseStream(isw); + //将文件内容转换为字符串,便于后续写入文件 + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + doc.Accept(writer); + std::string jsonStr = buffer.GetString(); + res.status = 200; + res.set_content(jsonStr, "text/plain"); file.close(); - }); + }); //覆盖json文件内容 svr.Post("/OverwriteJsonFile", [](const httplib::Request& req, httplib::Response& res) { - GetTime(); - std::cout << "接收到覆写文件的请求,请求覆写文件的数据: " << req.body << std::endl; - //将获取的body数据转换为char* - char* json = (char*)req.body.c_str(); + INFO("接收到覆写文件的请求,请求覆写文件的数据: " << req.body); //解析字符串并创建一个json对象 rapidjson::Document NewFileData; - NewFileData.Parse(json); + NewFileData.Parse(req.body.c_str()); //判断是否解析成功 if (NewFileData.HasParseError()) { res.status = 200; res.set_content("Data parsing failed", "text/plain"); + return ; } - else { - //初始化文件名称 - std::string fileName = ""; - //读取键为fileName的内容 - if (NewFileData.HasMember("fileName")) { - //读取文件名称 - fileName = NewFileData["fileName"].GetString(); - //读取文件内容 - rapidjson::Value& fileData = NewFileData["fileData"]; - //将文件内容转换为字符串,便于后续写入文件 - rapidjson::StringBuffer buffer; - rapidjson::PrettyWriter writer(buffer); - writer.SetIndent(' ', 4); - fileData.Accept(writer); - // 检测${fileName}文件是否存在,如果不存在,就创建一个新的文件,并写入内容 - std::ifstream file(fileName); - if (file) { - std::ofstream out(fileName); - out << buffer.GetString(); - out.close(); - res.status = 200; - res.set_content("success", "text/plain"); - } - else { - res.status = 200; - res.set_content("The target file does not exist.", "text/plain"); - }; - file.close(); - } - else { - res.status = 200; - res.set_content("Incorrect data format, please recheck and send again.", "text/plain"); - } - - }; - - }); + if(!NewFileData.HasMember("fileName")){ + res.status = 200; + res.set_content("Incorrect data format, please recheck and send again.", "text/plain"); + return ; + } + //初始化文件名称 + std::string fileName = ""; + //读取键为fileName的内容 + //读取文件名称 + fileName = NewFileData["fileName"].GetString(); + //读取文件内容 + rapidjson::Value& fileData = NewFileData["fileData"]; + //将文件内容转换为字符串,便于后续写入文件 + rapidjson::StringBuffer buffer; + rapidjson::PrettyWriter writer(buffer); + writer.SetIndent(' ', 4); + fileData.Accept(writer); + // 检测${fileName}文件是否存在,如果不存在,就创建一个新的文件,并写入内容 + std::ifstream file(fileName); + if(!file) { + res.status = 200; + res.set_content("The target file does not exist.", "text/plain"); + return ; + } + std::ofstream out(fileName); + out << buffer.GetString(); + out.close(); + res.status = 200; + res.set_content("success", "text/plain"); + file.close(); + + }); svr.listen("127.0.0.1", 10086); From 8c5d14f272375a4ebe602243de5ebd77beb7a37c Mon Sep 17 00:00:00 2001 From: NIANIANKNIA Date: Sat, 8 Jul 2023 01:14:31 +0800 Subject: [PATCH 02/13] =?UTF-8?q?=E4=BC=98=E5=8C=96NIAHttpBOT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG-PRE.md | 13 +- NIA-Server-BOT/index.html | 26 -- NIA-Server-BOT/index.js | 419 ------------------------------- NIA-Server-BOT/logo.jpg | Bin 29512 -> 0 bytes NIA-Server-BOT/market.json | 300 ---------------------- NIA-Server-BOT/package-lock.json | 325 ------------------------ NIA-Server-BOT/package.json | 16 -- NIA-Server-BOT/test.js | 347 ------------------------- NIAHttpBOT/src/NIAHttpBOT.cpp | 27 +- 9 files changed, 18 insertions(+), 1455 deletions(-) delete mode 100644 NIA-Server-BOT/index.html delete mode 100644 NIA-Server-BOT/index.js delete mode 100644 NIA-Server-BOT/logo.jpg delete mode 100644 NIA-Server-BOT/market.json delete mode 100644 NIA-Server-BOT/package-lock.json delete mode 100644 NIA-Server-BOT/package.json delete mode 100644 NIA-Server-BOT/test.js diff --git a/CHANGELOG-PRE.md b/CHANGELOG-PRE.md index 8ab7682..ed4e9db 100644 --- a/CHANGELOG-PRE.md +++ b/CHANGELOG-PRE.md @@ -1,4 +1,4 @@ -# v1.3.0-pre-5 更新日志 +# v1.3.1-pre-1 更新日志 [![BDS VERSION](https://img.shields.io/badge/BDS-1.20.10.02-green?style=for-the-badge&logo=appveyor)](https://www.minecraft.net/en-us/download/server/bedrock) [![LiteLoader VERSION](https://img.shields.io/badge/LiteLoader-2.14.1-green?style=for-the-badge&logo=appveyor)](https://github.com/LiteLDev/LiteLoaderBDS/releases/) @@ -7,19 +7,12 @@ > 预发布版本提醒:这是一个预览版本,可能存在一些bug,仅供测试,请勿在正式生产环境使用本版本! -## 新增 - -全新的NIAHttpBOT!基于c++编写,相比旧方案内存占用更小,性能更好!(特别感谢[**@jiansyuan**](https://github.com/jiansyuan)在编写中给予的帮助!) ## 优化 -1.由于qq机器人暂时不稳定,在找到稳定的解决方案前暂时停止qq机器人的使用 - -2.自本版本之后,**停止对NIA-Server-BOT的更新与维护**,转而使用全新的**NIAHttpBOT**实现对原有功能的替代。 - -## 修复 +1.NIAHttpBOT部分优化 -回收商店系统部分商品无法回收的bug +2.正式移除`NIA-Server-BOT`项目及其所有文件 **配置说明:您可以前往[NIA服务器官方文档站](https://docs.mcnia.top/zh-CN/deploy.html)查看具体部署过程!** diff --git a/NIA-Server-BOT/index.html b/NIA-Server-BOT/index.html deleted file mode 100644 index d609141..0000000 --- a/NIA-Server-BOT/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - -NIA服务器监听服务器 - - - - -

 

-

 

-

欢迎使用

-

NIA服务器监听服务器

-

如果你看到这行字说明监听服务器已经在正常运行了!

-

有BUG请联系作者!

-

项目地址:https://github.com/NIANIANKNIA/NIASERVER-V4/

-

当前监听服务器版本:v0.1.0

-

-

NIA服务器版权©所有

-

 

-

 

- - - - - \ No newline at end of file diff --git a/NIA-Server-BOT/index.js b/NIA-Server-BOT/index.js deleted file mode 100644 index fc1d1a3..0000000 --- a/NIA-Server-BOT/index.js +++ /dev/null @@ -1,419 +0,0 @@ -const http = require('http'); -const fs = require('fs'); -const os = require('os-utils'); -//端口不要更换! -const port = 10086; -const { createClient } = require("icqq"); -const { fail } = require('assert'); -//const PLAYERCMDS = ["list","申请白名单","查"] -const serverInfo = {cpuUsage: 0} - -//初始化变量 -var AccountOnline = false; -var ServerStarted = false; - -//初始化配置文件格式,请勿更改!!!! -var config = {"account": 123456,"password": "","QQGroup": 123456789,"owners": [123456],"botconfig":{"platform": 6}} -var client = createClient(config.botconfig) -var account = config.account -var password = config.password -var group = client.pickGroup(config.QQGroup) - -//配置文件地址 -const cfg_path = "./config.json"; - - -const log = { - error(message) { - console.log("[NIA-Server-BOT] \x1b[31m[ERROR]\x1b[0m [" + new Date().toLocaleString('zh', { hour12: false }).replaceAll('/', '-') + "] " + message) - }, - info(message) { - console.log("[NIA-Server-BOT] \x1b[32m[INFO]\x1b[0m [" + new Date().toLocaleString('zh', { hour12: false }).replaceAll('/', '-') + "] " + message) - }, - warn(message) { - console.log("[NIA-Server-BOT] \x1b[33m[WARN]\x1b[0m [" + new Date().toLocaleString('zh', { hour12: false }).replaceAll('/', '-') + "] " + message) - } -} - -//判断配置文件是否存在 -fs.access(cfg_path, (err) => { - //不存在 - if (err) { - fs.writeFile(cfg_path, JSON.stringify(config,null,4), 'utf-8', (err) => { - if (err) { - return log.error('该文件不存在,重新创建失败!') - } - }); - log.warn("配置文件不存在,已重新创建,请修改配置文件后再运行!"); - //直接结束本次进程 - process.exit(1) - } else { - //存在,读取配置文件 - fs.readFile(cfg_path,(err,data) => { - if (err) { - return log.error("配置文件读取错误!") - } - config = JSON.parse(data.toString()) - //再次读取配置文件中的数据 - account = config.account - password = config.password - group = client.pickGroup(config.QQGroup) - log.info("配置文件数据读取成功,正在启动机器人!"); - //登录qq机器人 - client = createClient(config.botconfig) - client.on('system.login.slider', (e) => { - console.log('输入滑块地址获取的ticket后继续。\n滑块地址: ' + e.url) - process.stdin.once('data', (data) => { - client.submitSlider(data.toString().trim()) - }) - }) - client.on('system.login.qrcode', (e) => { - console.log('扫码完成后回车继续: ') - process.stdin.once('data', () => { - client.login() - }) - }) - client.on('system.login.device', (e) => { - console.log('请选择验证方式:(1:短信验证 其他:扫码验证)') - process.stdin.once('data', (data) => { - if (data.toString().trim() === '1') { - client.sendSmsCode() - console.log('请输入手机收到的短信验证码:') - process.stdin.once('data', (res) => { - client.submitSmsCode(res.toString().trim()) - }) - } else { - console.log('扫码完成后回车继续:' + e.url) - process.stdin.once('data', () => { - client.login() - }) - } - }) - }) - client.login(account,password) - //判断机器人是否登录成功 - client.on('system.online', (e) => { - AccountOnline = true - group = client.pickGroup(config.QQGroup) - group.sendMsg("机器人登陆成功!") - log.info("机器人登陆成功!") - }) - - //监听群聊消息 - client.on('message.group', (e) => { - //等适配 - if (e.group_id == config.QQGroup && e.sender.user_id != 3467371607) { - if (e.message[0].text.toString().slice(0,1) == "#") { - let message = e.message[0].text.toString().slice(1).split(" ") - switch (message[0]) { - default: - e.group.sendMsg("未知的指令,请重新检查后再次发送!") - break; - case "申请白名单": - if (message[1] == undefined) { - e.group.sendMsg("未知的XboxID,请发送形如 #申请白名单 Steve 来获取白名单!") - } else { - e.group.sendMsg("你已成功将XboxID <" + message[1] + "> 与qq <" + e.sender.user_id + "> 成功绑定!如需解绑/换绑请联系管理员!") - } - break; - case "查市场": - fs.readFile("./market.json",(err,data) => { - if (err) { - return log.error("market文件读取错误!") - } - commodities = JSON.parse(data.toString()) - let marketStr = "" - if (message[1] == undefined) { - for (let i = 0; i < commodities.length; i++) { - marketStr = "商品名称:" + commodities[i].name + " 商品单价:" + commodities[i].price + "\n" + marketStr - } - e.group.sendMsg("已成功获取玩家市场数据:\n" + marketStr) - } - }) - break; - } - // if (PLAYERCMDS.indexOf(e.message[0].text.toString().slice(1)) != -1) { - // e.group.sendMsg("开发中功能!") - // } else if (e.sender.role == "owner" || e.sender.role == "admin") { - // e.group.sendMsg("开发中功能!") - // } else { - // e.group.sendMsg("您不是管理员,无法执行相关指令!") - // } - } else { - if (e.sender.card == "") { - repData.msgboxs.push([e.sender.nickname,e.message[0].text.toString()]) - } else { - repData.msgboxs.push([e.sender.card,e.message[0].text.toString()]) - } - } - } - }) - - }) - } -}) - -var commodities = [] - -//判断有没有market文件,没有直接初始化 -fs.access("./market.json", (err) => { - //不存在 - if (err) { - //没有文件直接创建 - fs.writeFile("./market.json", "[]", 'utf-8', (err) => { - if (err) { - log.error('该文件不存在且重新创建失败!') - process.exit(1) - } - }); - } else { - fs.readFile("./market.json",(err,data) => { - if (err) { - return log.error("market文件读取错误!") - } - commodities = JSON.parse(data.toString()) - }) - log.info("market.json已成功读取!") - } -}) - - -process.on('uncaughtException', function (err) { - //打印出错误 - console.log(err); - //打印出错误的调用栈方便调试 - console.log(err.stack); -}); - - -//process.on('unhandledRejection', error => {}); - -//初始化一些变量便于下方的调用 -var msgboxs= {} -var repData = {} -repData.msgboxs = [] - -//定义监听服务器 -var server = http.createServer() - -//如果页面生成失败则调用该函数 -function hadErrer(err,res){ - console.log(err) - res.end('server err') -} - -server.on("request", (req, res) => { - let arr = []; - switch (req.url) { - //监听直接访问 - case "/": - fs.readFile('./index.html', (err, data) => { - if (err) { - return hadErrer(err,res) - } - res.statusCode = 200; - res.setHeader('Content-Type', 'text/html'); - res.end(data.toString()); - }) - break; - //与mc服务器进行通讯,接受其请求 - case "/Check": - if (!ServerStarted) { - ServerStarted = true; - log.info("已经与MC服务器成功连接!") - } - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain;charset=utf-8'); - res.end(JSON.stringify(repData)); - repData = {} - repData.msgboxs = [] - break; - case '/MarketInitialize': - fs.readFile("./market.json",(err,data) => { - if (err) { - return log.error("market文件读取错误!") - } - commodities = JSON.parse(data.toString()) - //开始读取文件 - res.statusCode = 200; - ServerStarted = true; - res.setHeader('Content-Type', 'text/plain;charset=utf-8'); - res.end(JSON.stringify(commodities)); - group.sendMsg("交易市场数据获得成功") - log.info("market.json已成功读取!") - }) - break; - //监听服务器开服 - case '/ServerStarted': - log.info("已经与MC服务器成功连接!") - res.statusCode = 200; - ServerStarted = true; - res.setHeader('Content-Type', 'text/plain;charset=utf-8'); - res.end("Server Started"); - group.sendMsg("服务器已启动!") - break; - //监听玩家说话并转发 - case '/PlayerChat': - req.on("data", (data) => { - arr.push(data) - }) - req.on("end", () => { - let msgData = JSON.parse(Buffer.concat(arr).toString()) - if (AccountOnline) { - group.sendMsg("<" + msgData.name + "> " + msgData.message) - } - }) - res.statusCode = 200; - break; - //监听玩家加入服务器 - case '/PlayerJoin': - req.on("data", (data) => { - arr.push(data) - }) - req.on("end", () => { - let playerjoinData = Buffer.concat(arr).toString() - if (AccountOnline) { - group.sendMsg(playerjoinData + " 加入了服务器!") - } - }) - break; - //监听玩家退出服务器 - case '/PlayerLeave': - req.on("data", (data) => { - arr.push(data) - }) - req.on("end", () => { - let playerleaveData = Buffer.concat(arr).toString() - if (AccountOnline) { - group.sendMsg(playerleaveData + " 离开了服务器!") - } - }) - break; - case '/Market': - //开始读取文件 - // let commodities = {} - // fs.readFileSync("./market.json",(err,data) => { - // if (err) { - // // - // return console.log("market文件读取错误!") - // } - // commodities = JSON.parse(data.toString()) - // }) - // res.statusCode = 200; - // res.setHeader('Content-Type', 'text/plain;charset=utf-8'); - // res.end(JSON.stringify(commodities)); - break; - //监听玩家市场上架物品 - case '/Shelf': - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain;charset=utf-8'); - res.end("success") - req.on("data", (data) => { - arr.push(data) - }) - req.on("end", () => { - let itemData = JSON.parse(Buffer.concat(arr).toString()) - if (AccountOnline) { - group.sendMsg(`【玩家市场上新提醒】\n玩家 ${itemData.playerName} 在市场中上架了全新的商品!\n商品名称: ${itemData.name} (${itemData.typeid}) \n商品简介: ${itemData.description} \n商品单价: ${itemData.price}\n商品剩余库存: ${itemData.amount}\n商品流水号: ${itemData.id} \n想要的玩家赶快上线购买吧!`) - //group.sendMsg(JSON.stringify(itemData,null,2)) - fs.readFile("./market.json",(err,data) => { - if (err) { - // - return console.log("market文件读取错误!") - } - marketData = JSON.parse(data.toString()) - marketData.push(itemData) - fs.writeFile("./market.json",JSON.stringify(marketData,null,4),function(err){ - if(err){ - console.error(err); - } - errInfo = {} - errInfo.info = "shelf" - repData.errData = marketData - }) - }) - // fs.access("./market.json", (err) => { - // //不存在 - // if (err) { - // //没有文件直接创建 - // fs.writeFile("./market.json", "[]", 'utf-8', (err) => { - // if (err) { - // return console.log('该文件不存在且重新创建失败!') - // process.exit(1) - // } - // }); - // //创建成功后直接读取 - // marketData = [] - // marketData.push(itemData) - // fs.writeFile("./market.json",JSON.stringify(marketData,null,4),function(err){ - // if(err){ - // res.statusCode = 201; - // return console.error(err); - // } - // console.log('新增成功'); - // res.statusCode = 200; - // }) - // } else { - // //存在,读取配置文件 - // fs.readFile("./market.json",(err,data) => { - // if (err) { - // res.statusCode = 201; - // return console.log("配置文件读取错误!") - // } - // marketData = JSON.parse(data.toString()) - // marketData.push(itemData) - // fs.writeFile("./market.json",JSON.stringify(marketData,null,4),function(err){ - // if(err){ - // console.error(err); - // } - // res.statusCode = 200; - // }) - // }) - // } - // }) - } - }) - // if (result) { - // res.statusCode = 200; - // console.log("123") - // } else { - // res.statusCode = 201; - // console.log("456") - // } - break; - } -}) - -//监听服务器开启成功提醒 -server.listen(port,'127.0.0.1', () => { - log.info("NIA服务器监听服务器已经成功在 http://127.0.0.1:" + port + " 启动!"); -}); - - -//获得系统cou占用率 -async function getCPUUsage() { - let promise = new Promise((resolve) => { - os.cpuUsage(function(v){ - resolve(v) - }); - }); - serverInfo.cpuUsage = await promise -} - -//周期运作 -setInterval(() => { - if (AccountOnline) { - //等后续获取自己的qq号 - getCPUUsage() - if (serverInfo.cpuUsage <= 0.6) { - group.setCard(3374574180,"🟢流畅 | CPU占用率:" + (serverInfo.cpuUsage*100).toFixed(2) + "%") - } else if (serverInfo.cpuUsage <= 0.8) { - group.setCard(3374574180,"🟡一般 | CPU占用率:" + (serverInfo.cpuUsage*100).toFixed(2) + "%") - } else if (serverInfo.cpuUsage >= 0.9) { - group.setCard(3374574180,"🔴卡死 | CPU占用率:" + (serverInfo.cpuUsage*100).toFixed(2) + "%") - } - } - if (!ServerStarted && AccountOnline) { - log.error("暂未连接到MC服务器!") - } -}, 10000) diff --git a/NIA-Server-BOT/logo.jpg b/NIA-Server-BOT/logo.jpg deleted file mode 100644 index c027a467ad1a9b38e6139f8af1321bd7a2681a8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29512 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 Iz`k<-3*=4SL;wH) diff --git a/NIA-Server-BOT/market.json b/NIA-Server-BOT/market.json deleted file mode 100644 index 36c280e..0000000 --- a/NIA-Server-BOT/market.json +++ /dev/null @@ -1,300 +0,0 @@ -[ - { - "state": true, - "slot": 8, - "typeid": "minecraft:gray_wool", - "amount": 64, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "灰羊毛", - "description": "咩咩咩咩咩咩咩咩", - "price": 10, - "id": "077743858", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-23 23:39:14" - }, - { - "state": true, - "slot": 29, - "typeid": "minecraft:planks", - "amount": 64, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "木板", - "description": "飒飒水水水水水水水水水水", - "price": 456, - "id": "371011238", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-6-23 14:41:51" - }, - { - "state": true, - "slot": 6, - "typeid": "minecraft:planks", - "amount": 64, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "炒掉木板", - "description": "456", - "price": 456, - "id": "591170954", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-23 23:39:14" - }, - { - "state": true, - "slot": 9, - "typeid": "minecraft:coral_block", - "amount": 36, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "?", - "description": "!!!!", - "price": 12, - "id": "880481242", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-23 23:39:14" - }, - { - "state": true, - "slot": 0, - "typeid": "minecraft:rotten_flesh", - "amount": 1, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "腐肉", - "description": "!", - "price": 10, - "id": "018208282", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-23 23:39:14" - }, - { - "state": true, - "slot": 4, - "typeid": "minecraft:golden_sword", - "amount": 1, - "keepOnDeath": false, - "maxAmount": 1, - "Hasdamage": true, - "damage": 0, - "Hasench": true, - "ench": { - "sharpness": 1 - }, - "name": "金剑", - "description": "!!!!!!!!!!!!!!!!!!!", - "price": 10, - "id": "336094512", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-23 23:44:48" - }, - { - "state": true, - "slot": 0, - "typeid": "minecraft:salmon", - "amount": 1, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "鱼", - "description": "fish", - "price": 10, - "id": "489485464", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-23 23:51:00" - }, - { - "state": true, - "slot": 1, - "typeid": "minecraft:torch", - "amount": 64, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "火柴", - "description": "?", - "price": null, - "id": "207868920", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-23 23:52:25" - }, - { - "state": true, - "slot": 0, - "typeid": "minecraft:planks", - "amount": 64, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "木板", - "description": "测试商品1", - "price": 50, - "id": "386803089", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-24 15:47:14" - }, - { - "state": true, - "slot": 0, - "typeid": "minecraft:planks", - "amount": 16, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "木板", - "description": "测试商品2", - "price": 5050, - "id": "943789566", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-24 15:49:59" - }, - { - "state": true, - "slot": 0, - "typeid": "minecraft:planks", - "amount": 16, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "jsy家的木板", - "description": "亲自采摘(", - "price": 5000, - "id": "445548991", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-30 18:02:31" - }, - { - "state": true, - "slot": 1, - "typeid": "minecraft:planks", - "amount": 64, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "木板", - "description": "114514", - "price": 10, - "id": "52f0a94", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-30 19:16:13" - }, - { - "state": true, - "slot": 23, - "typeid": "minecraft:balloon", - "amount": 64, - "keepOnDeath": false, - "maxAmount": 64, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "气球", - "description": "哈哈哈", - "price": 10, - "id": "f5c0a44", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-06-30 20:23:15" - }, - { - "state": true, - "slot": 1, - "typeid": "minecraft:wooden_sword", - "amount": 1, - "keepOnDeath": false, - "maxAmount": 1, - "Hasdamage": true, - "damage": 0, - "Hasench": true, - "ench": { - "sharpness": 0, - "fire_aspect": 32767, - "unbreaking": 32767, - "knockback": 32767 - }, - "name": "木剑", - "description": "测试", - "price": 100000000, - "id": "f950a4b", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-07-01 00:52:18" - }, - { - "state": true, - "slot": 1, - "typeid": "minecraft:sparkler", - "amount": 1, - "keepOnDeath": false, - "maxAmount": 1, - "Hasdamage": true, - "damage": 0, - "Hasench": true, - "ench": {}, - "name": "测试", - "description": "测试", - "price": 41023, - "id": "3160a73", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-07-01 00:59:10" - }, - { - "state": true, - "slot": 18, - "typeid": "minecraft:shulker_box", - "amount": 1, - "keepOnDeath": false, - "maxAmount": 1, - "Hasdamage": false, - "Hasench": true, - "ench": {}, - "name": "测试1111111", - "description": "牵引和", - "price": 456456, - "id": "1370bc4", - "playerid": "-21474836479", - "playerName": "NIANIANKNIA", - "addedTime": "2023-07-01 01:00:08" - } -] \ No newline at end of file diff --git a/NIA-Server-BOT/package-lock.json b/NIA-Server-BOT/package-lock.json deleted file mode 100644 index 8c04daa..0000000 --- a/NIA-Server-BOT/package-lock.json +++ /dev/null @@ -1,325 +0,0 @@ -{ - "name": "niaserver-net", - "version": "1.2.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "niaserver-net", - "version": "1.2.0", - "license": "ISC", - "dependencies": { - "icqq": "^0.4.7", - "os-utils": "^0.0.14" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmmirror.com/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icqq": { - "version": "0.4.7", - "resolved": "https://registry.npmmirror.com/icqq/-/icqq-0.4.7.tgz", - "integrity": "sha512-S1ayfpyJsvMYhQaqh2VJQsDABb/Rx3kPNUHM2kfVPW2omO3C1DCS42f82v2en52V6pzdbRI3xYmkLrhAW+v66w==", - "dependencies": { - "axios": "^1.1.2", - "log4js": "^6.3.0", - "long": "^4.0.0", - "pngjs": "^6.0.0", - "probe-image-size": "^7.2.2", - "triptrap": "^0.0.17" - }, - "engines": { - "node": ">= v14" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "node_modules/log4js": { - "version": "6.9.1", - "resolved": "https://registry.npmmirror.com/log4js/-/log4js-6.9.1.tgz", - "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.5" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/needle": { - "version": "2.9.1", - "resolved": "https://registry.npmmirror.com/needle/-/needle-2.9.1.tgz", - "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", - "dependencies": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "bin": { - "needle": "bin/needle" - }, - "engines": { - "node": ">= 4.4.x" - } - }, - "node_modules/needle/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/os-utils": { - "version": "0.0.14", - "resolved": "https://registry.npmmirror.com/os-utils/-/os-utils-0.0.14.tgz", - "integrity": "sha512-ajB8csaHLBvJOYsHJkp8YdO2FvlBbf/ZxaYQwXXRDyQ84UoE+uTuLXxqd0shekXMX6Qr/pt/DDyLMRAMsgfWzg==", - "engines": { - "node": "*" - } - }, - "node_modules/pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/probe-image-size": { - "version": "7.2.3", - "resolved": "https://registry.npmmirror.com/probe-image-size/-/probe-image-size-7.2.3.tgz", - "integrity": "sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==", - "dependencies": { - "lodash.merge": "^4.6.2", - "needle": "^2.5.2", - "stream-parser": "~0.3.1" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmmirror.com/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/stream-parser": { - "version": "0.3.1", - "resolved": "https://registry.npmmirror.com/stream-parser/-/stream-parser-0.3.1.tgz", - "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==", - "dependencies": { - "debug": "2" - } - }, - "node_modules/stream-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/stream-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/streamroller": { - "version": "3.1.5", - "resolved": "https://registry.npmmirror.com/streamroller/-/streamroller-3.1.5.tgz", - "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/triptrap": { - "version": "0.0.17", - "resolved": "https://registry.npmmirror.com/triptrap/-/triptrap-0.0.17.tgz", - "integrity": "sha512-hXc5npX73EeFc64PX1fyofdeyMVyXrNwLNbxAkirymK3AoTcn+xfbeYjfXOJl8iuKsciYQf1Q6VusAK1FUVcGw==" - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - } - } -} diff --git a/NIA-Server-BOT/package.json b/NIA-Server-BOT/package.json deleted file mode 100644 index a972d80..0000000 --- a/NIA-Server-BOT/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "niaserver-net", - "version": "1.2.0", - "description": "用于NIA服务器net通信", - "main": "index.js", - "scripts": { - "start": "node index.js", - "test": "node test.js" - }, - "author": "NIANIANKNIA", - "license": "ISC", - "dependencies": { - "icqq": "^0.4.7", - "os-utils": "^0.0.14" - } -} diff --git a/NIA-Server-BOT/test.js b/NIA-Server-BOT/test.js deleted file mode 100644 index 6833bf8..0000000 --- a/NIA-Server-BOT/test.js +++ /dev/null @@ -1,347 +0,0 @@ -const http = require('http'); -const fs = require('fs'); -const os = require('os-utils'); -//端口不要更换! -const port = 10086; -//const { createClient } = require("icqq"); -//const PLAYERCMDS = ["list","申请白名单","查"] -const serverInfo = {cpuUsage: 0} - -//初始化变量 -var AccountOnline = true; -var ServerStarted = false; - -//初始化配置文件格式,请勿更改!!!! -var config = {"account": 123456,"password": "","QQGroup": 123456789,"owners": [123456],"botconfig":{"platform": 6}} -var account = config.account -var password = config.password - -//配置文件地址 -const cfg_path = "./config.json"; - - -const log = { - error(message) { - console.log("[NIA-Server-BOT] \x1b[31m[ERROR]\x1b[0m [" + new Date().toLocaleString('zh', { hour12: false }).replaceAll('/', '-') + "] " + message) - }, - info(message) { - console.log("[NIA-Server-BOT] \x1b[32m[INFO]\x1b[0m [" + new Date().toLocaleString('zh', { hour12: false }).replaceAll('/', '-') + "] " + message) - }, - warn(message) { - console.log("[NIA-Server-BOT] \x1b[33m[WARN]\x1b[0m [" + new Date().toLocaleString('zh', { hour12: false }).replaceAll('/', '-') + "] " + message) - } -} - -//判断配置文件是否存在 -// fs.access(cfg_path, (err) => { -// //不存在 -// if (err) { -// fs.writeFile(cfg_path, JSON.stringify(config,null,4), 'utf-8', (err) => { -// if (err) { -// return log.error('该文件不存在,重新创建失败!') -// } -// }); -// log.warn("配置文件不存在,已重新创建,请修改配置文件后再运行!"); -// //直接结束本次进程 -// process.exit(1) -// } else { -// //存在,读取配置文件 -// fs.readFile(cfg_path,(err,data) => { -// if (err) { -// return log.error("配置文件读取错误!") -// } -// config = JSON.parse(data.toString()) -// //再次读取配置文件中的数据 -// account = config.account -// password = config.password -// group = client.pickGroup(config.QQGroup) -// log.info("配置文件数据读取成功,正在启动机器人!"); -// //登录qq机器人 -// client = createClient(config.botconfig) -// client.on('system.login.slider', (e) => { -// console.log('输入滑块地址获取的ticket后继续。\n滑块地址: ' + e.url) -// process.stdin.once('data', (data) => { -// client.submitSlider(data.toString().trim()) -// }) -// }) -// client.on('system.login.qrcode', (e) => { -// console.log('扫码完成后回车继续: ') -// process.stdin.once('data', () => { -// client.login() -// }) -// }) -// client.on('system.login.device', (e) => { -// console.log('请选择验证方式:(1:短信验证 其他:扫码验证)') -// process.stdin.once('data', (data) => { -// if (data.toString().trim() === '1') { -// client.sendSmsCode() -// console.log('请输入手机收到的短信验证码:') -// process.stdin.once('data', (res) => { -// client.submitSmsCode(res.toString().trim()) -// }) -// } else { -// console.log('扫码完成后回车继续:' + e.url) -// process.stdin.once('data', () => { -// client.login() -// }) -// } -// }) -// }) -// client.login(account,password) -// //判断机器人是否登录成功 -// client.on('system.online', (e) => { -// AccountOnline = true -// group = client.pickGroup(config.QQGroup) -// group.sendMsg("机器人登陆成功!") -// log.info("机器人登陆成功!") -// }) - -// //监听群聊消息 -// client.on('message.group', (e) => { -// //等适配 -// if (e.group_id == config.QQGroup && e.sender.user_id != 3467371607) { -// if (e.message[0].text.toString().slice(0,1) == "#") { -// let message = e.message[0].text.toString().slice(1).split(" ") -// switch (message[0]) { -// default: -// e.group.sendMsg("未知的指令,请重新检查后再次发送!") -// break; -// case "申请白名单": -// if (message[1] == undefined) { -// e.group.sendMsg("未知的XboxID,请发送形如 #申请白名单 Steve 来获取白名单!") -// } else { -// e.group.sendMsg("你已成功将XboxID <" + message[1] + "> 与qq <" + e.sender.user_id + "> 成功绑定!如需解绑/换绑请联系管理员!") -// } -// break; -// case "查市场": -// fs.readFile("./market.json",(err,data) => { -// if (err) { -// return log.error("market文件读取错误!") -// } -// commodities = JSON.parse(data.toString()) -// let marketStr = "" -// if (message[1] == undefined) { -// for (let i = 0; i < commodities.length; i++) { -// marketStr = "商品名称:" + commodities[i].name + " 商品单价:" + commodities[i].price + "\n" + marketStr -// } -// e.group.sendMsg("已成功获取玩家市场数据:\n" + marketStr) -// } -// }) -// break; -// } -// // if (PLAYERCMDS.indexOf(e.message[0].text.toString().slice(1)) != -1) { -// // e.group.sendMsg("开发中功能!") -// // } else if (e.sender.role == "owner" || e.sender.role == "admin") { -// // e.group.sendMsg("开发中功能!") -// // } else { -// // e.group.sendMsg("您不是管理员,无法执行相关指令!") -// // } -// } else { -// if (e.sender.card == "") { -// repData.msgboxs.push([e.sender.nickname,e.message[0].text.toString()]) -// } else { -// repData.msgboxs.push([e.sender.card,e.message[0].text.toString()]) -// } -// } -// } -// }) - -// }) -// } -// }) - -var commodities = [] - -//判断有没有market文件,没有直接初始化 -fs.access("./market.json", (err) => { - //不存在 - if (err) { - //没有文件直接创建 - fs.writeFile("./market.json", "[]", 'utf-8', (err) => { - if (err) { - log.error('该文件不存在且重新创建失败!') - process.exit(1) - } - }); - } else { - fs.readFile("./market.json",(err,data) => { - if (err) { - return log.error("market文件读取错误!") - } - commodities = JSON.parse(data.toString()) - }) - log.info("market.json已成功读取!") - } -}) - - - -//process.on('unhandledRejection', error => {}); - -//初始化一些变量便于下方的调用 -var msgboxs= {} -var repData = {} -repData.msgboxs = [] - -//定义监听服务器 -var server = http.createServer() - -//如果页面生成失败则调用该函数 -function hadErrer(err,res){ - console.log(err) - res.end('server err') -} - -server.on("request", (req, res) => { - let arr = []; - switch (req.url) { - //监听直接访问 - case "/": - fs.readFile('./index.html', (err, data) => { - if (err) { - return hadErrer(err,res) - } - res.statusCode = 200; - res.setHeader('Content-Type', 'text/html'); - res.end(data.toString()); - }) - break; - //与mc服务器进行通讯,接受其请求 - case "/Check": - if (!ServerStarted) { - ServerStarted = true; - log.info("已经与MC服务器成功连接!") - } - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain;charset=utf-8'); - res.end(JSON.stringify(repData)); - repData = {} - repData.msgboxs = [] - break; - case '/MarketInitialize': - fs.readFile("./market.json",(err,data) => { - if (err) { - return log.error("market文件读取错误!") - } - commodities = JSON.parse(data.toString()) - //开始读取文件 - res.statusCode = 200; - ServerStarted = true; - res.setHeader('Content-Type', 'text/plain;charset=utf-8'); - res.end(JSON.stringify(commodities)); - log.info("market.json已成功读取!") - }) - break; - //监听服务器开服 - case '/ServerStarted': - log.info("已经与MC服务器成功连接!") - res.statusCode = 200; - ServerStarted = true; - res.setHeader('Content-Type', 'text/plain;charset=utf-8'); - res.end("Server Started"); - log.info("服务器已启动!") - break; - //监听玩家说话并转发 - case '/PlayerChat': - req.on("data", (data) => { - arr.push(data) - }) - req.on("end", () => { - let msgData = JSON.parse(Buffer.concat(arr).toString()) - if (AccountOnline) { - group.sendMsg("<" + msgData.name + "> " + msgData.message) - } - }) - res.statusCode = 200; - break; - //监听玩家加入服务器 - case '/PlayerJoin': - req.on("data", (data) => { - arr.push(data) - }) - req.on("end", () => { - let playerjoinData = Buffer.concat(arr).toString() - if (AccountOnline) { - log.info(playerjoinData + " 加入了服务器!") - } - }) - break; - //监听玩家退出服务器 - case '/PlayerLeave': - req.on("data", (data) => { - arr.push(data) - }) - req.on("end", () => { - let playerleaveData = Buffer.concat(arr).toString() - if (AccountOnline) { - log.info(playerleaveData + " 离开了服务器!") - } - }) - break; - case '/Shelf': - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain;charset=utf-8'); - res.end("success") - req.on("data", (data) => { - arr.push(data) - }) - req.on("end", () => { - let itemData = JSON.parse(Buffer.concat(arr).toString()) - if (AccountOnline) { - log.info(`【玩家市场上新提醒】\n玩家 ${itemData.playerName} 在市场中上架了全新的商品!\n商品名称: ${itemData.name} (${itemData.typeid}) \n商品简介: ${itemData.description} \n商品单价: ${itemData.price}\n商品剩余库存: ${itemData.amount}\n商品流水号: ${itemData.id} \n想要的玩家赶快上线购买吧!`) - //group.sendMsg(JSON.stringify(itemData,null,2)) - fs.readFile("./market.json",(err,data) => { - if (err) { - // - return console.log("market文件读取错误!") - } - marketData = JSON.parse(data.toString()) - marketData.push(itemData) - fs.writeFile("./market.json",JSON.stringify(marketData,null,4),function(err){ - if(err){ - console.error(err); - } - errInfo = {} - errInfo.info = "shelf" - repData.errData = marketData - }) - }) - } - }) - break; - } -}) - -//监听服务器开启成功提醒 -server.listen(port,'127.0.0.1', () => { - log.info("NIA服务器监听服务器已经成功在 http://127.0.0.1:" + port + " 启动!"); -}); - - -//获得系统cou占用率 -async function getCPUUsage() { - let promise = new Promise((resolve) => { - os.cpuUsage(function(v){ - resolve(v) - }); - }); - serverInfo.cpuUsage = await promise -} - -//周期运作 -setInterval(() => { - if (AccountOnline) { - //等后续获取自己的qq号 - getCPUUsage() - // if (serverInfo.cpuUsage <= 0.6) { - // group.setCard(3374574180,"🟢流畅 | CPU占用率:" + (serverInfo.cpuUsage*100).toFixed(2) + "%") - // } else if (serverInfo.cpuUsage <= 0.8) { - // group.setCard(3374574180,"🟡一般 | CPU占用率:" + (serverInfo.cpuUsage*100).toFixed(2) + "%") - // } else if (serverInfo.cpuUsage >= 0.9) { - // group.setCard(3374574180,"🔴卡死 | CPU占用率:" + (serverInfo.cpuUsage*100).toFixed(2) + "%") - // } - } - if (!ServerStarted && AccountOnline) { - log.error("暂未连接到MC服务器!") - } -}, 10000) diff --git a/NIAHttpBOT/src/NIAHttpBOT.cpp b/NIAHttpBOT/src/NIAHttpBOT.cpp index cfba914..b1e2707 100644 --- a/NIAHttpBOT/src/NIAHttpBOT.cpp +++ b/NIAHttpBOT/src/NIAHttpBOT.cpp @@ -5,17 +5,21 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include -#define INFO(a) GetTime(), std::cout<<"[INFO] "< Date: Sat, 8 Jul 2023 16:31:01 +0800 Subject: [PATCH 03/13] modify --- NIAHttpBOT/CMakeLists.txt | 2 ++ NIAHttpBOT/src/NIAHttpBOT.cpp | 32 +++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/NIAHttpBOT/CMakeLists.txt b/NIAHttpBOT/CMakeLists.txt index 10f79bf..1087695 100644 --- a/NIAHttpBOT/CMakeLists.txt +++ b/NIAHttpBOT/CMakeLists.txt @@ -9,6 +9,8 @@ project(${PROJECT}) aux_source_directory(./src/ SOURCE) include_directories(./header) +add_definitions(-D__PROJECT__="${CMAKE_CURRENT_SOURCE_DIR}") + add_executable(${PROJECT} ${SOURCE}) diff --git a/NIAHttpBOT/src/NIAHttpBOT.cpp b/NIAHttpBOT/src/NIAHttpBOT.cpp index b1e2707..ea54d59 100644 --- a/NIAHttpBOT/src/NIAHttpBOT.cpp +++ b/NIAHttpBOT/src/NIAHttpBOT.cpp @@ -12,8 +12,11 @@ #include #define INFO(a) GetTime(), std::cout<<"\x1b[32m[INFO]\x1b[0m "<\n"< Date: Sat, 8 Jul 2023 18:22:19 +0800 Subject: [PATCH 04/13] update cmake to run without dll --- NIAHttpBOT/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NIAHttpBOT/CMakeLists.txt b/NIAHttpBOT/CMakeLists.txt index 1087695..5c1137e 100644 --- a/NIAHttpBOT/CMakeLists.txt +++ b/NIAHttpBOT/CMakeLists.txt @@ -4,6 +4,8 @@ set(PROJECT NIAHttpBOT) set(CMAKE_CXX_STANDARD 20) set(CMAKE_BUILD_TYPE Release) +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + project(${PROJECT}) aux_source_directory(./src/ SOURCE) From d292bffe5b9e7691e97841dd5e5d6d56e602b4fd Mon Sep 17 00:00:00 2001 From: jiansyuan Date: Sun, 9 Jul 2023 00:28:38 +0800 Subject: [PATCH 05/13] add the CFG_Parser --- NIAHttpBOT/src/CFG_Parser.hpp | 246 ++++++++++++++++++++++++++++++++++ NIAHttpBOT/src/NIAHttpBOT.cpp | 29 ++++ 2 files changed, 275 insertions(+) create mode 100644 NIAHttpBOT/src/CFG_Parser.hpp diff --git a/NIAHttpBOT/src/CFG_Parser.hpp b/NIAHttpBOT/src/CFG_Parser.hpp new file mode 100644 index 0000000..fed5269 --- /dev/null +++ b/NIAHttpBOT/src/CFG_Parser.hpp @@ -0,0 +1,246 @@ +#ifndef CFG_PARSER_HPP +#define CFG_PARSER_HPP + +// CFG (==CFG File's Genteel) Parser, writen by jiansyuan(github.com/jiansyuan) +/* + | version ? ? ? ----------------- ? ? ? ? | support more... + |--> version 0.0.0 ----------------- 2023.7.8 <--| support basic types: bool, int, char, string and null + | version -1 ----------------- ? ? ? ? | +*/ + + +/* + +Copyright (C) 2023 jiansyuan + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + + +#include +#include +#include +#include +#include + + +#define IS_SPACE(ch) ((ch==' ')||(ch=='\t')||(ch=='\r')) +#define IS_DIGIT(ch) (('0'<=ch)&&(ch<='9')) +#define IS_LETTER(ch) (('a'<=ch&&ch<='z')||('A'<=ch&&ch<='Z')) +#define IS_SYMBOL(ch) (IS_LETTER(ch)||IS_DIGIT(ch)||ch=='-'||ch=='_') + +namespace CFGPAR { + +enum ValueTypeEnum{ + IDontKnow = -1, + BoolType, IntType, CharType, StringType, NullType +}; + +// struct KVnode{ +// std::string key; +// ValueTypeEnum typ = IDontKnow; +// std::variant val; +// }; + +struct Vnode{ + ValueTypeEnum typ = IDontKnow; + std::variant val; + template inline T get() { + return std::get(val); + } +}; + +class parser{ +private: + std::unordered_map KVmap; + +private: + + inline char escapeChar(char ch){ + if(ch=='0') ch = '\0'; + else if(ch=='\\') ch = '\\'; + else if(ch=='r') ch = '\r'; + else if(ch=='n') ch = '\n'; + else if(ch=='t') ch = '\t'; + else if(ch=='\'') ch = '\''; + else if(ch=='\"') ch = '\"'; + else ch = ' '; // TODO: need more + return ch; + } + + std::pair matchBool(const std::string& str, int idx) { + if(str.size()-idx<3) return std::make_pair(false, false); + if(str[idx+1]=='r'&&str[idx+2]=='u'&&str[idx+3]=='e') return std::make_pair(true, true); + if(str.size()-idx<4) return std::make_pair(false, false); + if(str[idx+1]=='a'&&str[idx+2]=='l'&&str[idx+3]=='s'&&str[idx+4]=='e') + return std::make_pair(true, false); + return std::make_pair(false, false); + } + + std::pair matchInt(const std::string& str, int idx) { // TODO: need to support more formats of number + int num = 0, pre = 1; + if(str[idx]=='-') pre=-1, idx++; + if(idx>=str.size() || !IS_DIGIT(str[idx])) return std::make_pair(false, 0); + for(int i=idx; i matchChar(const std::string& str, int idx) { + char ch; + if(str.size()-idx<2 || (str[idx+1]=='\\'&&str.size()-idx<3)) return std::make_pair(false, '\0'); + if(str[idx+1]=='\\') ch = escapeChar(str[idx+2]), idx++; + else ch = str[idx+1]; + if(str[idx+2]!='\'') return std::make_pair(false, '\0'); + return std::make_pair(true, ch); + } + + std::pair matchString(const std::string& str, int idx) { + std::string ret; + for(int i=idx+1;i=str.size()) return std::make_pair(false, ""); // out of range + ret.push_back(escapeChar(str[i+1])), i++; + }else ret.push_back(str[i]); + } + return std::make_pair(true, ret); + } + + bool matchNull(const std::string& str, int idx){ + if(str.size()-idx<3) return false; + if(str[idx+1]=='u'&&str[idx+2]=='l'&&str[idx+3]=='l') return true; + return false; + } + + inline Vnode& operator[] (const std::string& idx){ + return KVmap[idx]; + } + + template inline T getVal(const std::string& idx){ + return KVmap[idx].get(); + } + +public: + parser() : KVmap() {} + + parser(const std::string& cfg) { + parser(); + parFromStr(cfg); + } + + void clear() { + KVmap.clear(); + } + + bool parFromStr(const std::string& str) { + std::vector key; + //std::vector valVec; + for(int i=0; i val; + ValueTypeEnum typ = IDontKnow; + for(int j=i; j>=0; j--) { + if(str[j] == '\n') break; + if(IS_SPACE(str[j])||str[j]=='=') continue; + if(IS_SYMBOL(str[j])) { + tmp=j; break; + } + } + if(tmp == -1) return false; // no symbol in left of the equal sign + for(int j=tmp; j>=0; j--) { + if(str[j]=='\n') break; + if(IS_SYMBOL(str[j])) sym.push_back(str[j]); + else if(IS_SPACE(str[j])) break; + } + std::reverse(sym.begin(), sym.end()); + for(int j=i; j pbi = matchBool(str, j); + if(!pbi.first) return false; // error in matching boolean + val=pbi.second, typ=BoolType; break; + }else if(IS_DIGIT(str[j])||str[j]=='-') { + std::pair pbi = matchInt(str, j); + if(!pbi.first) return false; // error in matching number + val=pbi.second, typ=IntType; break; + }else if(str[j]=='\'') { + std::pair pbi = matchChar(str, j); + if(!pbi.first) return false; // ditto + val=pbi.second, typ=CharType; break; + }else if(str[j]=='\"') { + std::pair pbi = matchString(str, j); + if(!pbi.first) return false; // ditto + val=pbi.second ,typ=StringType; break; + }else if(str[j]=='n') { + bool pbi = matchNull(str, j); + if(!pbi) return false; // ditto + typ=NullType; break; + } + + } + if(typ==IDontKnow) return false; //error in match + //valVec.push_back((KVnode){sym, typ, val}); + KVmap.insert(std::make_pair(sym, (Vnode){typ, val})); + } + return true; + } + + bool parFromFile(const std::string& path){ + std::ifstream file(path); + if (!file.is_open()) return false; + std::string cont((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + file.close(); + return parFromStr(cont); + } + + inline bool hasKey(const std::string& idx){ + return KVmap.count(idx)==1; + } + + #define MAKEIS(name) inline bool is##name(const std::string& idx){ if(KVmap.count(idx)==0) return false; return KVmap[idx].typ == name##Type; } + #define MAKEGET(name,typ) inline typ get##name(const std::string& idx){ if(KVmap.count(idx)==0) return NULL; return getVal(idx); } + #define MAKEISGET(name,typ) MAKEIS(name) MAKEGET(name,typ) + + MAKEISGET(Bool, bool) + MAKEISGET(Int, int) + MAKEISGET(Char, char) + MAKEISGET(String, std::string) + + MAKEIS(Null) + inline bool getNull(const std::string& idx){ return isNull(idx);} + + inline bool isError(const std::string& idx){ + return !hasKey(idx) || KVmap[idx].typ==IDontKnow; + } + +}; + +} + +#undef IS_SPACE +#undef IS_DIGIT +#undef IS_LETTER +#undef IS_SYMBOL +#undef MAKEIS +#undef MAKEGET +#undef MAKEISGET + + +#endif //CFG_PARSER_HPP \ No newline at end of file diff --git a/NIAHttpBOT/src/NIAHttpBOT.cpp b/NIAHttpBOT/src/NIAHttpBOT.cpp index ea54d59..935a1a1 100644 --- a/NIAHttpBOT/src/NIAHttpBOT.cpp +++ b/NIAHttpBOT/src/NIAHttpBOT.cpp @@ -11,6 +11,8 @@ #include #include +#include "CFG_Parser.hpp" + #define INFO(a) GetTime(), std::cout<<"\x1b[32m[INFO]\x1b[0m "< Date: Sun, 9 Jul 2023 14:40:49 +0800 Subject: [PATCH 06/13] add include file --- NIAHttpBOT/src/CFG_Parser.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/NIAHttpBOT/src/CFG_Parser.hpp b/NIAHttpBOT/src/CFG_Parser.hpp index fed5269..bda935f 100644 --- a/NIAHttpBOT/src/CFG_Parser.hpp +++ b/NIAHttpBOT/src/CFG_Parser.hpp @@ -26,6 +26,7 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I #include #include #include +#include #include From e91d8e14217e4529d24e50d1d31b37d67717e955 Mon Sep 17 00:00:00 2001 From: NIANIANKNIA Date: Mon, 10 Jul 2023 02:34:52 +0800 Subject: [PATCH 07/13] =?UTF-8?q?NIAHttpBOT=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG-PRE.md | 21 +- NIAHttpBOT/CMakeLists.txt | 2 - NIAHttpBOT/header/httplib.h | 279 ++++++++++++++--- NIAHttpBOT/src/CFG_Parser.hpp | 15 +- NIAHttpBOT/src/NIAHttpBOT.cpp | 288 ++++++++++++++---- .../NIA_V4.0_BP/manifest.json | 4 +- .../NIA_V4.0_BP/scripts/main.js | 5 +- .../NIA_V4.0_BP/scripts/net.js | 93 +++++- .../NIA_V4.0_RP/manifest.json | 4 +- world_behavior_packs.json | 2 +- world_resource_packs.json | 2 +- 11 files changed, 590 insertions(+), 125 deletions(-) diff --git a/CHANGELOG-PRE.md b/CHANGELOG-PRE.md index ed4e9db..bea7b0c 100644 --- a/CHANGELOG-PRE.md +++ b/CHANGELOG-PRE.md @@ -1,18 +1,27 @@ -# v1.3.1-pre-1 更新日志 +# v1.3.1-pre-2 更新日志 [![BDS VERSION](https://img.shields.io/badge/BDS-1.20.10.02-green?style=for-the-badge&logo=appveyor)](https://www.minecraft.net/en-us/download/server/bedrock) [![LiteLoader VERSION](https://img.shields.io/badge/LiteLoader-2.14.1-green?style=for-the-badge&logo=appveyor)](https://github.com/LiteLDev/LiteLoaderBDS/releases/) -**版本说明:本次script-api出现部分变动,与老版本不相兼容,请及时更新本版本!** - > 预发布版本提醒:这是一个预览版本,可能存在一些bug,仅供测试,请勿在正式生产环境使用本版本! +## 新增 -## 优化 +1.NIAHttpBOT新增部分API(具体使用方法请前往**NIA服务器官方文档站**查看) + +- `/CheckFile` +- `/RunCmd` +- `/WriteLineToFile` +- `/OverwriteFile` +- `/CheckDir` -1.NIAHttpBOT部分优化 +2.NIAHttpBOT新增配置文件 + +3.行为包现在可以自动检查是否为最新版本了 + +## 优化 -2.正式移除`NIA-Server-BOT`项目及其所有文件 +NIAHttpBOT部分情况下报错信息更加详细 **配置说明:您可以前往[NIA服务器官方文档站](https://docs.mcnia.top/zh-CN/deploy.html)查看具体部署过程!** diff --git a/NIAHttpBOT/CMakeLists.txt b/NIAHttpBOT/CMakeLists.txt index 5c1137e..0cffb05 100644 --- a/NIAHttpBOT/CMakeLists.txt +++ b/NIAHttpBOT/CMakeLists.txt @@ -14,5 +14,3 @@ include_directories(./header) add_definitions(-D__PROJECT__="${CMAKE_CURRENT_SOURCE_DIR}") add_executable(${PROJECT} ${SOURCE}) - - diff --git a/NIAHttpBOT/header/httplib.h b/NIAHttpBOT/header/httplib.h index d403b37..716cfa0 100644 --- a/NIAHttpBOT/header/httplib.h +++ b/NIAHttpBOT/header/httplib.h @@ -8,7 +8,7 @@ #ifndef CPPHTTPLIB_HTTPLIB_H #define CPPHTTPLIB_HTTPLIB_H -#define CPPHTTPLIB_VERSION "0.12.6" +#define CPPHTTPLIB_VERSION "0.13.1" /* * Configuration @@ -229,6 +229,8 @@ using socket_t = int; #include #include #include +#include +#include #include #ifdef CPPHTTPLIB_OPENSSL_SUPPORT @@ -472,6 +474,7 @@ struct Request { MultipartFormDataMap files; Ranges ranges; Match matches; + std::unordered_map path_params; // for client ResponseHandler response_handler; @@ -665,6 +668,76 @@ using SocketOptions = std::function; void default_socket_options(socket_t sock); +namespace detail { + +class MatcherBase { +public: + virtual ~MatcherBase() = default; + + // Match request path and populate its matches and + virtual bool match(Request &request) const = 0; +}; + +/** + * Captures parameters in request path and stores them in Request::path_params + * + * Capture name is a substring of a pattern from : to /. + * The rest of the pattern is matched agains the request path directly + * Parameters are captured starting from the next character after + * the end of the last matched static pattern fragment until the next /. + * + * Example pattern: + * "/path/fragments/:capture/more/fragments/:second_capture" + * Static fragments: + * "/path/fragments/", "more/fragments/" + * + * Given the following request path: + * "/path/fragments/:1/more/fragments/:2" + * the resulting capture will be + * {{"capture", "1"}, {"second_capture", "2"}} + */ +class PathParamsMatcher : public MatcherBase { +public: + PathParamsMatcher(const std::string &pattern); + + bool match(Request &request) const override; + +private: + static constexpr char marker = ':'; + // Treat segment separators as the end of path parameter capture + // Does not need to handle query parameters as they are parsed before path + // matching + static constexpr char separator = '/'; + + // Contains static path fragments to match against, excluding the '/' after + // path params + // Fragments are separated by path params + std::vector static_fragments_; + // Stores the names of the path parameters to be used as keys in the + // Request::path_params map + std::vector param_names_; +}; + +/** + * Performs std::regex_match on request path + * and stores the result in Request::matches + * + * Note that regex match is performed directly on the whole request. + * This means that wildcard patterns may match multiple path segments with /: + * "/begin/(.*)/end" will match both "/begin/middle/end" and "/begin/1/2/end". + */ +class RegexMatcher : public MatcherBase { +public: + RegexMatcher(const std::string &pattern) : regex_(pattern) {} + + bool match(Request &request) const override; + +private: + std::regex regex_; +}; + +} // namespace detail + class Server { public: using Handler = std::function; @@ -772,9 +845,14 @@ class Server { size_t payload_max_length_ = CPPHTTPLIB_PAYLOAD_MAX_LENGTH; private: - using Handlers = std::vector>; + using Handlers = + std::vector, Handler>>; using HandlersForContentReader = - std::vector>; + std::vector, + HandlerWithContentReader>>; + + static std::unique_ptr + make_matcher(const std::string &pattern); socket_t create_server_socket(const std::string &host, int port, int socket_flags, @@ -817,17 +895,18 @@ class Server { virtual bool process_and_close_socket(socket_t sock); + std::atomic is_running_{false}; + std::atomic done_{false}; + struct MountPointEntry { std::string mount_point; std::string base_dir; Headers headers; }; std::vector base_dirs_; - - std::atomic is_running_{false}; - std::atomic done_{false}; std::map file_extension_and_mimetype_map_; Handler file_request_handler_; + Handlers get_handlers_; Handlers post_handlers_; HandlersForContentReader post_handlers_for_content_reader_; @@ -838,13 +917,15 @@ class Server { Handlers delete_handlers_; HandlersForContentReader delete_handlers_for_content_reader_; Handlers options_handlers_; + HandlerWithResponse error_handler_; ExceptionHandler exception_handler_; HandlerWithResponse pre_routing_handler_; Handler post_routing_handler_; - Logger logger_; Expect100ContinueHandler expect_100_continue_handler_; + Logger logger_; + int address_family_ = AF_UNSPEC; bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY; SocketOptions socket_options_ = default_socket_options; @@ -878,6 +959,7 @@ std::ostream &operator<<(std::ostream &os, const Error &obj); class Result { public: + Result() = default; Result(std::unique_ptr &&res, Error err, Headers &&request_headers = Headers{}) : res_(std::move(res)), err_(err), @@ -906,7 +988,7 @@ class Result { private: std::unique_ptr res_; - Error err_; + Error err_ = Error::Unknown; Headers request_headers_; }; @@ -1066,11 +1148,13 @@ class ClientImpl { bool send(Request &req, Response &res, Error &error); Result send(const Request &req); - size_t is_socket_open() const; + void stop(); - socket_t socket() const; + std::string host() const; + int port() const; - void stop(); + size_t is_socket_open() const; + socket_t socket() const; void set_hostname_addr_map(std::map addr_map); @@ -1439,11 +1523,13 @@ class Client { bool send(Request &req, Response &res, Error &error); Result send(const Request &req); - size_t is_socket_open() const; + void stop(); - socket_t socket() const; + std::string host() const; + int port() const; - void stop(); + size_t is_socket_open() const; + socket_t socket() const; void set_hostname_addr_map(std::map addr_map); @@ -5143,6 +5229,99 @@ inline socket_t BufferStream::socket() const { return 0; } inline const std::string &BufferStream::get_buffer() const { return buffer; } +inline PathParamsMatcher::PathParamsMatcher(const std::string &pattern) { + // One past the last ending position of a path param substring + std::size_t last_param_end = 0; + +#ifndef CPPHTTPLIB_NO_EXCEPTIONS + // Needed to ensure that parameter names are unique during matcher + // construction + // If exceptions are disabled, only last duplicate path + // parameter will be set + std::unordered_set param_name_set; +#endif + + while (true) { + const auto marker_pos = pattern.find(marker, last_param_end); + if (marker_pos == std::string::npos) { break; } + + static_fragments_.push_back( + pattern.substr(last_param_end, marker_pos - last_param_end)); + + const auto param_name_start = marker_pos + 1; + + auto sep_pos = pattern.find(separator, param_name_start); + if (sep_pos == std::string::npos) { sep_pos = pattern.length(); } + + auto param_name = + pattern.substr(param_name_start, sep_pos - param_name_start); + +#ifndef CPPHTTPLIB_NO_EXCEPTIONS + if (param_name_set.find(param_name) != param_name_set.cend()) { + std::string msg = "Encountered path parameter '" + param_name + + "' multiple times in route pattern '" + pattern + "'."; + throw std::invalid_argument(msg); + } +#endif + + param_names_.push_back(std::move(param_name)); + + last_param_end = sep_pos + 1; + } + + if (last_param_end < pattern.length()) { + static_fragments_.push_back(pattern.substr(last_param_end)); + } +} + +inline bool PathParamsMatcher::match(Request &request) const { + request.matches = std::smatch(); + request.path_params.clear(); + request.path_params.reserve(param_names_.size()); + + // One past the position at which the path matched the pattern last time + std::size_t starting_pos = 0; + for (size_t i = 0; i < static_fragments_.size(); ++i) { + const auto &fragment = static_fragments_[i]; + + if (starting_pos + fragment.length() > request.path.length()) { + return false; + } + + // Avoid unnecessary allocation by using strncmp instead of substr + + // comparison + if (std::strncmp(request.path.c_str() + starting_pos, fragment.c_str(), + fragment.length()) != 0) { + return false; + } + + starting_pos += fragment.length(); + + // Should only happen when we have a static fragment after a param + // Example: '/users/:id/subscriptions' + // The 'subscriptions' fragment here does not have a corresponding param + if (i >= param_names_.size()) { continue; } + + auto sep_pos = request.path.find(separator, starting_pos); + if (sep_pos == std::string::npos) { sep_pos = request.path.length(); } + + const auto ¶m_name = param_names_[i]; + + request.path_params.emplace( + param_name, request.path.substr(starting_pos, sep_pos - starting_pos)); + + // Mark everythin up to '/' as matched + starting_pos = sep_pos + 1; + } + // Returns false if the path is longer than the pattern + return starting_pos >= request.path.length(); +} + +inline bool RegexMatcher::match(Request &request) const { + request.path_params.clear(); + return std::regex_match(request.path, request.matches, regex_); +} + } // namespace detail // HTTP server implementation @@ -5156,67 +5335,76 @@ inline Server::Server() inline Server::~Server() {} +inline std::unique_ptr +Server::make_matcher(const std::string &pattern) { + if (pattern.find("/:") != std::string::npos) { + return detail::make_unique(pattern); + } else { + return detail::make_unique(pattern); + } +} + inline Server &Server::Get(const std::string &pattern, Handler handler) { get_handlers_.push_back( - std::make_pair(std::regex(pattern), std::move(handler))); + std::make_pair(make_matcher(pattern), std::move(handler))); return *this; } inline Server &Server::Post(const std::string &pattern, Handler handler) { post_handlers_.push_back( - std::make_pair(std::regex(pattern), std::move(handler))); + std::make_pair(make_matcher(pattern), std::move(handler))); return *this; } inline Server &Server::Post(const std::string &pattern, HandlerWithContentReader handler) { post_handlers_for_content_reader_.push_back( - std::make_pair(std::regex(pattern), std::move(handler))); + std::make_pair(make_matcher(pattern), std::move(handler))); return *this; } inline Server &Server::Put(const std::string &pattern, Handler handler) { put_handlers_.push_back( - std::make_pair(std::regex(pattern), std::move(handler))); + std::make_pair(make_matcher(pattern), std::move(handler))); return *this; } inline Server &Server::Put(const std::string &pattern, HandlerWithContentReader handler) { put_handlers_for_content_reader_.push_back( - std::make_pair(std::regex(pattern), std::move(handler))); + std::make_pair(make_matcher(pattern), std::move(handler))); return *this; } inline Server &Server::Patch(const std::string &pattern, Handler handler) { patch_handlers_.push_back( - std::make_pair(std::regex(pattern), std::move(handler))); + std::make_pair(make_matcher(pattern), std::move(handler))); return *this; } inline Server &Server::Patch(const std::string &pattern, HandlerWithContentReader handler) { patch_handlers_for_content_reader_.push_back( - std::make_pair(std::regex(pattern), std::move(handler))); + std::make_pair(make_matcher(pattern), std::move(handler))); return *this; } inline Server &Server::Delete(const std::string &pattern, Handler handler) { delete_handlers_.push_back( - std::make_pair(std::regex(pattern), std::move(handler))); + std::make_pair(make_matcher(pattern), std::move(handler))); return *this; } inline Server &Server::Delete(const std::string &pattern, HandlerWithContentReader handler) { delete_handlers_for_content_reader_.push_back( - std::make_pair(std::regex(pattern), std::move(handler))); + std::make_pair(make_matcher(pattern), std::move(handler))); return *this; } inline Server &Server::Options(const std::string &pattern, Handler handler) { options_handlers_.push_back( - std::make_pair(std::regex(pattern), std::move(handler))); + std::make_pair(make_matcher(pattern), std::move(handler))); return *this; } @@ -5926,10 +6114,10 @@ inline bool Server::routing(Request &req, Response &res, Stream &strm) { inline bool Server::dispatch_request(Request &req, Response &res, const Handlers &handlers) { for (const auto &x : handlers) { - const auto &pattern = x.first; + const auto &matcher = x.first; const auto &handler = x.second; - if (std::regex_match(req.path, req.matches, pattern)) { + if (matcher->match(req)) { handler(req, res); return true; } @@ -6051,10 +6239,10 @@ inline bool Server::dispatch_request_for_content_reader( Request &req, Response &res, ContentReader content_reader, const HandlersForContentReader &handlers) { for (const auto &x : handlers) { - const auto &pattern = x.first; + const auto &matcher = x.first; const auto &handler = x.second; - if (std::regex_match(req.path, req.matches, pattern)) { + if (matcher->match(req)) { handler(req, res, content_reader); return true; } @@ -6074,15 +6262,10 @@ Server::process_request(Stream &strm, bool close_connection, if (!line_reader.getline()) { return false; } Request req; - Response res; + Response res; res.version = "HTTP/1.1"; - - for (const auto &header : default_headers_) { - if (res.headers.find(header.first) == res.headers.end()) { - res.headers.insert(header); - } - } + res.headers = default_headers_; #ifdef _WIN32 // TODO: Increase FD_SETSIZE statically (libzmq), dynamically (MySQL). @@ -7477,13 +7660,6 @@ inline Result ClientImpl::Options(const std::string &path, return send_(std::move(req)); } -inline size_t ClientImpl::is_socket_open() const { - std::lock_guard guard(socket_mutex_); - return socket_.is_open(); -} - -inline socket_t ClientImpl::socket() const { return socket_.sock; } - inline void ClientImpl::stop() { std::lock_guard guard(socket_mutex_); @@ -7507,6 +7683,17 @@ inline void ClientImpl::stop() { close_socket(socket_); } +inline std::string ClientImpl::host() const { return host_; } + +inline int ClientImpl::port() const { return port_; } + +inline size_t ClientImpl::is_socket_open() const { + std::lock_guard guard(socket_mutex_); + return socket_.is_open(); +} + +inline socket_t ClientImpl::socket() const { return socket_.sock; } + inline void ClientImpl::set_connection_timeout(time_t sec, time_t usec) { connection_timeout_sec_ = sec; connection_timeout_usec_ = usec; @@ -8719,12 +8906,16 @@ inline bool Client::send(Request &req, Response &res, Error &error) { inline Result Client::send(const Request &req) { return cli_->send(req); } +inline void Client::stop() { cli_->stop(); } + +inline std::string Client::host() const { return cli_->host(); } + +inline int Client::port() const { return cli_->port(); } + inline size_t Client::is_socket_open() const { return cli_->is_socket_open(); } inline socket_t Client::socket() const { return cli_->socket(); } -inline void Client::stop() { cli_->stop(); } - inline void Client::set_hostname_addr_map(std::map addr_map) { cli_->set_hostname_addr_map(std::move(addr_map)); diff --git a/NIAHttpBOT/src/CFG_Parser.hpp b/NIAHttpBOT/src/CFG_Parser.hpp index bda935f..9c184c7 100644 --- a/NIAHttpBOT/src/CFG_Parser.hpp +++ b/NIAHttpBOT/src/CFG_Parser.hpp @@ -5,11 +5,11 @@ /* | version ? ? ? ----------------- ? ? ? ? | support more... |--> version 0.0.0 ----------------- 2023.7.8 <--| support basic types: bool, int, char, string and null - | version -1 ----------------- ? ? ? ? | + | version -1 ----------------- ? ? ? ? | */ -/* +/* Copyright (C) 2023 jiansyuan @@ -35,6 +35,9 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I #define IS_LETTER(ch) (('a'<=ch&&ch<='z')||('A'<=ch&&ch<='Z')) #define IS_SYMBOL(ch) (IS_LETTER(ch)||IS_DIGIT(ch)||ch=='-'||ch=='_') + + + namespace CFGPAR { enum ValueTypeEnum{ @@ -197,11 +200,13 @@ class parser{ } if(typ==IDontKnow) return false; //error in match //valVec.push_back((KVnode){sym, typ, val}); - KVmap.insert(std::make_pair(sym, (Vnode){typ, val})); + /*Vnode temp = {typ, val}; + KVmap.insert(std::make_pair(sym, temp));*/ + KVmap.insert(std::make_pair(sym, Vnode{ typ, val })); } - return true; + return true; } - + bool parFromFile(const std::string& path){ std::ifstream file(path); if (!file.is_open()) return false; diff --git a/NIAHttpBOT/src/NIAHttpBOT.cpp b/NIAHttpBOT/src/NIAHttpBOT.cpp index 935a1a1..713eaa3 100644 --- a/NIAHttpBOT/src/NIAHttpBOT.cpp +++ b/NIAHttpBOT/src/NIAHttpBOT.cpp @@ -1,8 +1,9 @@ - + #include #include #include #include +#include #include #include @@ -21,8 +22,10 @@ <<")\x1b[0m ==>\n"< writer(buffer); @@ -256,6 +312,124 @@ R"( _ _ _____ _____ ___ ___ ___ _____ }); + //执行cmd命令 + svr.Post("/RunCmd", [](const httplib::Request& req, httplib::Response& res) { + //首先判断配置文件是否启用 + if (!UseCmd) { + WARN("执行DOS命令的功能暂未启用!请在启用后使用!"); + res.status = 200; + res.set_content("feature not enabled!", "text/plain"); + return ; + } + std::string cmd = req.body; + WARN("收到一条执行DOS命令的请求:" + cmd); + system(cmd.c_str()); + res.status = 200; + res.set_content("success", "text/plain"); + }); + + //向目标文件写入一行内容 + svr.Post("/WriteLineToFile", [](const httplib::Request& req, httplib::Response& res) { + INFO("接收到向目标文件写入一行内容的请求!"); + //解析字符串并创建一个json对象 + rapidjson::Document WriteLineData; + WriteLineData.Parse(req.body.c_str()); + //判断是否解析成功 + if (WriteLineData.HasParseError()) { + res.status = 200; + res.set_content("Data parsing failed", "text/plain"); + return ; + } + if(!WriteLineData.HasMember("fileName")){ + res.status = 200; + res.set_content("The fileName key for the json object was not found! Please recheck and send again.", "text/plain"); + return ; + } + if(!WriteLineData.HasMember("content")){ + res.status = 200; + res.set_content("The content key for the json object was not found! Please recheck and send again.", "text/plain"); + return ; + } + //初始化文件名称 + std::string fileName = ""; + //读取文件名称 + fileName = WriteLineData["fileName"].GetString(); + //读取文件内容 + std::string fileContent = WriteLineData["content"].GetString(); + // 检测${fileName}文件是否存在,如果不存在,就创建一个新的文件,并写入内容 + std::ifstream file(fileName); + if(!file) { + res.status = 200; + res.set_content("The target file does not exist.", "text/plain"); + return ; + } + //打开指定文件开始写入数据 + std::ofstream outFile(fileName, std::ios_base::app); + outFile << fileContent; + outFile.close(); + res.status = 200; + res.set_content("success", "text/plain"); + file.close(); + }); + + //向目标文件覆盖内容 + svr.Post("/OverwriteFile", [](const httplib::Request& req, httplib::Response& res) { + INFO("接收到覆写文件的请求!"); + //解析字符串并创建一个json对象 + rapidjson::Document OverwriteFileData; + OverwriteFileData.Parse(req.body.c_str()); + //判断是否解析成功 + if (OverwriteFileData.HasParseError()) { + res.status = 200; + res.set_content("Data parsing failed", "text/plain"); + return ; + } + if(!OverwriteFileData.HasMember("fileName")){ + res.status = 200; + res.set_content("The fileName key for the json object was not found! Please recheck and send again.", "text/plain"); + return ; + } + if(!OverwriteFileData.HasMember("content")){ + res.status = 200; + res.set_content("The content key for the json object was not found! Please recheck and send again.", "text/plain"); + return ; + } + //初始化文件名称 + std::string fileName = ""; + //读取文件名称 + fileName = OverwriteFileData["fileName"].GetString(); + //读取文件内容 + std::string fileContent = OverwriteFileData["content"].GetString(); + // 检测${fileName}文件是否存在 + std::ifstream file(fileName); + if(!file) { + res.status = 200; + res.set_content("The target file does not exist.", "text/plain"); + return ; + } + //打开指定文件开始写入数据 + std::ofstream outFile(fileName); + outFile << fileContent; + outFile.close(); + res.status = 200; + res.set_content("success", "text/plain"); + file.close(); + }); + + //检测指定文件夹是否存在 + svr.Post("/CheckDir", [](const httplib::Request& req, httplib::Response& res) { + std::filesystem::path p{req.body}; + if (std::filesystem::exists(p)) { + res.status = 200; + res.set_content("true", "text/plain"); + } else { + res.status = 200; + res.set_content("false", "text/plain"); + } + }); + + + svr.listen(IPAddress, PORT); return 0; diff --git a/development_behavior_packs/NIA_V4.0_BP/manifest.json b/development_behavior_packs/NIA_V4.0_BP/manifest.json index 8e6befd..6576bcd 100644 --- a/development_behavior_packs/NIA_V4.0_BP/manifest.json +++ b/development_behavior_packs/NIA_V4.0_BP/manifest.json @@ -4,7 +4,7 @@ "name": "NIA V4.0 BP", "description": "§bNIA服务器V4-行为包\n作者:NIANIANKNIA\n项目地址:https://github.com/NIANIANKNIA/NIASERVER-V4", "uuid": "cab0bbe3-eb10-465e-b1de-b09facc076c8", - "version": [ 1, 3, 0 ], + "version": [ 1, 3, 1 ], "min_engine_version": [ 1, 20, 0 ] }, "modules": [ @@ -14,7 +14,7 @@ "description": "gametest module", "uuid": "92cd3fe1-e764-425a-aa40-a7e4d7760922", "entry": "scripts/main.js", - "version": [ 1, 3, 0 ] + "version": [ 1, 3, 1 ] } ], "dependencies": [ diff --git a/development_behavior_packs/NIA_V4.0_BP/scripts/main.js b/development_behavior_packs/NIA_V4.0_BP/scripts/main.js index c15c893..0de5ca2 100644 --- a/development_behavior_packs/NIA_V4.0_BP/scripts/main.js +++ b/development_behavior_packs/NIA_V4.0_BP/scripts/main.js @@ -137,7 +137,10 @@ const equLevelData = { //服务器启动监听 world.afterEvents.worldInitialize.subscribe(() => { - console.log("\n\x1b[33m[NIA V4] You are using a preview version, do not use it in a production environment!\n[NIA V4] NIA V4 has been successfully started on the server!\n[NIA V4] version: v1.3.0-pre based on BDS-1.20.10.02(last upgrate:2023/6/28)\n[NIA V4] author:@NIANIANKNIA(https://github.com/NIANIANKNIA)\x1b[0m") + console.log("\n\x1b[33m[NIA V4] You are using a preview version, do not use it in a production environment!\x1b[0m") + console.log("\n\x1b[33m[NIA V4] NIA V4 has been successfully started on the server!\x1b[0m") + console.log("\n\x1b[33m[NIA V4] version: v1.3.1-pre based on BDS-1.20.10.02(last upgrate:2023/7/10)\x1b[0m") + console.log("\n\x1b[33m[NIA V4] author: @NIANIANKNIA(https://github.com/NIANIANKNIA)\x1b[0m") }) // 玩家死亡后重生的检测 diff --git a/development_behavior_packs/NIA_V4.0_BP/scripts/net.js b/development_behavior_packs/NIA_V4.0_BP/scripts/net.js index d6f44bc..264b829 100644 --- a/development_behavior_packs/NIA_V4.0_BP/scripts/net.js +++ b/development_behavior_packs/NIA_V4.0_BP/scripts/net.js @@ -1,8 +1,9 @@ import {world,system} from '@minecraft/server'; import {cfg} from './config.js' -import {Broadcast,Tell,RunCmd,AddScoreboard,GetScore,getNumberInNormalDistribution} from './customFunction.js' +import {Broadcast,Tell,RunCmd,AddScoreboard,GetScore,getNumberInNormalDistribution, GetTime} from './customFunction.js' import {http,HttpRequestMethod,HttpRequest,HttpHeader} from '@minecraft/server-net'; const port = 10086 +const VERSION = "v1.3.1-pre-1" //与服务器通信获取群聊消息 system.runInterval(() => { // let reqCheck = http.get(`http://127.0.0.1:${port}/Check`) @@ -29,7 +30,10 @@ system.runInterval(() => { } }) - //检查文件是否存在 + + //NIAHttpBOT部分功能使用示例 + + // 检查文件是否存在 // const reqCheckFile = new HttpRequest(`http://127.0.0.1:${port}/CheckFile`); // reqCheckFile.body = "FileName.json" // reqCheckFile.method = HttpRequestMethod.POST; @@ -46,6 +50,23 @@ system.runInterval(() => { // } // }) + // 检查文件夹是否存在 + // const reqCheckDir = new HttpRequest(`http://127.0.0.1:${port}/CheckDir`); + // reqCheckDir.body = "./A" + // reqCheckDir.method = HttpRequestMethod.POST; + // reqCheckDir.headers = [ + // new HttpHeader("Content-Type", "text/plain"), + // ]; + // http.request(reqCheckDir).then((response) => { + // if (response.status == 200 && response.body == "true") { + // console.log("Target folder exists.") + // } else if (response.status == 200 && response.body == "false") { + // console.error("The target folder does not exist") + // } else { + // console.error("Dependent server connection failed! Check whether the dependent server started successfully.") + // } + // }) + //创建json文件 // const reqCreateNewJsonFile = new HttpRequest(`http://127.0.0.1:${port}/CreateNewJsonFile`); // reqCreateNewJsonFile.body = JSON.stringify({"fileName":"market111.json","fileContent":{"a":10}}) @@ -96,9 +117,59 @@ system.runInterval(() => { // console.error("Dependent server connection failed! Check whether the dependent server started successfully.") // } // }) -},60) -// + //执行cmd指令 + // const reqRunCmd = new HttpRequest(`http://127.0.0.1:${port}/RunCmd`); + // reqRunCmd.body = "del 123.txt" + // reqRunCmd.method = HttpRequestMethod.POST; + // reqRunCmd.headers = [ + // new HttpHeader("Content-Type", "text/plain"), + // ]; + // http.request(reqRunCmd).then((response) => { + // if (response.status == 200 && response.body == "success") { + // console.log("Dos command executed successfully!") + // } else if (response.status == 200 && response.body != "success") { + // console.error(response.body) + // } else { + // console.error("Dependent server connection failed! Check whether the dependent server started successfully.") + // } + // }) + + //向目标文件写入一行 + // const reqWriteLineToFile = new HttpRequest(`http://127.0.0.1:${port}/WriteLineToFile`); + // reqWriteLineToFile.body = JSON.stringify({"fileName":"123.txt","content": "这是一行测试内容" + "\n"}) + // reqWriteLineToFile.method = HttpRequestMethod.POST; + // reqWriteLineToFile.headers = [ + // new HttpHeader("Content-Type", "text/plain"), + // ]; + // http.request(reqWriteLineToFile).then((response) => { + // if (response.status == 200 && response.body == "success") { + // console.log("Overwrite file data successfully!") + // } else if (response.status == 200 && response.body != "success") { + // console.error(response.body) + // } else { + // console.error("Dependent server connection failed! Check whether the dependent server started successfully.") + // } + // }) + + //向目标文件覆写内容 + // const reqOverwriteFile = new HttpRequest(`http://127.0.0.1:${port}/OverwriteFile`); + // reqOverwriteFile.body = JSON.stringify({"fileName":"123.txt","content": "这是一行测试内容" + "\n"}) + // reqOverwriteFile.method = HttpRequestMethod.POST; + // reqOverwriteFile.headers = [ + // new HttpHeader("Content-Type", "text/plain"), + // ]; + // http.request(reqOverwriteFile).then((response) => { + // if (response.status == 200 && response.body == "success") { + // console.log("Overwrite file data successfully!") + // } else if (response.status == 200 && response.body != "success") { + // console.error(response.body) + // } else { + // console.error("Dependent server connection failed! Check whether the dependent server started successfully.") + // } + // }) + +}, 60) //服务器启动监听 world.afterEvents.worldInitialize.subscribe(() => { @@ -110,6 +181,20 @@ world.afterEvents.worldInitialize.subscribe(() => { console.error("[NIA V4] Dependent server connection failed! Check whether the dependent server started successfully.") } }) + + //检查更新 + const reqCheckUpdate = http.get(`http://api.github.com/repos/NIANIANKNIA/NIASERVER-V4/releases`) + reqCheckUpdate.then((response) => { + if (response.status == 200) { + if (JSON.parse(response.body)[0].tag_name != VERSION) { + console.warn(`The current version is not the latest version. The currently used version is ${VERSION}, and the latest version is ${JSON.parse(response.body)[0].tag_name}. Click the link to jump to download immediately: https://github.com/NIANIANKNIA/NIASERVER-V4/releases/tag/${JSON.parse(response.body)[0].tag_name}`) + } else { + console.log("Checking for updates is successful, all versions are the latest versions!") + } + } else { + console.error("Github server connection failed!") + } + }) // const reqServerStarted = new HttpRequest(`http://127.0.0.1:${port}/ServerStarted`); // reqServerStarted.body = JSON.stringify({ // score: 22, diff --git a/development_resource_packs/NIA_V4.0_RP/manifest.json b/development_resource_packs/NIA_V4.0_RP/manifest.json index 728087a..77cefeb 100644 --- a/development_resource_packs/NIA_V4.0_RP/manifest.json +++ b/development_resource_packs/NIA_V4.0_RP/manifest.json @@ -5,14 +5,14 @@ "name": "NIA V4.0 RP", "uuid": "981f1ce2-370b-4f58-99d9-9c504a118ec0", "min_engine_version": [1, 20, 0], - "version": [1, 3, 0] + "version": [1, 3, 1] }, "modules": [ { "description": "NIANIANKNIA", "type": "resources", "uuid": "7e41869f-82f7-40f5-87c0-4dcfbc61d91b", - "version": [1, 3, 0] + "version": [1, 3, 1] } ], "metadata": { diff --git a/world_behavior_packs.json b/world_behavior_packs.json index da19c63..ab552a2 100644 --- a/world_behavior_packs.json +++ b/world_behavior_packs.json @@ -2,7 +2,7 @@ { "pack_id": "cab0bbe3-eb10-465e-b1de-b09facc076c8", "version": [ - 1,3,0 + 1,3,1 ] } ] \ No newline at end of file diff --git a/world_resource_packs.json b/world_resource_packs.json index 290d892..d89e311 100644 --- a/world_resource_packs.json +++ b/world_resource_packs.json @@ -2,7 +2,7 @@ { "pack_id": "981f1ce2-370b-4f58-99d9-9c504a118ec0", "version": [ - 1,3,0 + 1,3,1 ] } ] \ No newline at end of file From c7b9c6e3e9804ccec0f602dbddced43445590a65 Mon Sep 17 00:00:00 2001 From: NIANIANKNIA Date: Mon, 10 Jul 2023 02:42:53 +0800 Subject: [PATCH 08/13] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NIAHttpBOT/src/NIAHttpBOT.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/NIAHttpBOT/src/NIAHttpBOT.cpp b/NIAHttpBOT/src/NIAHttpBOT.cpp index 713eaa3..380a7bc 100644 --- a/NIAHttpBOT/src/NIAHttpBOT.cpp +++ b/NIAHttpBOT/src/NIAHttpBOT.cpp @@ -38,6 +38,7 @@ void GetTime() { int main() { + system("title NIAHttpBOT V1.3.1"); SetConsoleOutputCP(65001); std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0); From 9605c564abc3fef67586516258d1c351d7b9f839 Mon Sep 17 00:00:00 2001 From: NIANIANKNIA Date: Mon, 10 Jul 2023 02:54:33 +0800 Subject: [PATCH 09/13] =?UTF-8?q?=E9=87=8D=E6=96=B0=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NIAHttpBOT/src/NIAHttpBOT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NIAHttpBOT/src/NIAHttpBOT.cpp b/NIAHttpBOT/src/NIAHttpBOT.cpp index 380a7bc..0cf7c66 100644 --- a/NIAHttpBOT/src/NIAHttpBOT.cpp +++ b/NIAHttpBOT/src/NIAHttpBOT.cpp @@ -1,4 +1,4 @@ - + #include #include #include From 5d3d153bfbbf49d0e86815669cdb87afd39e2bef Mon Sep 17 00:00:00 2001 From: NIANIANKNIA Date: Mon, 10 Jul 2023 15:03:34 +0800 Subject: [PATCH 10/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dhttpbot=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E9=94=99=E4=BD=8D=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NIAHttpBOT/src/NIAHttpBOT.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/NIAHttpBOT/src/NIAHttpBOT.cpp b/NIAHttpBOT/src/NIAHttpBOT.cpp index 0cf7c66..9ae238e 100644 --- a/NIAHttpBOT/src/NIAHttpBOT.cpp +++ b/NIAHttpBOT/src/NIAHttpBOT.cpp @@ -63,24 +63,25 @@ int main() { } std::cout<<"\x1b[36m"< Date: Mon, 10 Jul 2023 17:20:15 +0800 Subject: [PATCH 11/13] add AVX2 --- NIAHttpBOT/CMakeLists.txt | 10 ++++++++- NIAHttpBOT/src/CFG_Parser.hpp | 35 +++++++++++++++++++++++--------- NIAHttpBOT/src/NIAHttpBOT.cpp | 38 ++++++++++++++--------------------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/NIAHttpBOT/CMakeLists.txt b/NIAHttpBOT/CMakeLists.txt index 0cffb05..a3cca32 100644 --- a/NIAHttpBOT/CMakeLists.txt +++ b/NIAHttpBOT/CMakeLists.txt @@ -1,12 +1,19 @@ cmake_minimum_required(VERSION 3.21) +include(CheckCXXCompilerFlag) + set(PROJECT NIAHttpBOT) set(CMAKE_CXX_STANDARD 20) set(CMAKE_BUILD_TYPE Release) +project(${PROJECT}) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") -project(${PROJECT}) +check_cxx_compiler_flag("/arch:AVX2" COMPILER_SUPPORTS_AVX2) +if(COMPILER_SUPPORTS_AVX2) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2") +endif() aux_source_directory(./src/ SOURCE) include_directories(./header) @@ -14,3 +21,4 @@ include_directories(./header) add_definitions(-D__PROJECT__="${CMAKE_CURRENT_SOURCE_DIR}") add_executable(${PROJECT} ${SOURCE}) + diff --git a/NIAHttpBOT/src/CFG_Parser.hpp b/NIAHttpBOT/src/CFG_Parser.hpp index 9c184c7..cf06324 100644 --- a/NIAHttpBOT/src/CFG_Parser.hpp +++ b/NIAHttpBOT/src/CFG_Parser.hpp @@ -22,12 +22,13 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I */ +#include + #include #include #include #include #include -#include #define IS_SPACE(ch) ((ch==' ')||(ch=='\t')||(ch=='\r')) @@ -65,6 +66,28 @@ class parser{ private: + inline std::vector findEqualSigns(const std::string& str, char tar='=') { + std::vector ret; +#ifdef __AVX2__ + const char* data = str.data(); + __m256i tars = _mm256_set1_epi8(tar); + size_t i = 0; + for (; i+32(data+i)), + match = _mm256_cmpeq_epi8(chunk, tars); + int mask = _mm256_movemask_epi8(match); + while (mask != 0) { + int index = __builtin_ctz(mask); + ret.push_back(i+(unsigned)index), mask &= ~(1< matchString(const std::string& str, int idx) { std::string ret; - for(int i=idx+1;i key; - //std::vector valVec; - for(int i=0; i key = findEqualSigns(str); for(auto i : key) { int tmp = -1; std::string sym; @@ -199,9 +219,6 @@ class parser{ } if(typ==IDontKnow) return false; //error in match - //valVec.push_back((KVnode){sym, typ, val}); - /*Vnode temp = {typ, val}; - KVmap.insert(std::make_pair(sym, temp));*/ KVmap.insert(std::make_pair(sym, Vnode{ typ, val })); } return true; diff --git a/NIAHttpBOT/src/NIAHttpBOT.cpp b/NIAHttpBOT/src/NIAHttpBOT.cpp index 9ae238e..2c5f957 100644 --- a/NIAHttpBOT/src/NIAHttpBOT.cpp +++ b/NIAHttpBOT/src/NIAHttpBOT.cpp @@ -43,25 +43,6 @@ int main() { SetConsoleOutputCP(65001); std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0); - CFGPAR::parser par; - //首先检查有没有配置文件 - std::ifstream cfgFile("NIAHttpBOT.cfg"); - if (!cfgFile) { - std::ofstream outcfgFile("NIAHttpBOT.cfg"); - outcfgFile << "IPAddress = \"127.0.0.1\"\n"; - outcfgFile << "Port = 10086\n"; - outcfgFile << "UseCmd = false\n"; - outcfgFile.close(); - WARN("未找到配置文件,已自动初始化配置文件 NIAHttpBOT.cfg"); - } else { - cfgFile.close(); - par.parFromFile("./NIAHttpBOT.cfg"); - IPAddress = par.getString("IPAddress"); - PORT = par.getInt("Port"); - UseCmd = par.getBool("UseCmd"); - INFO("已成功读取配置文件!"); - } - std::cout<<"\x1b[36m"< Date: Mon, 10 Jul 2023 21:47:41 +0800 Subject: [PATCH 12/13] remove the function cannot use on msvc --- NIAHttpBOT/src/CFG_Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NIAHttpBOT/src/CFG_Parser.hpp b/NIAHttpBOT/src/CFG_Parser.hpp index cf06324..79f7164 100644 --- a/NIAHttpBOT/src/CFG_Parser.hpp +++ b/NIAHttpBOT/src/CFG_Parser.hpp @@ -77,7 +77,7 @@ class parser{ match = _mm256_cmpeq_epi8(chunk, tars); int mask = _mm256_movemask_epi8(match); while (mask != 0) { - int index = __builtin_ctz(mask); + int index = _tzcnt_u32(mask); //__builtin_ctz(mask); ret.push_back(i+(unsigned)index), mask &= ~(1< Date: Wed, 19 Jul 2023 22:40:43 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E4=BC=98=E5=8C=96NIAHttpBOT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 48 ++++--------------- NIAHttpBOT/src/NIAHttpBOT.cpp | 41 ++++------------ .../NIA_V4.0_BP/scripts/API/scoreboard.js | 0 .../NIA_V4.0_BP/scripts/config.js | 8 ++-- .../NIA_V4.0_BP/scripts/customFunction.js | 18 +------ .../NIA_V4.0_BP/scripts/main.js | 24 ---------- .../NIA_V4.0_BP/scripts/market.js | 4 ++ 7 files changed, 29 insertions(+), 114 deletions(-) delete mode 100644 development_behavior_packs/NIA_V4.0_BP/scripts/API/scoreboard.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 7069d3a..fcde991 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,53 +5,25 @@ **版本说明:本次script-api出现部分变动,与老版本不相兼容,请及时更新本版本!** -## 适配 - -BDS && Minecraft BedRock-1.20.10.02 - -Liteloader 2.14.1 - ## 新增 -1.全新的NIAHttpBOT!基于c++编写,相比旧方案内存占用更小,性能更好!(特别感谢[**@jiansyuan**](https://github.com/jiansyuan)在编写中给予的帮助!) +1.NIAHttpBOT新增部分API(具体使用方法请前往**NIA服务器官方文档站**查看) -2.玩家交易市场部分功能(制作中,预计将在v1.4.0发布正式版) +- `/CheckFile` +- `/RunCmd` +- `/WriteLineToFile` +- `/OverwriteFile` +- `/CheckDir` -已完成模块: +2.NIAHttpBOT新增配置文件 -- 玩家上线市场逻辑(服务器本地) -- 玩家上线物品依赖服务器存储数据 -- 玩家可以初步查看市场商品 +3.行为包现在可以自动检查是否为最新版本了 ## 优化 -1.由于qq机器人暂时不稳定,在找到稳定的解决方案前暂时停止qq机器人的使用 - -2.自本版本之后,**停止对NIA-Server-BOT的更新与维护**,转而使用全新的**NIAHttpBOT**实现对原有功能的替代。 - -3.飞行系统授权码算法优化 [**@jiansyuan**](https://github.com/jiansyuan) - -4.优化商城id生成逻辑 - -## 修复 - -1.商店系统&&回收系统无法正常购买&&回收的bug - -2.传送系统无法正常同意的bug - -3.转账系统无法正常使用的bug - -4.飞行系统无法正常验证的bug - -5.玩家上架物品时不填写详细项目仍可以正常上架的bug - -6.玩家上架物品不为物品最大数量时显示仍为最大数量的bug - -7.在部分情况下无法正常上架商品的bug - -8.每晚12点更新时传送指令的错误 +1.NIAHttpBOT部分情况下报错信息更加详细 -9.(llse)扫地机插件无法正常恢复被扫物品的bug +2.正式移除`NIA-Server-BOT`项目及其所有文件 **配置说明:您可以前往[NIA服务器官方文档站](https://docs.mcnia.top/zh-CN/deploy.html)查看具体部署过程!** diff --git a/NIAHttpBOT/src/NIAHttpBOT.cpp b/NIAHttpBOT/src/NIAHttpBOT.cpp index 2c5f957..4811396 100644 --- a/NIAHttpBOT/src/NIAHttpBOT.cpp +++ b/NIAHttpBOT/src/NIAHttpBOT.cpp @@ -78,7 +78,7 @@ int main() { UseCmd = par.getBool("UseCmd"); INFO("已成功读取配置文件!"); } - + INFO("NIAHttpBOT 已在 " + IPAddress + ":" + std::to_string(PORT) + " 上成功启动!"); INFO("项目地址:https://github.com/NIANIANKNIA/NIASERVER-V4/tree/main/NIAHttpBOT"); INFO("项目作者:@NIANIANKNIA @jiansyuan"); @@ -134,22 +134,20 @@ int main() { //创建新的文件 svr.Post("/CreateNewFile", [](const httplib::Request& req, httplib::Response& res) { INFO("接收到创建文件的请求! "); + res.status = 200; //解析字符串并创建一个json对象 rapidjson::Document NewFileData; NewFileData.Parse(req.body.c_str()); //判断是否解析成功 if (NewFileData.HasParseError()) { - res.status = 200; res.set_content("Data parsing failed", "text/plain"); return ; } if(!NewFileData.HasMember("fileName")){ - res.status = 200; res.set_content("The fileName key for the json object was not found! Please recheck and send again.", "text/plain"); return ; } if(!NewFileData.HasMember("fileContent")){ - res.status = 200; res.set_content("The fileContent key for the json object was not found! Please recheck and send again.", "text/plain"); return ; } @@ -163,7 +161,6 @@ int main() { // 检测${fileName}文件是否存在,如果不存在,就创建一个新的文件,并写入内容 std::ifstream file(fileName); if(file){ - res.status = 200; res.set_content("The target file already exists and cannot be regenerated.", "text/plain"); return ; } @@ -171,7 +168,6 @@ int main() { std::ofstream outFile(fileName); outFile << fileContent; outFile.close(); - res.status = 200; res.set_content("success", "text/plain"); file.close(); }); @@ -180,22 +176,20 @@ int main() { //创建新的json文件 svr.Post("/CreateNewJsonFile", [](const httplib::Request& req, httplib::Response& res) { INFO("接收到创建json文件的请求! "); + res.status = 200; //解析字符串并创建一个json对象 rapidjson::Document NewFileData; NewFileData.Parse(req.body.c_str()); //判断是否解析成功 if (NewFileData.HasParseError()) { - res.status = 200; res.set_content("Data parsing failed", "text/plain"); return ; } if(!NewFileData.HasMember("fileName")){ - res.status = 200; res.set_content("The fileName key for the json object was not found! Please recheck and send again.", "text/plain"); return ; } if(!NewFileData.HasMember("fileContent")){ - res.status = 200; res.set_content("The fileContent key for the json object was not found! Please recheck and send again.", "text/plain"); return ; } @@ -214,7 +208,6 @@ int main() { // 检测${fileName}文件是否存在,如果不存在,就创建一个新的文件,并写入内容 std::ifstream file(fileName); if(file){ - res.status = 200; res.set_content("The target file already exists and cannot be regenerated.", "text/plain"); return ; } @@ -222,7 +215,6 @@ int main() { std::ofstream out(fileName); out << buffer.GetString(); out.close(); - res.status = 200; res.set_content("success", "text/plain"); file.close(); }); @@ -230,13 +222,13 @@ int main() { //获取json文件数据 svr.Post("/GetJsonFileData", [](const httplib::Request& req, httplib::Response& res) { INFO("接收到获取文件数据的请求,请求获取的文件名称为: " << req.body); + res.status = 200; //初始化文件名称 std::string fileName = req.body; //判断文件存不存在 std::ifstream file(fileName); if(!file) { //文件打开失败 - res.status = 200; res.set_content("The target file does not exist", "text/plain"); return ; } @@ -251,7 +243,6 @@ int main() { rapidjson::Writer writer(buffer); doc.Accept(writer); std::string jsonStr = buffer.GetString(); - res.status = 200; res.set_content(jsonStr, "text/plain"); file.close(); }); @@ -259,22 +250,20 @@ int main() { //覆盖json文件内容 svr.Post("/OverwriteJsonFile", [](const httplib::Request& req, httplib::Response& res) { INFO("接收到覆写json文件的请求!"); + res.status = 200; //解析字符串并创建一个json对象 rapidjson::Document overWriteFileData; overWriteFileData.Parse(req.body.c_str()); //判断是否解析成功 if (overWriteFileData.HasParseError()) { - res.status = 200; res.set_content("Data parsing failed", "text/plain"); return ; } if(!overWriteFileData.HasMember("fileName")){ - res.status = 200; res.set_content("The fileName key for the json object was not found! Please recheck and send again.", "text/plain"); return ; } if(!overWriteFileData.HasMember("fileData")){ - res.status = 200; res.set_content("The fileData key for the json object was not found! Please recheck and send again.", "text/plain"); return ; } @@ -293,14 +282,12 @@ int main() { // 检测${fileName}文件是否存在,如果不存在,就创建一个新的文件,并写入内容 std::ifstream file(fileName); if(!file) { - res.status = 200; res.set_content("The target file does not exist.", "text/plain"); return ; } std::ofstream out(fileName); out << buffer.GetString(); out.close(); - res.status = 200; res.set_content("success", "text/plain"); file.close(); @@ -308,39 +295,36 @@ int main() { //执行cmd命令 svr.Post("/RunCmd", [](const httplib::Request& req, httplib::Response& res) { + res.status = 200; //首先判断配置文件是否启用 if (!UseCmd) { WARN("执行DOS命令的功能暂未启用!请在启用后使用!"); - res.status = 200; res.set_content("feature not enabled!", "text/plain"); return ; } std::string cmd = req.body; WARN("收到一条执行DOS命令的请求:" + cmd); system(cmd.c_str()); - res.status = 200; res.set_content("success", "text/plain"); }); //向目标文件写入一行内容 svr.Post("/WriteLineToFile", [](const httplib::Request& req, httplib::Response& res) { INFO("接收到向目标文件写入一行内容的请求!"); + res.status = 200; //解析字符串并创建一个json对象 rapidjson::Document WriteLineData; WriteLineData.Parse(req.body.c_str()); //判断是否解析成功 if (WriteLineData.HasParseError()) { - res.status = 200; res.set_content("Data parsing failed", "text/plain"); return ; } if(!WriteLineData.HasMember("fileName")){ - res.status = 200; res.set_content("The fileName key for the json object was not found! Please recheck and send again.", "text/plain"); return ; } if(!WriteLineData.HasMember("content")){ - res.status = 200; res.set_content("The content key for the json object was not found! Please recheck and send again.", "text/plain"); return ; } @@ -353,7 +337,6 @@ int main() { // 检测${fileName}文件是否存在,如果不存在,就创建一个新的文件,并写入内容 std::ifstream file(fileName); if(!file) { - res.status = 200; res.set_content("The target file does not exist.", "text/plain"); return ; } @@ -361,7 +344,6 @@ int main() { std::ofstream outFile(fileName, std::ios_base::app); outFile << fileContent; outFile.close(); - res.status = 200; res.set_content("success", "text/plain"); file.close(); }); @@ -369,22 +351,20 @@ int main() { //向目标文件覆盖内容 svr.Post("/OverwriteFile", [](const httplib::Request& req, httplib::Response& res) { INFO("接收到覆写文件的请求!"); + res.status = 200; //解析字符串并创建一个json对象 rapidjson::Document OverwriteFileData; OverwriteFileData.Parse(req.body.c_str()); //判断是否解析成功 if (OverwriteFileData.HasParseError()) { - res.status = 200; res.set_content("Data parsing failed", "text/plain"); return ; } if(!OverwriteFileData.HasMember("fileName")){ - res.status = 200; res.set_content("The fileName key for the json object was not found! Please recheck and send again.", "text/plain"); return ; } if(!OverwriteFileData.HasMember("content")){ - res.status = 200; res.set_content("The content key for the json object was not found! Please recheck and send again.", "text/plain"); return ; } @@ -397,7 +377,6 @@ int main() { // 检测${fileName}文件是否存在 std::ifstream file(fileName); if(!file) { - res.status = 200; res.set_content("The target file does not exist.", "text/plain"); return ; } @@ -405,19 +384,17 @@ int main() { std::ofstream outFile(fileName); outFile << fileContent; outFile.close(); - res.status = 200; res.set_content("success", "text/plain"); file.close(); }); //检测指定文件夹是否存在 svr.Post("/CheckDir", [](const httplib::Request& req, httplib::Response& res) { + res.status = 200; std::filesystem::path p{req.body}; if (std::filesystem::exists(p)) { - res.status = 200; res.set_content("true", "text/plain"); } else { - res.status = 200; res.set_content("false", "text/plain"); } }); diff --git a/development_behavior_packs/NIA_V4.0_BP/scripts/API/scoreboard.js b/development_behavior_packs/NIA_V4.0_BP/scripts/API/scoreboard.js deleted file mode 100644 index e69de29..0000000 diff --git a/development_behavior_packs/NIA_V4.0_BP/scripts/config.js b/development_behavior_packs/NIA_V4.0_BP/scripts/config.js index eaa8f05..0963441 100644 --- a/development_behavior_packs/NIA_V4.0_BP/scripts/config.js +++ b/development_behavior_packs/NIA_V4.0_BP/scripts/config.js @@ -1,6 +1,3 @@ -//这里是配置文件,你可以根据自己的需求更改相应的配置项目 -//配置文件每一项的详细作用前往 https://docs.mcnia.top/zh-CN/deploy.html 查看 -//当前配置文件版本号;v1.0.0 const config = { "ServerMode": "Island", @@ -16,7 +13,12 @@ const config = { "CX": 402, "CY": 100, "CZ": 547 + }, + "HttpCfg": { + "IPAddress": "http://127.0.0.1", + "Port": 10086 } } + export const cfg = config \ No newline at end of file diff --git a/development_behavior_packs/NIA_V4.0_BP/scripts/customFunction.js b/development_behavior_packs/NIA_V4.0_BP/scripts/customFunction.js index 619224c..4d9ec37 100644 --- a/development_behavior_packs/NIA_V4.0_BP/scripts/customFunction.js +++ b/development_behavior_packs/NIA_V4.0_BP/scripts/customFunction.js @@ -51,6 +51,7 @@ export function AddScoreboard(scoreboardName,showName) { export function GetTime() { //创建一个Date对象 let nowTime = new Date() + //这里是或得北京时间 let addedTime = new Date(nowTime.getTime() + 28800000); //获取年份 let year = addedTime.getFullYear (); @@ -99,31 +100,14 @@ export function GetScore(scoreboardName,targets) { } -// function getNumberInNormalDistribution(mean,std_dev){ -// return mean+(uniform2NormalDistribution()*std_dev); -// } - -// function uniform2NormalDistribution(){ -// var sum=0.0; -// for(var i=0; i<12; i++){ -// sum=sum+Math.random(); -// } -// return sum-6.0; -// } - function randomNormalDistribution(){ var u=0.0, v=0.0, w=0.0, c=0.0; do{ - //获得两个(-1,1)的独立随机变量 u=Math.random()*2-1.0; v=Math.random()*2-1.0; w=u*u+v*v; }while(w==0.0||w>=1.0) - //这里就是 Box-Muller转换 c=Math.sqrt((-2*Math.log(w))/w); - //返回2个标准正态分布的随机数,封装进一个数组返回 - //当然,因为这个函数运行较快,也可以扔掉一个 - //return [u*c,v*c]; return u*c; } diff --git a/development_behavior_packs/NIA_V4.0_BP/scripts/main.js b/development_behavior_packs/NIA_V4.0_BP/scripts/main.js index 0de5ca2..062cb02 100644 --- a/development_behavior_packs/NIA_V4.0_BP/scripts/main.js +++ b/development_behavior_packs/NIA_V4.0_BP/scripts/main.js @@ -268,30 +268,6 @@ system.runInterval(() => { // RunCmd(`tag ${playerList[i].nameTag} remove GetIsland`) // } - // Broadcast(`§c[NKillHacker]§r\nspeed:${((Math.pow(playerList[i].velocity.x,2) + Math.pow(playerList[i].velocity.y,2) + Math.pow(playerList[i].velocity.z,2))).toFixed(5)} \npos:${playerList[i].location.x.toFixed(4)} ${playerList[i].location.y.toFixed(4)} ${playerList[i].location.z.toFixed(4)}`) - // let pos = {} - // if (posData[playerList[i].nameTag]) { - // //Broadcast((Math.pow(playerList[i].location.x.toFixed(4) - posData[playerList[i].nameTag].x,2) + Math.pow(playerList[i].location.y.toFixed(4) - posData[playerList[i].nameTag].y,2) + Math.pow(playerList[i].location.z.toFixed(4) - posData[playerList[i].nameTag].z,2)).toString()) - // if (((Math.pow(playerList[i].velocity.x,2) + Math.pow(playerList[i].velocity.y,2) + Math.pow(playerList[i].velocity.z,2))) >= 0.045 && (Math.pow(playerList[i].location.x.toFixed(4) - posData[playerList[i].nameTag].x,2) + Math.pow(playerList[i].location.y.toFixed(4) - posData[playerList[i].nameTag].y,2) + Math.pow(playerList[i].location.z.toFixed(4) - posData[playerList[i].nameTag].z,2)) <= 0.5) { - // world.getDimension("overworld").runCommandAsync(`tellraw @a[tag=op] {\"rawtext\":[{\"text\":\"§c>> 疑似 §e${playerList[i].nameTag} §c正在使用自由视角,如果本消息短期多次出现建议前往查看!注意:本消息可能是个误判!以下为该玩家的异常数据§r\nspeed:${((Math.pow(playerList[i].velocity.x,2) + Math.pow(playerList[i].velocity.y,2) + Math.pow(playerList[i].velocity.z,2))).toFixed(3)} \npos:${playerList[i].location.x.toFixed(3)} ${playerList[i].location.y.toFixed(3)} ${playerList[i].location.z.toFixed(3)}\ndistance:${(Math.pow(playerList[i].location.x.toFixed(4) - posData[playerList[i].nameTag].x,2) + Math.pow(playerList[i].location.y.toFixed(4) - posData[playerList[i].nameTag].y,2) + Math.pow(playerList[i].location.z.toFixed(4) - posData[playerList[i].nameTag].z,2)).toFixed(3).toString()}\"}]}`); - // posData[playerList[i].nameTag].num++ - // if (posData[playerList[i].nameTag].num >= 8) { - // posData[playerList[i].nameTag].num = 0 - // RunCmd(`ban ${playerList[i].nameTag} 1 违规使用自由视角(灵魂出窍)`) - // } - // //RunCmd(`ban ${playerList[i].nameTag} 1 违规使用自由视角(灵魂出窍)`) - // } - // posData[playerList[i].nameTag].x = playerList[i].location.x.toFixed(4) - // posData[playerList[i].nameTag].y = playerList[i].location.y.toFixed(4) - // posData[playerList[i].nameTag].z = playerList[i].location.z.toFixed(4) - // } else { - // //Broadcast("1") - // pos.num = 0 - // pos.x = playerList[i].location.x.toFixed(4) - // pos.y = playerList[i].location.y.toFixed(4) - // pos.z = playerList[i].location.z.toFixed(4) - // posData[playerList[i].nameTag] = pos - // } if ((Math.pow(playerList[i].getVelocity().x,2) + Math.pow(playerList[i].getVelocity().y,2) + Math.pow(playerList[i].getVelocity().z,2)) > 0.07 && GetScore("equLevel",playerList[i].nameTag) <= 10) { RunCmd(`scoreboard players add @e[name="${playerList[i].nameTag}",type=player] oxygen -1`); } diff --git a/development_behavior_packs/NIA_V4.0_BP/scripts/market.js b/development_behavior_packs/NIA_V4.0_BP/scripts/market.js index ecc56c6..9d5c507 100644 --- a/development_behavior_packs/NIA_V4.0_BP/scripts/market.js +++ b/development_behavior_packs/NIA_V4.0_BP/scripts/market.js @@ -134,6 +134,10 @@ const MarketGUI = { }) }, + Preview(player) { + + }, + //上架商品菜单 Shelf(player) { let InventoryData = ["-无-"]