Discord模拟器开发:读取JSON匹配PassiveName并加载对应成员数据
解决Discord斜杠命令中匹配JSON被动技能数据的问题
需求概述
开发了类似Dokkan模拟器的Discord斜杠命令,支持用户创建自定义被动技能。当前核心需求是:读取存储被动技能的JSON文件,根据用户输入的PassiveName字段匹配对应条目,加载完整数据用于后续属性计算。
现有代码
原读取JSON的代码可将内容存入列表,但无法实现匹配逻辑:
private void ReadJSONFile(string nameSearch) { List<object> Passives = new List<object>(); //临时存储JSON内容的列表 try { using (StreamReader sr = new StreamReader("UserPassivesStorage.json")) { string jsonFile = sr.ReadToEnd(); JSONObject100 jsonObject = JsonConvert.DeserializeObject<JSONObject100>(jsonFile); Passives.Add(jsonObject); for (int i = 0; i < jsonObject.members.Length; i++) { if (i < jsonObject.members.Length) { var data = jsonObject.members[i]; Passives.Add(data); } else { Console.Write("Error"); } } } } catch (Exception ex) { Console.WriteLine(ex); } }
JSON文件结构
存储被动技能的JSON示例:
{ "userPassiveStorage": "Storage for user created passives using /passivecreator", "members": [ { "UserName": "𝕤𝕒𝕞.𝕛𝕖𝕤𝕦𝕤𝟠", "PassiveName": "TEQ Gogeta", "UnitHP": 19199, "UnitATK": 20744, "UnitDEF": 10909, "UnitLeaderName": "Fusion", "UnitLeaderSkill": 170, "UnitPassiveATK": 200, "UnitPassiveDEF": 200, "Support": 0, "Links": "No Links Provided by the user" }, { "UserName": "𝕤𝕒𝕞.𝕛𝕖𝕤𝕦𝕤𝟠", "PassiveName": "AGL Gogeta", "UnitHP": 15745, "UnitATK": 16492, "UnitDEF": 11088, "UnitLeaderName": "Movie Heroes", "UnitLeaderSkill": 170, "UnitPassiveATK": 100, "UnitPassiveDEF": 100, "Support": 0, "Links": "No Links Provided by the user" } ] }
修改方案
1. 明确实体类定义
确保你的JSONObject100和成员类结构与JSON匹配(如果还没定义):
// 单个被动技能的实体类 public class PassiveMember { public string UserName { get; set; } public string PassiveName { get; set; } public int UnitHP { get; set; } public int UnitATK { get; set; } public int UnitDEF { get; set; } public string UnitLeaderName { get; set; } public int UnitLeaderSkill { get; set; } public int UnitPassiveATK { get; set; } public int UnitPassiveDEF { get; set; } public int Support { get; set; } public string Links { get; set; } } // 顶层JSON对象的实体类 public class JSONObject100 { public string userPassiveStorage { get; set; } public PassiveMember[] members { get; set; } }
2. 重写匹配方法
修改原方法,移除无用的List<object>,直接遍历并匹配PassiveName,返回匹配结果:
private PassiveMember FindMatchingPassive(string nameSearch) { try { // 简化文件读取,替代StreamReader string jsonContent = File.ReadAllText("UserPassivesStorage.json"); JSONObject100 passiveStorage = JsonConvert.DeserializeObject<JSONObject100>(jsonContent); // 遍历成员列表,匹配PassiveName(忽略大小写提升用户体验) foreach (var passive in passiveStorage.members) { if (string.Equals(passive.PassiveName, nameSearch, StringComparison.OrdinalIgnoreCase)) { return passive; // 返回匹配的完整数据 } } // 无匹配项时返回null return null; } catch (Exception ex) { Console.WriteLine($"处理JSON时出错: {ex.Message}"); return null; } }
3. 使用匹配结果
在命令逻辑中调用该方法,获取数据后执行后续计算:
// 用户输入的被动技能名称 string userInput = "TEQ Gogeta"; var matchedPassive = FindMatchingPassive(userInput); if (matchedPassive != null) { // 执行属性计算,示例:计算最终ATK int finalATK = matchedPassive.UnitATK * (100 + matchedPassive.UnitPassiveATK) / 100; Console.WriteLine($"匹配成功:{matchedPassive.PassiveName} | 最终ATK:{finalATK}"); } else { Console.WriteLine($"未找到名为「{userInput}」的被动技能"); }
关键优化点
- 移除无用的临时列表,直接操作反序列化后的实体对象,简化代码
- 加入忽略大小写的匹配逻辑,避免用户输入大小写差异导致匹配失败
- 修改方法返回值为
PassiveMember,直接返回匹配数据,方便后续业务逻辑调用 - 简化文件读取方式,使用
File.ReadAllText替代StreamReader,代码更简洁
内容的提问来源于stack exchange,提问作者user11057786
相关产品推荐
相关产品推荐

