From e3f6579193c8ab6461ea6cb13dc356cbb28008ad Mon Sep 17 00:00:00 2001 From: Cai <13110818005@qq.com> Date: Fri, 3 May 2024 16:42:30 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=EF=BC=9AHelpPlus=20=E6=9B=B4=E5=A5=BD=E7=9A=84=E5=B8=AE?= =?UTF-8?q?=E5=8A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HelpPlus/Conifg.cs | 256 ++++++++++++++++++++++++++++++++++++++ HelpPlus/Help.cs | 260 +++++++++++++++++++++++++++++++++++++++ HelpPlus/HelpPlus.csproj | 13 ++ HelpPlus/README.md | 14 +++ 4 files changed, 543 insertions(+) create mode 100644 HelpPlus/Conifg.cs create mode 100644 HelpPlus/Help.cs create mode 100644 HelpPlus/HelpPlus.csproj create mode 100644 HelpPlus/README.md diff --git a/HelpPlus/Conifg.cs b/HelpPlus/Conifg.cs new file mode 100644 index 000000000..3e43bdbd1 --- /dev/null +++ b/HelpPlus/Conifg.cs @@ -0,0 +1,256 @@ +using System; +using System.Drawing; +using System.IO; +using Newtonsoft.Json; +using TShockAPI; +using TShockAPI.DB; +using Region = TShockAPI.DB.Region; + +namespace UserCheck +{ + public class Config + { + public const string Path = "tshock/HelpPlus.json"; + + public static Config config = new Config(); + public Config() + { + + ShortCommands = new Dictionary + { + { "user", "用户管理" }, + { "login", "登录" }, + { "logout", "登出" }, + { "password", "修改密码" }, + { "register", "注册" }, + { "accountinfo", "账号信息" }, + { "ban", "封禁" }, + { "broadcast", "广播" }, + { "displaylogs", "显示日志" }, + { "group", "组管理" }, + { "itemban", "物品封禁" }, + { "projban", "弹幕封禁" }, + { "tileban", "图格封禁" }, + { "su", "临时超管" }, + { "sudo", "以超管权限运行" }, + { "userinfo", "玩家信息" }, + { "region", "区域管理" }, + { "kick", "踢" }, + { "mute", "禁言" }, + { "overridessc", "覆盖SSC" }, + { "savessc", "保存SSC" }, + { "uploadssc","上传SSC"}, + { "tempgroup", "临时组" }, + { "annoy", "打扰" }, + { "rocket", "上天" }, + { "firework", "烟火" }, + { "checkupdates", "检查更新" }, + { "off", "关服并保存" }, + { "off-nosave", "关服不保存" }, + { "reload", "重载配置" }, + { "serverpassword", "服务器密码" }, + { "version", "版本" }, + { "whitelist", "白名单" }, + { "give", "给物品" }, + { "item", "给自己物品" }, + { "butcher", "击杀生物" }, + { "renamenpc", "重命名城镇NPC" }, + { "maxspawns", "单人最大刷怪" }, + { "spawnboss", "召唤BOSS" }, + { "spawnmob", "召唤生物" }, + { "spawnrate", "刷怪间隔" }, + { "clearangler", "重置渔夫任务" }, + { "home", "回家" }, + { "spawn", "传送至世界出生点" }, + { "tp", "传送" }, + { "tphere", "传送玩家至身边" }, + { "tpnpc", "传送至生物" }, + { "tppos", "传送至坐标" }, + { "pos", "显示坐标" }, + { "tpallow", "传送保护" }, + { "worldmode", "修改世界难度" }, + { "antibuild", "建筑保护" }, + { "grow", "种植" }, + { "forcehalloween", "强制万圣节" }, + { "forcexmas", "强制圣诞节" }, + { "worldevent", "事件" }, + { "hardmode", "切换困难模式" }, + { "protectspawn", "出生点保护" }, + { "save", "保存世界" }, + { "setspawn", "设置世界出生点" }, + { "setdungeon", "设置地牢" }, + { "settle", "平衡液体" }, + { "time", "时间" }, + { "wind", "风速" }, + { "worldinfo", "地图信息" }, + { "buff", "给自己Buff" }, + { "clear", "清理" }, + { "gbuff", "给BUFF" }, + { "godmode", "上帝模式" }, + { "heal", "治疗" }, + { "kill", "杀死" }, + { "me", "发送消息" }, + { "party", "队内消息" }, + { "reply", "回复私聊" }, + { "rest", "REST管理" }, + { "slap", "伤害" }, + { "serverinfo", "服务器信息" }, + { "warp", "传送点" }, + { "whisper", "私聊" }, + { "wallow", "私聊保护" }, + { "dump-reference-data", "生成帮助文档" }, + { "sync", "同步" }, + { "respawn", "复活" }, + { "aliases", "命令别名" }, + { "help", "帮助" }, + { "motd", "进服提示" }, + { "playing", "在线人数" }, + { "rules", "规则" }, + + { "分界线", "下面是Cai自己服务器的命令" }, + + // { " + // ", "重置" }, + { "rs", "重置设置" }, + { "ghost", "幽灵模式" }, + { "maxplayers", "最大玩家数" }, + { "runas", "以某用户执行" }, + { "exportcharacter", "导出角色" }, + { "whynot", "权限查询" }, + { "setlang", "设置语言" }, + { "resetcharacte", "重置玩家角色" }, + { "searchitem", "查找物品" }, + { "searchchest", "查找箱子" }, + { "tpchest", "传送至箱子" }, + { "chestinfo", "箱子信息" }, + { "tpall", "传送至所有人" }, + { "tpallchest", "传送至所有箱子" }, + { "removechestitem", "移除箱子物品" }, + { "removeitem", "移除玩家物品" }, + { "key", "钥匙兑换" }, + { "load", "插件热重载" }, + { "statustext", "计分板开关" }, + { "veinminer", "连锁挖矿" }, + { "replen", "资源补充" }, + { "replenreload", "重载资源补充" }, + { "lookbag", "查背包" }, + { "playermanager", "玩家管理" }, + { "vote", "投票" }, + { "worldmodify", "地图修改" }, + { "moonphase", "月相" }, + { "moonstyle", "月亮样式" }, + { "bossmanage", "BOSS管理" }, + { "npcmanage", "NPC管理" }, + { "creativemode", "创造模式" }, + { "generatemap", "生成地图图片" }, + { "history", "图格历史" }, + { "prunehist", "还原图格" }, + { "reenact", "撤销" }, + { "rollback", "还原玩家修改" }, + { "tpahere", "请求传送玩家至身边" }, + { "tpa", "请求传送" }, + { "back", "回到死亡点" }, + { "permabuff", "永久BUFF" }, + { "buffcheck", "列出永久BUFF" }, + { "gpermabuff", "给永久BUFF" }, + { "regionbuff", "区域BUFF" }, + { "globalbuff", "全局BUFF" }, + { "clearbuffs", "移除永久BUFF" }, + { "scommand", "查命令" }, + { "sperm", "查权限" }, + { "sgcommand", "查命令可用组" }, + { "pluginlist", "查非TShock权限" }, + { "invsee", "修改背包" }, + { "house", "圈地" }, + { "分界线2", "常用插件" }, + { "query", "查询货币" }, + { "es", "倍率设置" }, + { "bank", "银行" }, + { "level", "等级设置" }, + { "rank", "升级" }, + { "reset", "重置职业" }, + { "skill", "技能" }, + { "task", "任务" }, + { "pco", "计划书" }, + { "plus", "强化武器" }, + { "clearallplayersplus", "重置强化武器" }, + { "zhelp", "ZPM帮助" }, + { "zsave", "备份存档" }, + { "zvisa", "查看存档" }, + { "zsaveauto", "自动备份" }, + { "zback", "回档" }, + { "zclone", "克隆存档" }, + { "zmodify", "修改玩家" }, + { "zfre", "冻结玩家" }, + { "zunfre", "解冻玩家" }, + { "zresetdb", "删除玩家备份" }, + { "zresetex", "重置额外数据" }, + { "zreset", "重置角色" }, + { "zresetallplayers", "重置所有角色" }, + { "vi", "查背包(排序)" }, + { "vid", "查背包" }, + { "vs", "查状态" }, + { "zsort", "排行" }, + { "zban", "封禁" }, + { "zhide", "隐藏弹字" }, + { "zclear", "清理" }, + { "shop", "商店" }, + { "deal", "交易" }, + { "igen", "快速构建" }, + { "relive", "复活NPC" }, + { "bossinfo", "进度查询" }, + { "zout", "导出存档" } + }; + } + public void Write(string path = Path) + { + using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write)) + { + this.Write(fileStream); + } + } + + public void Write(Stream stream) + { + string value = JsonConvert.SerializeObject(this, Formatting.Indented); + using (StreamWriter streamWriter = new StreamWriter(stream)) + { + streamWriter.Write(value); + } + } + + public static Config Read(string path = Path) + { + bool flag = !File.Exists(path); + Config result; + if (flag) + { + result = new Config(); + result.Write(path); + } + else + { + using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + result = Config.Read(fileStream); + } + } + config = result; + return result; + } + + public static Config Read(Stream stream) + { + Config result; + using (StreamReader streamReader = new StreamReader(stream)) + { + result = JsonConvert.DeserializeObject(streamReader.ReadToEnd()); + } + return result; + } + [JsonProperty("简短提示开关")] + public bool DisPlayShort = true; + [JsonProperty("简短提示对应")] + public Dictionary ShortCommands = new Dictionary(); + } +} diff --git a/HelpPlus/Help.cs b/HelpPlus/Help.cs new file mode 100644 index 000000000..c210dcfd9 --- /dev/null +++ b/HelpPlus/Help.cs @@ -0,0 +1,260 @@ +using Terraria; +using TerrariaApi.Server; +using TShockAPI; +using Terraria.DataStructures; +using IL.Terraria.ID; +using IL.Terraria.Chat.Commands; +using Microsoft.Xna.Framework; +using System.Timers; +using On.OTAPI; +using static MonoMod.InlineRT.MonoModRule; +using MonoMod.RuntimeDetour; +using Terraria.Localization; +using System.Diagnostics; +using Terraria.Chat; +using static System.Net.Mime.MediaTypeNames; +using System.Text; +using MySqlX.XDevAPI; +using TShockAPI.Hooks; + +namespace UserCheck +{ + [ApiVersion(2, 1)] + public class HelpPlus : TerrariaPlugin + { + + public override string Author => "Cai"; + + public override string Description => "更好的Help"; + + public override string Name => "Help+(更好的Help)"; + public override Version Version => new Version(1, 0, 0, 0); + + public HelpPlus(Main game) + : base(game) + { + Order = int.MaxValue; + } + Command Command = new Command(Help, "help"); + public override void Initialize() + { + GeneralHooks.ReloadEvent += GeneralHooks_ReloadEvent; + On.OTAPI.Hooks.MessageBuffer.InvokeGetData += MessageBuffer_InvokeGetData; + Commands.ChatCommands.RemoveAll(x => x.Name == "help"); + Commands.ChatCommands.Add(Command); + Config.Read(); + + } + + private void GeneralHooks_ReloadEvent(ReloadEventArgs e) + { + Config.Read(); + e.Player.SendSuccessMessage("[HelpPlus]插件配置已重载!"); + } + + private static bool IsWhiteSpace(char c) + { + return c == ' ' || c == '\t' || c == '\n'; + } + private static List ParseParameters(string str) + { + var ret = new List(); + var sb = new StringBuilder(); + bool instr = false; + for (int i = 0; i < str.Length; i++) + { + char c = str[i]; + + if (c == '\\' && ++i < str.Length) + { + if (str[i] != '"' && str[i] != ' ' && str[i] != '\\') + sb.Append('\\'); + sb.Append(str[i]); + } + else if (c == '"') + { + instr = !instr; + if (!instr) + { + ret.Add(sb.ToString()); + sb.Clear(); + } + else if (sb.Length > 0) + { + ret.Add(sb.ToString()); + sb.Clear(); + } + } + else if (IsWhiteSpace(c) && !instr) + { + if (sb.Length > 0) + { + ret.Add(sb.ToString()); + sb.Clear(); + } + } + else + sb.Append(c); + } + if (sb.Length > 0) + ret.Add(sb.ToString()); + + return ret; + } + private bool MessageBuffer_InvokeGetData(Hooks.MessageBuffer.orig_InvokeGetData orig, MessageBuffer instance, ref byte packetId, ref int readOffset, ref int start, ref int length, ref int messageType, int maxPackets) + { + //Console.WriteLine(1); + if (messageType == 82) + { + + instance.ResetReader(); + instance.reader.BaseStream.Position = start + 1; + + ushort moduleId = instance.reader.ReadUInt16(); + //LoadNetModule is now used for sending chat text. + //Read the module ID to determine if this is in fact the text module + if (moduleId == Terraria.Net.NetManager.Instance.GetId()) + { + //Then deserialize the message from the reader + Terraria.Chat.ChatMessage msg = Terraria.Chat.ChatMessage.Deserialize(instance.reader); + if (msg.CommandId._name != "Help") + { + return orig(instance, ref packetId, ref readOffset, ref start, ref length, ref messageType, maxPackets); + } + TSPlayer player = TShock.Players[instance.whoAmI]; + string text = "/help "+ msg.Text; + string Specifier = TShock.Config.Settings.CommandSpecifier; + string cmdText = text.Remove(0, 1); + string cmdPrefix = text[0].ToString(); + int index = -1; + for (int i = 0; i < cmdText.Length; i++) + { + if (IsWhiteSpace(cmdText[i])) + { + index = i; + break; + } + } + //player.Account.VerifyPassword("114514"); + string cmdName; + if (index < 0) + cmdName = cmdText.ToLower(); + else + cmdName = cmdText.Substring(0, index).ToLower(); + + List args; + if (index < 0) + args = new List(); + else + args = ParseParameters(cmdText.Substring(index)); + if (cmdName == "help") + { + Help(new CommandArgs(null, false, player, args)); + TShock.Utils.SendLogs($"{player.Name}执行了/{cmdText}。" ,Color.PaleVioletRed, player); + return false; + } + + } + } + + + return orig(instance, ref packetId, ref readOffset, ref start, ref length, ref messageType, maxPackets); + } + private static void Help(CommandArgs args) + { + string Specifier = TShock.Config.Settings.CommandSpecifier; + if (args.Parameters.Count > 1) + { + args.Player.SendErrorMessage(string.Format("无效用法.正确用法: {0}help <命令/页码>", Specifier)); + return; + } + + int pageNumber; + if (args.Parameters.Count == 0 || int.TryParse(args.Parameters[0], out pageNumber)) + { + if (!PaginationTools.TryParsePageNumber(args.Parameters, 0, args.Player, out pageNumber)) + { + return; + } + + IEnumerable cmdNames = from cmd in TShockAPI.Commands.ChatCommands + where cmd.CanRun(args.Player) && (cmd.Name != "setup" || TShock.SetupToken != 0) + select Specifier + cmd.Name+GetShort(cmd.Name); + + PaginationTools.SendPage(args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(cmdNames), + new PaginationTools.Settings + { + HeaderFormat = string.Format("命令列表 ({{0}}/{{1}}):"), + FooterFormat = string.Format("输入 {0}help {{0}} 翻页.", Specifier) + }); + } + else + { + string commandName = args.Parameters[0].ToLower(); + if (commandName.StartsWith(Specifier)) + { + commandName = commandName.Substring(1); + } + + Command command = TShockAPI.Commands.ChatCommands.Find(c => c.Names.Contains(commandName)); + if (command == null) + { + args.Player.SendErrorMessage(string.Format("无效命令.")); + return; + } + if (!command.CanRun(args.Player)) + { + args.Player.SendErrorMessage(string.Format("你没有权限查询此命令.")); + return; + } + + args.Player.SendSuccessMessage(string.Format("{0}{1}的帮助:", Specifier, command.Name)); + if (command.HelpDesc == null) + { + args.Player.SendWarningMessage(command.HelpText); + + } + else + { + foreach (string line in command.HelpDesc) + { + args.Player.SendInfoMessage(line); + } + } + if (command.Names.Count > 1) + args.Player.SendInfoMessage($"别名: [c/00ffff:{string.Join(',', command.Names)}]"); + args.Player.SendInfoMessage($"权限: {(command.Permissions.Count == 0||command.Permissions.Count(i=>i=="")==command.Permissions.Count ? "[c/c2ff39:无权限限制]" : "[c/bf0705:"+string.Join(',', command.Permissions)+"]")}"); + args.Player.SendInfoMessage($"来源插件: [c/8500ff:{command.CommandDelegate.Method.DeclaringType.Assembly.FullName.Split(',').First()}]"); + if (!command.AllowServer) + args.Player.SendInfoMessage("*此命令只能游戏内执行"); + if (!command.DoLog) + args.Player.SendInfoMessage("*此命令不记录命令参数"); + } + } + + public static string GetShort(string str) + { + if (Config.config.DisPlayShort && Config.config.ShortCommands.ContainsKey(str)) + { + return $"({Config.config.ShortCommands[str].Color(TShockAPI.Utils.BoldHighlight)})"; + + } + else + { + return ""; + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + On.OTAPI.Hooks.MessageBuffer.InvokeGetData -= MessageBuffer_InvokeGetData; + GeneralHooks.ReloadEvent-= GeneralHooks_ReloadEvent; + } + base.Dispose(disposing); + } + + + } +} diff --git a/HelpPlus/HelpPlus.csproj b/HelpPlus/HelpPlus.csproj new file mode 100644 index 000000000..f041a9b95 --- /dev/null +++ b/HelpPlus/HelpPlus.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/HelpPlus/README.md b/HelpPlus/README.md new file mode 100644 index 000000000..6ee5d25e8 --- /dev/null +++ b/HelpPlus/README.md @@ -0,0 +1,14 @@ +# HelpPlus (更好的帮助) + +---------- +## 安装方法: + +**1.将插件安装在ServerPlugins/ +2.重启服务器** + + +-------- +## 功能: +**•修复/help指令无法使用的问题 +•为/help添加简短提示 +•为/help <命令> 可以看见更详细的命令帮助** \ No newline at end of file From 195f5955d412794af19918dbb86d9b170e79ce8f Mon Sep 17 00:00:00 2001 From: Cai <13110818005@qq.com> Date: Fri, 3 May 2024 16:43:39 +0800 Subject: [PATCH 2/3] =?UTF-8?q?HelpPlus=EF=BC=9A=E5=B0=8F=E4=BF=AE?= =?UTF-8?q?=E5=B0=8F=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HelpPlus/HelpPlus.csproj | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/HelpPlus/HelpPlus.csproj b/HelpPlus/HelpPlus.csproj index f041a9b95..9c9fc71b0 100644 --- a/HelpPlus/HelpPlus.csproj +++ b/HelpPlus/HelpPlus.csproj @@ -1,13 +1,3 @@ - - - net6.0 - enable - enable - - - - - - + From 0e156a9afc92f6f4fabda12c733cde36a4041f40 Mon Sep 17 00:00:00 2001 From: Cai <13110818005@qq.com> Date: Fri, 3 May 2024 16:46:57 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BB=8Esln=E4=B8=AD=E6=B7=BB=E5=8A=A0Help?= =?UTF-8?q?Plus.csproj?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plugin.sln | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Plugin.sln b/Plugin.sln index 874d14ed4..d93f01550 100644 --- a/Plugin.sln +++ b/Plugin.sln @@ -130,7 +130,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Platform", "Platform\Platfo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CaiLib", "CaiLib\CaiLib.csproj", "{3B98CF6B-A295-485C-8ABC-64388BA995BE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenerateMap", "GenerateMap\GenerateMap.csproj", "{70B2E6F1-D38D-406F-BFBD-98301AE327CA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelpPlus", "HelpPlus\HelpPlus.csproj", "{B744AA76-F785-4E85-8C68-450758FD55D0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -628,14 +628,14 @@ Global {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Release|Any CPU.Build.0 = Release|Any CPU {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Release|x64.ActiveCfg = Release|Any CPU {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Release|x64.Build.0 = Release|Any CPU - {70B2E6F1-D38D-406F-BFBD-98301AE327CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {70B2E6F1-D38D-406F-BFBD-98301AE327CA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {70B2E6F1-D38D-406F-BFBD-98301AE327CA}.Debug|x64.ActiveCfg = Debug|Any CPU - {70B2E6F1-D38D-406F-BFBD-98301AE327CA}.Debug|x64.Build.0 = Debug|Any CPU - {70B2E6F1-D38D-406F-BFBD-98301AE327CA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {70B2E6F1-D38D-406F-BFBD-98301AE327CA}.Release|Any CPU.Build.0 = Release|Any CPU - {70B2E6F1-D38D-406F-BFBD-98301AE327CA}.Release|x64.ActiveCfg = Release|Any CPU - {70B2E6F1-D38D-406F-BFBD-98301AE327CA}.Release|x64.Build.0 = Release|Any CPU + {B744AA76-F785-4E85-8C68-450758FD55D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B744AA76-F785-4E85-8C68-450758FD55D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B744AA76-F785-4E85-8C68-450758FD55D0}.Debug|x64.ActiveCfg = Debug|Any CPU + {B744AA76-F785-4E85-8C68-450758FD55D0}.Debug|x64.Build.0 = Debug|Any CPU + {B744AA76-F785-4E85-8C68-450758FD55D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B744AA76-F785-4E85-8C68-450758FD55D0}.Release|Any CPU.Build.0 = Release|Any CPU + {B744AA76-F785-4E85-8C68-450758FD55D0}.Release|x64.ActiveCfg = Release|Any CPU + {B744AA76-F785-4E85-8C68-450758FD55D0}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE