diff --git a/OshimaModules/Items/Consumable/回复药.cs b/OshimaModules/Items/Consumable/回复药.cs index fa17cbb..1011956 100644 --- a/OshimaModules/Items/Consumable/回复药.cs +++ b/OshimaModules/Items/Consumable/回复药.cs @@ -35,7 +35,7 @@ namespace Oshima.FunGame.OshimaModules.Items return "此物品没有主动技能,无法被使用!"; } - public static bool OnItemUsed(User user, Item item, Dictionary args) + public static bool OnItemUsed(User user, Item item, int times, Dictionary args) { string msg = ""; bool result = false; @@ -55,16 +55,12 @@ namespace Oshima.FunGame.OshimaModules.Items } } args["msg"] = msg; - key = args.Keys.FirstOrDefault(s => s.Equals("useCount", StringComparison.CurrentCultureIgnoreCase)) ?? ""; - if (key != "" && args.TryGetValue(key, out value) && value is int count && targets.Length > 0) + string truemsg = $"对角色 [ {targets[0]} ] 使用 {times} 个 [ {item.Name} ] 成功!"; + if (item is HPRecovery expBook) { - string truemsg = $"对角色 [ {targets[0]} ] 使用 {count} 个 [ {item.Name} ] 成功!"; - if (item is HPRecovery expBook) - { - truemsg += $"回复了 {expBook.HP * count} 点生命值!"; - } - args["truemsg"] = truemsg; + truemsg += $"回复了 {expBook.HP * times} 点生命值!"; } + args["truemsg"] = truemsg; return result; } } @@ -83,9 +79,9 @@ namespace Oshima.FunGame.OshimaModules.Items 回复药.Init(this, HP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 回复药.OnItemUsed(user, this, args); + return 回复药.OnItemUsed(user, this, times, args); } } @@ -103,9 +99,9 @@ namespace Oshima.FunGame.OshimaModules.Items 回复药.Init(this, HP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 回复药.OnItemUsed(user, this, args); + return 回复药.OnItemUsed(user, this, times, args); } } @@ -123,9 +119,9 @@ namespace Oshima.FunGame.OshimaModules.Items 回复药.Init(this, HP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 回复药.OnItemUsed(user, this, args); + return 回复药.OnItemUsed(user, this, times, args); } } @@ -143,9 +139,9 @@ namespace Oshima.FunGame.OshimaModules.Items 回复药.Init(this, HP, remainUseTimes, true); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 回复药.OnItemUsed(user, this, args); + return 回复药.OnItemUsed(user, this, times, args); } } diff --git a/OshimaModules/Items/Consumable/复苏药.cs b/OshimaModules/Items/Consumable/复苏药.cs index c064c17..823e504 100644 --- a/OshimaModules/Items/Consumable/复苏药.cs +++ b/OshimaModules/Items/Consumable/复苏药.cs @@ -36,7 +36,7 @@ namespace Oshima.FunGame.OshimaModules.Items return "此物品没有主动技能,无法被使用!"; } - public static bool OnItemUsed(User user, Item item, Dictionary args) + public static bool OnItemUsed(User user, Item item, int times, Dictionary args) { string msg = ""; bool result = false; @@ -56,16 +56,12 @@ namespace Oshima.FunGame.OshimaModules.Items } } args["msg"] = msg; - key = args.Keys.FirstOrDefault(s => s.Equals("useCount", StringComparison.CurrentCultureIgnoreCase)) ?? ""; - if (key != "" && args.TryGetValue(key, out value) && value is int count && targets.Length > 0) + string truemsg = $"对角色 [ {targets[0]} ] 使用 {times} 个 [ {item.Name} ] 成功!"; + if (item is HPRecovery expBook) { - string truemsg = $"对角色 [ {targets[0]} ] 使用 {count} 个 [ {item.Name} ] 成功!"; - if (item is HPRecovery expBook) - { - truemsg += $"回复了 {expBook.HP * count} 点生命值!"; - } - args["truemsg"] = truemsg; + truemsg += $"回复了 {expBook.HP * times} 点生命值!"; } + args["truemsg"] = truemsg; return result; } } @@ -84,9 +80,9 @@ namespace Oshima.FunGame.OshimaModules.Items 复苏药.Init(this, HP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 复苏药.OnItemUsed(user, this, args); + return 复苏药.OnItemUsed(user, this, times, args); } } @@ -104,9 +100,9 @@ namespace Oshima.FunGame.OshimaModules.Items 复苏药.Init(this, HP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 复苏药.OnItemUsed(user, this, args); + return 复苏药.OnItemUsed(user, this, times, args); } } @@ -124,9 +120,9 @@ namespace Oshima.FunGame.OshimaModules.Items 复苏药.Init(this, HP, remainUseTimes, true); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 复苏药.OnItemUsed(user, this, args); + return 复苏药.OnItemUsed(user, this, times, args); } } diff --git a/OshimaModules/Items/Consumable/经验书.cs b/OshimaModules/Items/Consumable/经验书.cs index 6884bea..6ddc5b0 100644 --- a/OshimaModules/Items/Consumable/经验书.cs +++ b/OshimaModules/Items/Consumable/经验书.cs @@ -36,7 +36,7 @@ namespace Oshima.FunGame.OshimaModules.Items return "此物品没有主动技能,无法被使用!"; } - public static bool OnItemUsed(User user, Item item, Dictionary args) + public static bool OnItemUsed(User user, Item item, int times, Dictionary args) { string msg = ""; bool result = false; @@ -56,16 +56,12 @@ namespace Oshima.FunGame.OshimaModules.Items } } args["msg"] = msg; - key = args.Keys.FirstOrDefault(s => s.Equals("useCount", StringComparison.CurrentCultureIgnoreCase)) ?? ""; - if (key != "" && args.TryGetValue(key, out value) && value is int count && targets.Length > 0) + string truemsg = $"对角色 [ {targets[0]} ] 使用 {times} 个 [ {item.Name} ] 成功!"; + if (item is EXPBook expBook) { - string truemsg = $"对角色 [ {targets[0]} ] 使用 {count} 个 [ {item.Name} ] 成功!"; - if (item is EXPBook expBook) - { - truemsg += $"获得了 {expBook.EXP * count} 点经验值!"; - } - args["truemsg"] = truemsg; + truemsg += $"获得了 {expBook.EXP * times} 点经验值!"; } + args["truemsg"] = truemsg; return result; } } @@ -84,9 +80,9 @@ namespace Oshima.FunGame.OshimaModules.Items 经验书.Init(this, EXP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 经验书.OnItemUsed(user, this, args); + return 经验书.OnItemUsed(user, this, times, args); } } @@ -104,9 +100,9 @@ namespace Oshima.FunGame.OshimaModules.Items 经验书.Init(this, EXP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 经验书.OnItemUsed(user, this, args); + return 经验书.OnItemUsed(user, this, times, args); } } @@ -124,9 +120,9 @@ namespace Oshima.FunGame.OshimaModules.Items 经验书.Init(this, EXP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 经验书.OnItemUsed(user, this, args); + return 经验书.OnItemUsed(user, this, times, args); } } diff --git a/OshimaModules/Items/Consumable/能量饮料.cs b/OshimaModules/Items/Consumable/能量饮料.cs index abc9e76..99c1998 100644 --- a/OshimaModules/Items/Consumable/能量饮料.cs +++ b/OshimaModules/Items/Consumable/能量饮料.cs @@ -35,7 +35,7 @@ namespace Oshima.FunGame.OshimaModules.Items return "此物品没有主动技能,无法被使用!"; } - public static bool OnItemUsed(User user, Item item, Dictionary args) + public static bool OnItemUsed(User user, Item item, int times, Dictionary args) { string msg = ""; bool result = false; @@ -55,16 +55,12 @@ namespace Oshima.FunGame.OshimaModules.Items } } args["msg"] = msg; - key = args.Keys.FirstOrDefault(s => s.Equals("useCount", StringComparison.CurrentCultureIgnoreCase)) ?? ""; - if (key != "" && args.TryGetValue(key, out value) && value is int count && targets.Length > 0) + string truemsg = $"对角色 [ {targets[0]} ] 使用 {times} 个 [ {item.Name} ] 成功!"; + if (item is EPAdd expBook) { - string truemsg = $"对角色 [ {targets[0]} ] 使用 {count} 个 [ {item.Name} ] 成功!"; - if (item is EPAdd expBook) - { - truemsg += $"获得了 {expBook.EP * count} 点能量值!"; - } - args["truemsg"] = truemsg; + truemsg += $"获得了 {expBook.EP * times} 点能量值!"; } + args["truemsg"] = truemsg; return result; } } @@ -83,9 +79,9 @@ namespace Oshima.FunGame.OshimaModules.Items 能量饮料.Init(this, EP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 能量饮料.OnItemUsed(user, this, args); + return 能量饮料.OnItemUsed(user, this, times, args); } } @@ -103,9 +99,9 @@ namespace Oshima.FunGame.OshimaModules.Items 能量饮料.Init(this, EP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 能量饮料.OnItemUsed(user, this, args); + return 能量饮料.OnItemUsed(user, this, times, args); } } @@ -123,9 +119,9 @@ namespace Oshima.FunGame.OshimaModules.Items 能量饮料.Init(this, EP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 能量饮料.OnItemUsed(user, this, args); + return 能量饮料.OnItemUsed(user, this, times, args); } } diff --git a/OshimaModules/Items/Consumable/魔力填充剂.cs b/OshimaModules/Items/Consumable/魔力填充剂.cs index cb02887..1e005e2 100644 --- a/OshimaModules/Items/Consumable/魔力填充剂.cs +++ b/OshimaModules/Items/Consumable/魔力填充剂.cs @@ -35,7 +35,7 @@ namespace Oshima.FunGame.OshimaModules.Items return "此物品没有主动技能,无法被使用!"; } - public static bool OnItemUsed(User user, Item item, Dictionary args) + public static bool OnItemUsed(User user, Item item, int times, Dictionary args) { string msg = ""; bool result = false; @@ -55,16 +55,12 @@ namespace Oshima.FunGame.OshimaModules.Items } } args["msg"] = msg; - key = args.Keys.FirstOrDefault(s => s.Equals("useCount", StringComparison.CurrentCultureIgnoreCase)) ?? ""; - if (key != "" && args.TryGetValue(key, out value) && value is int count && targets.Length > 0) + string truemsg = $"对角色 [ {targets[0]} ] 使用 {times} 个 [ {item.Name} ] 成功!"; + if (item is MPRecovery expBook) { - string truemsg = $"对角色 [ {targets[0]} ] 使用 {count} 个 [ {item.Name} ] 成功!"; - if (item is MPRecovery expBook) - { - truemsg += $"回复了 {expBook.MP * count} 点魔法值!"; - } - args["truemsg"] = truemsg; + truemsg += $"回复了 {expBook.MP * times} 点魔法值!"; } + args["truemsg"] = truemsg; return result; } } @@ -83,9 +79,9 @@ namespace Oshima.FunGame.OshimaModules.Items 魔力填充剂.Init(this, MP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 魔力填充剂.OnItemUsed(user, this, args); + return 魔力填充剂.OnItemUsed(user, this, times, args); } } @@ -103,9 +99,9 @@ namespace Oshima.FunGame.OshimaModules.Items 魔力填充剂.Init(this, MP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 魔力填充剂.OnItemUsed(user, this, args); + return 魔力填充剂.OnItemUsed(user, this, times, args); } } @@ -123,9 +119,9 @@ namespace Oshima.FunGame.OshimaModules.Items 魔力填充剂.Init(this, MP, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 魔力填充剂.OnItemUsed(user, this, args); + return 魔力填充剂.OnItemUsed(user, this, times, args); } } diff --git a/OshimaModules/Items/GiftBox/礼包.cs b/OshimaModules/Items/GiftBox/礼包.cs index 9e10757..6aa7641 100644 --- a/OshimaModules/Items/GiftBox/礼包.cs +++ b/OshimaModules/Items/GiftBox/礼包.cs @@ -24,7 +24,7 @@ namespace Oshima.FunGame.OshimaModules.Items item.IsRemoveAfterUse = true; } - public static bool OnItemUsed(User user, Item item, Dictionary args) + public static bool OnItemUsed(User user, Item item, int times, Dictionary args) { string msg = ""; if (item is GiftBox box) @@ -61,9 +61,9 @@ namespace Oshima.FunGame.OshimaModules.Items }, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 礼包.OnItemUsed(user, this, args); + return 礼包.OnItemUsed(user, this, times, args); } } @@ -93,9 +93,9 @@ namespace Oshima.FunGame.OshimaModules.Items }, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 礼包.OnItemUsed(user, this, args); + return 礼包.OnItemUsed(user, this, times, args); } } @@ -124,9 +124,9 @@ namespace Oshima.FunGame.OshimaModules.Items }, remainUseTimes); } - protected override bool OnItemUsed(User user, Dictionary args) + protected override bool OnItemUsed(User user, int times, Dictionary args) { - return 礼包.OnItemUsed(user, this, args); + return 礼包.OnItemUsed(user, this, times, args); } } diff --git a/OshimaServers/AnonymousServer.cs b/OshimaServers/AnonymousServer.cs index 10b96c8..82dea00 100644 --- a/OshimaServers/AnonymousServer.cs +++ b/OshimaServers/AnonymousServer.cs @@ -153,14 +153,12 @@ namespace Oshima.FunGame.OshimaServers updateQuest = true; } // 探索结算 - List list = pc.Get>("exploring") ?? []; - if (list.Count > 0) + PluginConfig pc2 = new("exploring", user.Id.ToString()); + pc2.LoadConfig(); + if (pc2.Count > 0 && FunGameService.SettleExploreAll(pc2, user)) { - updateExplore = FunGameService.SettleExploreAll(list, user); - if (updateExplore) - { - pc.Add("exploring", list); - } + pc2.SaveConfig(); + updateExplore = true; } if (updateQuest || updateExplore) { diff --git a/OshimaServers/OshimaServers.csproj b/OshimaServers/OshimaServers.csproj index 6363214..4933ede 100644 --- a/OshimaServers/OshimaServers.csproj +++ b/OshimaServers/OshimaServers.csproj @@ -19,6 +19,7 @@ + diff --git a/OshimaServers/Service/FunGameOrderList.cs b/OshimaServers/Service/FunGameOrderList.cs index c2b5ca0..945c0ef 100644 --- a/OshimaServers/Service/FunGameOrderList.cs +++ b/OshimaServers/Service/FunGameOrderList.cs @@ -13,23 +13,27 @@ {"我的角色 [序号]", "查看角色详细信息(默认1)"}, {"设置主战 <序号>", "将指定角色设置为主战"}, {"我的主战", "查看当前主战角色"}, - {"装备 <角色序号> <物品序号>", "装备指定物品给角色"}, - {"取消装备 <角色序号> <装备槽序号>", "卸下角色装备(槽位1-6)"}, - {"清空小队", "清空所有小队成员"}, - {"角色升级 [序号]", "提升角色等级"}, - {"角色突破 [序号]", "突破等级限制"}, - {"突破信息 [序号]", "查看突破需求"}, - {"角色重随", "重新随机角色属性"}, - {"角色改名", "修改角色名字"}, {"开启练级 [角色序号]", "启动练级模式"}, {"练级结算", "收取练级奖励"}, {"练级信息", "查看练级进度"}, {"我的状态", "查看主战角色状态"}, + {"装备 <角色序号> <物品序号>", "装备指定物品给角色"}, + {"取消装备 <角色序号> <装备槽序号>", "卸下角色装备(槽位1-6)"}, + {"角色升级 [角色序号]", "提升角色等级(默认1)"}, + {"角色突破 [角色序号]", "突破等级限制(默认1)"}, + {"突破信息 [角色序号]", "查看突破需求(默认1)"}, + {"普攻升级 [角色序号]", "升级普攻等级(默认1)"}, + {"查看普攻升级 [角色序号]", "查看下一次普攻升级信息(默认1)"}, + {"技能升级 <角色序号> <技能名称>", "升级技能等级"}, + {"查看技能升级 <角色序号> <技能名称>", "查看下一次技能升级信息"}, + {"角色重随", "重新随机角色属性"}, + {"角色改名", "修改角色名字"}, {"我的小队", "查看小队角色名单"}, {"设置小队 <{序号...}>", "设置小队角色(1-4个参数)"}, {"小队添加 <序号>", "将角色加入小队"}, {"小队移除 <序号>", "将角色移出小队"}, {"小队状态", "查看小队所有角色状态"}, + {"清空小队", "清空所有小队成员"}, {"生命之泉", "使用金币回复角色状态"}, }; @@ -59,6 +63,10 @@ {"查询boss [序号]", "查看boss信息(默认列表)"}, {"讨伐boss <序号>", "主战角色讨伐指定boss"}, {"小队讨伐boss <序号>", "小队讨伐指定boss"}, + {"开启练级 [角色序号]", "启动练级模式"}, + {"练级结算", "收取练级奖励,并且回血和复活"}, + {"练级信息", "查看练级进度"}, + {"生命之泉", "使用金币回复角色状态"}, }; public static Dictionary QuestHelp { get; } = new() { @@ -90,7 +98,7 @@ public static Dictionary ActivityHelp { get; } = new() { {"签到", "每日签到奖励"}, - {"活动中心", "查看当前活动"}, + {"活动", "查看活动中心"}, {"查活动 <编号>", "查看指定活动详情"}, {"做活动任务 <活动序号> <任务序号>", "开始指定活动任务"}, }; diff --git a/OshimaServers/Service/FunGameService.cs b/OshimaServers/Service/FunGameService.cs index 6c1f1bd..d1e2b7e 100644 --- a/OshimaServers/Service/FunGameService.cs +++ b/OshimaServers/Service/FunGameService.cs @@ -11,6 +11,7 @@ using Oshima.FunGame.OshimaModules.Regions; using Oshima.FunGame.OshimaModules.Skills; using Oshima.FunGame.OshimaModules.Units; using Oshima.FunGame.OshimaServers.Model; +using ProjectRedbud.FunGame.SQLQueryExtension; namespace Oshima.FunGame.OshimaServers.Service { @@ -1076,14 +1077,14 @@ namespace Oshima.FunGame.OshimaServers.Service } } - public static bool UseItem(Item item, User user, IEnumerable targets, out string msg) + public static bool UseItem(Item item, int times, User user, IEnumerable targets, out string msg) { msg = ""; Dictionary args = new() { { "targets", targets.ToArray() } }; - bool result = item.UseItem(user, args); + bool result = item.UseItem(user, times, args); if (item.EntityState == EntityState.Deleted) { user.Inventory.Items.Remove(item); @@ -1125,7 +1126,7 @@ namespace Oshima.FunGame.OshimaServers.Service { continue; } - bool tempResult = item.UseItem(user, args); + bool tempResult = item.UseItem(user, 1, args); if (item.EntityState == EntityState.Deleted) { user.Inventory.Items.Remove(item); @@ -2232,15 +2233,9 @@ namespace Oshima.FunGame.OshimaServers.Service return $"{(characters.Count > 0 ? string.Join(separator, characters.Keys.Select(c => $"#{characters[c]}. {c.ToStringWithLevelWithOutUser()}")) : "空")}"; } - public static async Task GenerateExploreModel(OshimaRegion region, long[] characterIds, User user) + public static async Task GenerateExploreModel(ExploreModel model, OshimaRegion region, long[] characterIds, User user) { int characterCount = characterIds.Length; - ExploreModel model = new() - { - RegionId = region.Id, - CharacterIds = characterIds, - StartTime = DateTime.Now - }; int diff = region.Difficulty switch { RarityType.OneStar => 1, @@ -2586,14 +2581,18 @@ namespace Oshima.FunGame.OshimaServers.Service } model.String = string.Format(exploreString, award, enemy.Name, npc, item1, area1, item2, area2); - return model; + + PluginConfig pc = new("exploring", user.Id.ToString()); + pc.LoadConfig(); + pc.Add(model.Guid.ToString(), model); + pc.SaveConfig(); } - public static bool SettleExplore(Guid exploreId, List list, User user, out string msg) + public static bool SettleExplore(string exploreId, PluginConfig pc, User user, out string msg) { bool result = false; msg = ""; - ExploreModel? model = list.FirstOrDefault(m => m.Guid == exploreId); + ExploreModel? model = pc.Get(exploreId); if (model != null) { result = true; @@ -2655,27 +2654,415 @@ namespace Oshima.FunGame.OshimaServers.Service return result; } - public static bool SettleExploreAll(List list, User user, bool skip = false) + public static bool SettleExploreAll(PluginConfig pc, User user, bool skip = false) { bool settle = false; - List remove = []; - foreach (ExploreModel model in list) + List remove = []; + foreach (string guid in pc.Keys) { + ExploreModel? model = pc.Get(guid); + if (model is null) continue; if (skip || (model.StartTime.HasValue && (DateTime.Now - model.StartTime.Value).TotalMinutes > FunGameConstant.ExploreTime + 2)) { - if (SettleExplore(model.Guid, list, user, out string msg)) + if (SettleExplore(guid, pc, user, out string msg)) { settle = true; AddNotice(user.Id, $"你上次未完成的探索已被自动结算:{msg}"); - remove.Add(model.Guid); + remove.Add(guid); } } } - foreach (Guid guid in remove) + foreach (string guid in remove) { - list.RemoveAll(m => m.Guid == guid); + pc.Remove(guid); } return settle; } + + public static long MakeOffer(User user, User offeree) + { + using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); + if (sql != null) + { + sql.AddOffer(user.Id, offeree.Id); + if (sql.Success) + { + long offerId = sql.LastInsertId; + Offer? offer = sql.GetOffer(offerId); + if (offer != null) + { + return offerId; + } + } + } + return -1; + } + + public static string AddItemsToOffer(PluginConfig pc, User user, long offerId, bool isOfferee, int[] itemIds) + { + using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); + if (sql != null) + { + bool result = true; + string msg = ""; + Offer? offer = sql.GetOffer(offerId); + if (offer != null && offer.Offeror == user.Id) + { + try + { + sql.NewTransaction(); + + User addUser = user; + if (isOfferee) + { + PluginConfig pc2 = new("saved", offer.Offeror.ToString()); + + if (pc2.Count > 0) + { + addUser = GetUser(pc2); + } + else + { + msg = "目标玩家不存在,请稍后再试。"; + } + } + + List failedItems = []; + foreach (int itemIndex in itemIds) + { + if (itemIndex > 0 && itemIndex <= user.Inventory.Items.Count) + { + Item item = user.Inventory.Items.ToList()[itemIndex - 1]; + + if (!item.IsTradable) + { + result = false; + if (msg != "") msg += "\r\n"; + msg += $"物品 {itemIndex}. {item.Name}:此物品无法交易{(item.NextTradableTime != DateTime.MinValue ? $",此物品将在 {item.NextTradableTime.ToString(General.GeneralDateTimeFormatChinese)} 后可交易" : "")}。"; + break; + } + + sql.AddOfferItem(offerId, addUser.Id, item.Guid); + if (msg != "") msg += "\r\n"; + if (sql.Success) + { + msg += $"物品添加成功:{itemIndex}. {item.Name}"; + } + else + { + result = false; + msg += $"物品添加失败:{itemIndex}. {item.Name}"; + break; + } + } + else + { + failedItems.Add(itemIndex); + } + } + + if (failedItems.Count > 0) + { + if (msg != "") msg += "\r\n"; + msg += "没有找到与这个序号相对应的物品:" + string.Join(",", failedItems); + } + + if (result) + { + offer = sql.GetOffer(offerId); + if (offer != null) + { + sql.Commit(); + } + } + else + { + sql.Rollback(); + } + } + catch + { + sql.Rollback(); + msg = "修改报价时发生错误,请稍后再试。"; + throw; + } + } + else + { + msg = "报价不存在或您无权修改。"; + } + + return msg; + } + return "服务器繁忙,请稍后再试。"; + } + + public static string SendOffer(User user, long offerId) + { + using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); + if (sql != null) + { + string msg = ""; + Offer? offer = sql.GetOffer(offerId); + if (offer != null && offer.Offeror == user.Id) + { + try + { + if (offer.Status != OfferState.Created) + { + msg = "此报价已被处理。"; + return msg; + } + + bool result = true; + sql.NewTransaction(); + sql.UpdateOfferStatus(offerId, OfferState.Sent); + + if (result) + { + offer = sql.GetOffer(offerId); + if (offer != null) + { + sql.Commit(); + AddNotice(offer.Offeree, $"你收到了一个报价!请通过【我的报价】查询报价记录。"); + return $"报价编号 {offerId} 已发送。"; + } + } + else + { + sql.Rollback(); + } + } + catch + { + sql.Rollback(); + msg = "修改报价时发生错误,请稍后再试。"; + throw; + } + } + else + { + msg = "报价不存在或您无权修改。"; + } + + return msg; + } + return "服务器繁忙,请稍后再试。"; + } + + public static List GetOffer(User user, out string msg, long offerId = -1) + { + msg = ""; + List offers = []; + using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); + if (sql != null) + { + if (offerId > 0) + { + Offer? offer = sql.GetOffer(offerId); + if (offer != null) offers.Add(offer); + else msg = $"报价编号 {offerId} 不存在。"; + } + else + { + offers = sql.GetOffersByOfferor(user.Id); + offers = [.. offers, ..sql.GetOffersByOfferee(user.Id)]; + } + } + return offers; + } + + public static string RespondOffer(PluginConfig pc, User user, long offerId, OfferActionType action) + { + using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); + if (sql != null) + { + string msg = ""; + Offer? offer = sql.GetOffer(offerId); + if (offer != null && offer.Offeree == user.Id) + { + bool canProceed = false; + bool isNegotiating = false; + + try + { + sql.NewTransaction(); + + // 根据 action 处理状态 + switch (action) + { + case OfferActionType.OffereeAccept: + if (offer.Status == OfferState.Sent || offer.Status == OfferState.Negotiating || offer.Status == OfferState.NegotiationAccepted) + { + if (offer.Status == OfferState.Negotiating) + { + isNegotiating = true; + } + sql.UpdateOfferStatus(offerId, OfferState.Completed); + sql.UpdateOfferFinishTime(offerId, DateTime.Now); + canProceed = true; + } + else msg = "当前状态不允许接受。"; + break; + + case OfferActionType.OffereeReject: + if (offer.Status == OfferState.Sent || offer.Status == OfferState.Negotiating || offer.Status == OfferState.NegotiationAccepted) + { + sql.UpdateOfferStatus(offerId, OfferState.Rejected); + sql.UpdateOfferFinishTime(offerId, DateTime.Now); + canProceed = true; + } + else msg = "当前状态不允许拒绝。"; + break; + + default: + msg = "无效的操作类型。"; + break; + } + + if (canProceed) + { + offer = sql.GetOffer(offerId, isNegotiating); + if (offer != null) + { + if (offer.Status == OfferState.Completed) + { + PluginConfig pc2 = new("saved", offer.Offeror.ToString()); + + if (pc2.Count > 0) + { + User user2 = GetUser(pc2); + + foreach (Guid itemGuid in offer.OffereeItems) + { + if (user.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item) + { + user.Inventory.Items.Remove(item); + + Item newItem = item.Copy(); + newItem.User = user2; + newItem.IsSellable = false; + newItem.IsTradable = false; + newItem.NextSellableTime = DateTimeUtility.GetTradableTime(); + newItem.NextTradableTime = DateTimeUtility.GetTradableTime(); + user2.Inventory.Items.Add(newItem); + } + } + foreach (Guid itemGuid in offer.OfferorItems) + { + if (user2.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item) + { + user2.Inventory.Items.Remove(item); + + Item newItem = item.Copy(); + newItem.User = user; + newItem.IsSellable = false; + newItem.IsTradable = false; + newItem.NextSellableTime = DateTimeUtility.GetTradableTime(); + newItem.NextTradableTime = DateTimeUtility.GetTradableTime(); + user.Inventory.Items.Add(newItem); + } + } + user.LastTime = DateTime.Now; + pc.Add("user", user); + pc.SaveConfig(); + + user2.LastTime = DateTime.Now; + pc2.Add("user", user2); + pc2.SaveConfig(); + + AddNotice(offer.Offeror, $"报价编号 {offerId} 已交易完成,请通过【我的报价】查询报价记录。"); + + msg = ""; + } + else + { + msg = "目标玩家不存在,请稍后再试。"; + } + } + else if (offer.Status == OfferState.Rejected) + { + AddNotice(offer.Offeror, $"报价编号 {offerId} 已被拒绝,请通过【我的报价】查询报价记录。"); + } + sql.Commit(); + } + } + + if (msg != "") + { + sql.Rollback(); + } + else + { + return $"报价编号 {offerId} 已交易完成,请通过【我的报价】查询报价记录。"; + } + } + catch + { + sql.Rollback(); + msg = "回应报价时发生错误,请稍后再试。"; + throw; + } + } + else + { + msg = "报价不存在或您无权回应。"; + } + return msg; + } + return "服务器繁忙,请稍后再试。"; + } + + public static string CancelOffer(User user, long offerId) + { + using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); + if (sql != null) + { + string msg = ""; + Offer? offer = sql.GetOffer(offerId); + if (offer != null && offer.Offeror == user.Id) + { + try + { + if (offer.Status != OfferState.Created || offer.Status != OfferState.Sent) + { + msg = "此报价已被处理。"; + return msg; + } + + bool result = true; + sql.NewTransaction(); + sql.UpdateOfferStatus(offerId, OfferState.Cancelled); + + if (result) + { + offer = sql.GetOffer(offerId); + if (offer != null) + { + sql.Commit(); + return $"报价编号 {offerId} 已取消。"; + } + } + else + { + sql.Rollback(); + } + } + catch + { + sql.Rollback(); + msg = "修改报价时发生错误,请稍后再试。"; + throw; + } + } + else + { + msg = "报价不存在或您无权修改。"; + } + + return msg; + } + return "服务器繁忙,请稍后再试。"; + } } } diff --git a/OshimaWebAPI/Controllers/FunGameController.cs b/OshimaWebAPI/Controllers/FunGameController.cs index cbb5c43..5ac8734 100644 --- a/OshimaWebAPI/Controllers/FunGameController.cs +++ b/OshimaWebAPI/Controllers/FunGameController.cs @@ -2033,13 +2033,22 @@ namespace Oshima.FunGame.WebAPI.Controllers } } + /// + /// 通过物品序号使用,指定使用次数和目标角色 + /// + /// + /// + /// + /// + /// [HttpPost("useitem")] - public string UseItem([FromQuery] long? uid = null, [FromQuery] int? id = null, [FromBody] int[]? characters = null) + public string UseItem([FromQuery] long? uid = null, [FromQuery] int? id = null, [FromQuery] int? times = null, [FromBody] int[]? characters = null) { try { long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11)); int itemIndex = id ?? 0; + int useTimes = times ?? 1; List charactersIndex = characters?.ToList() ?? []; PluginConfig pc = new("saved", userid.ToString()); @@ -2065,11 +2074,16 @@ namespace Oshima.FunGame.WebAPI.Controllers { return "此物品为魔法卡,请使用【使用魔法卡】指令!"; } - + if (item.RemainUseTimes <= 0) { return "此物品剩余使用次数为0,无法使用!"; } + + if (useTimes > item.RemainUseTimes) + { + return $"此物品剩余使用次数为 {item.RemainUseTimes} 次,但你想使用 {useTimes} 次,使用失败!"; + } List targets = []; foreach (int characterIndex in charactersIndex) @@ -2081,7 +2095,7 @@ namespace Oshima.FunGame.WebAPI.Controllers } } - if (FunGameService.UseItem(item, user, targets, out string msg)) + if (FunGameService.UseItem(item, useTimes, user, targets, out string msg)) { user.LastTime = DateTime.Now; pc.Add("user", user); @@ -2111,6 +2125,14 @@ namespace Oshima.FunGame.WebAPI.Controllers } } + /// + /// 通过物品名称使用,指定使用数量和目标角色,使用次数为1次 + /// + /// + /// + /// + /// + /// [HttpPost("useitem2")] public string UseItem2([FromQuery] long? uid = null, [FromQuery] string? name = null, [FromQuery] int? count = null, [FromBody] int[]? characters = null) { @@ -2184,6 +2206,14 @@ namespace Oshima.FunGame.WebAPI.Controllers } } + /// + /// 使用魔法卡 + /// + /// + /// + /// + /// + /// [HttpPost("useitem3")] public string UseItem3([FromQuery] long? uid = null, [FromQuery] int? id = null, [FromQuery] int? id2 = null, [FromQuery] bool? c = null) { @@ -2293,6 +2323,141 @@ namespace Oshima.FunGame.WebAPI.Controllers } } + /// + /// 通过物品序号批量使用物品,指定目标角色,使用次数为1次 + /// + /// + /// + /// + [HttpPost("useitem4")] + public string UseItem4([FromQuery] long uid, [FromBody] (int[], int[]) idsAndCids) + { + try + { + int[] itemsIndex = idsAndCids.Item1; + int[] charactersIndex = idsAndCids.Item2; + + PluginConfig pc = new("saved", uid.ToString()); + pc.LoadConfig(); + + if (pc.Count > 0) + { + User user = FunGameService.GetUser(pc); + + List characters = []; + List failedCharacters = []; + + foreach (int characterIndex in charactersIndex) + { + if (characterIndex > 0 && characterIndex <= user.Inventory.Characters.Count) + { + Character? character = user.Inventory.Characters.ToList()[characterIndex - 1]; + characters.Add(character); + } + else + { + failedCharacters.Add(characterIndex); + } + } + + if (failedCharacters.Count > 0) + { + return $"没有找到与这些序号相对应的角色:{string.Join(",", failedCharacters)}。"; + } + + bool result = true; + Dictionary itemsMsg = []; + + foreach (int itemIndex in itemsIndex) + { + if (!result) + { + break; + } + + bool subResult = true; + Item? item = null; + if (itemIndex > 0 && itemIndex <= user.Inventory.Items.Count) + { + itemsMsg[itemIndex] = ""; + item = user.Inventory.Items.ToList()[itemIndex - 1]; + if (FunGameConstant.ItemCanUsed.Contains(item.ItemType)) + { + if (item.IsLock) + { + subResult = false; + itemsMsg[itemIndex] += $"此物品已上锁,请先解锁:{itemIndex}. {item.Name}\r\n"; + } + + if (item.ItemType == ItemType.MagicCard) + { + subResult = false; + itemsMsg[itemIndex] += "此物品为魔法卡,请使用【使用魔法卡】指令!\r\n"; + } + + if (item.RemainUseTimes <= 0) + { + subResult = false; + itemsMsg[itemIndex] += "此物品剩余使用次数为0,无法使用!\r\n"; + } + + if (subResult) + { + subResult = FunGameService.UseItem(item, 1, user, characters, out string useMsg); + itemsMsg[itemIndex] += useMsg; + } + + if (!subResult) + { + result = false; + } + } + else + { + itemsMsg[itemIndex] += $"这个物品无法使用!\r\n"; + } + } + else + { + itemsMsg[itemIndex] += $"没有找到与这个序号相对应的物品。\r\n"; + } + } + + StringBuilder builder = new(); + foreach (int itemIndex in itemsMsg.Keys) + { + builder.AppendLine($"物品序号:{itemIndex}"); + builder.AppendLine($"使用结果:{string.Join("", itemsMsg[itemIndex])}"); + } + + string msg = builder.ToString().Trim(); + if (msg != "") + { + msg = $"使用 {itemsIndex.Length} 件物品完毕:\r\n{msg}"; + } + else result = false; + + if (result) + { + user.LastTime = DateTime.Now; + pc.Add("user", user); + pc.SaveConfig(); + } + + return msg; + } + else + { + return noSaved; + } + } + catch (Exception e) + { + Logger.LogError(e, "Error: "); + return busy; + } + } + [HttpPost("characterlevelup")] public string CharacterLevelUp([FromQuery] long? uid = null, [FromQuery] int? c = null, [FromQuery] int? count = null) { @@ -4400,12 +4565,12 @@ namespace Oshima.FunGame.WebAPI.Controllers Club? club = emc.Get("club"); if (club != null) { - StringBuilder builer = new(); + StringBuilder builder = new(); int count; switch (showType) { case 1: - builer.AppendLine($"☆--- 社团 [ {club.Name} ] 管理员列表 ---☆"); + builder.AppendLine($"☆--- 社团 [ {club.Name} ] 管理员列表 ---☆"); count = 1; List admins = []; if (club.Master != null && club.Master.Id != 0) @@ -4423,24 +4588,24 @@ namespace Oshima.FunGame.WebAPI.Controllers { if (FunGameConstant.UserIdAndUsername.TryGetValue(uid2, out User? user2) && user2 != null) { - builer.AppendLine($"{count}."); - builer.AppendLine($"UID:{user2.Id}"); - builer.AppendLine($"玩家昵称:{user2.Username}"); - builer.AppendLine($"加入时间:{club.MemberJoinTime[user2.Id].ToString(General.GeneralDateTimeFormatChinese)}"); + builder.AppendLine($"{count}."); + builder.AppendLine($"UID:{user2.Id}"); + builder.AppendLine($"玩家昵称:{user2.Username}"); + builder.AppendLine($"加入时间:{club.MemberJoinTime[user2.Id].ToString(General.GeneralDateTimeFormatChinese)}"); } count++; } - builer.AppendLine($"页数:{showPage} / {maxPage}"); + builder.AppendLine($"页数:{showPage} / {maxPage}"); } else { - builer.Append($"没有这么多页!当前总页数为 {maxPage},但你请求的是第 {showPage} 页。"); + builder.Append($"没有这么多页!当前总页数为 {maxPage},但你请求的是第 {showPage} 页。"); } break; case 2: if (club.Master?.Id == user.Id || club.Admins.ContainsKey(user.Id)) { - builer.AppendLine($"☆--- 社团 [ {club.Name} ] 申请人列表 ---☆"); + builder.AppendLine($"☆--- 社团 [ {club.Name} ] 申请人列表 ---☆"); count = 1; maxPage = (int)Math.Ceiling((double)club.Applicants.Count / FunGameConstant.ItemsPerPage2); if (maxPage < 1) maxPage = 1; @@ -4451,28 +4616,28 @@ namespace Oshima.FunGame.WebAPI.Controllers { if (FunGameConstant.UserIdAndUsername.TryGetValue(uid2, out User? user2) && user2 != null) { - builer.AppendLine($"{count}."); - builer.AppendLine($"UID:{user2.Id}"); - builer.AppendLine($"玩家昵称:{user2.Username}"); - builer.AppendLine($"申请时间:{club.ApplicationTime[user2.Id].ToString(General.GeneralDateTimeFormatChinese)}"); + builder.AppendLine($"{count}."); + builder.AppendLine($"UID:{user2.Id}"); + builder.AppendLine($"玩家昵称:{user2.Username}"); + builder.AppendLine($"申请时间:{club.ApplicationTime[user2.Id].ToString(General.GeneralDateTimeFormatChinese)}"); } count++; } - builer.AppendLine($"页数:{showPage} / {maxPage}"); + builder.AppendLine($"页数:{showPage} / {maxPage}"); } else { - builer.Append($"没有这么多页!当前总页数为 {maxPage},但你请求的是第 {showPage} 页。"); + builder.Append($"没有这么多页!当前总页数为 {maxPage},但你请求的是第 {showPage} 页。"); } } else { - builer.Append("你没有权限查看这个列表!"); + builder.Append("你没有权限查看这个列表!"); } break; case 0: default: - builer.AppendLine($"☆--- 社团 [ {club.Name} ] 成员列表 ---☆"); + builder.AppendLine($"☆--- 社团 [ {club.Name} ] 成员列表 ---☆"); count = 1; maxPage = (int)Math.Ceiling((double)club.Members.Count / FunGameConstant.ItemsPerPage2); if (maxPage < 1) maxPage = 1; @@ -4483,9 +4648,9 @@ namespace Oshima.FunGame.WebAPI.Controllers { if (FunGameConstant.UserIdAndUsername.TryGetValue(uid2, out User? user2) && user2 != null) { - builer.AppendLine($"{count}."); - builer.AppendLine($"UID:{user2.Id}"); - builer.AppendLine($"玩家昵称:{user2.Username}"); + builder.AppendLine($"{count}."); + builder.AppendLine($"UID:{user2.Id}"); + builder.AppendLine($"玩家昵称:{user2.Username}"); string userType = "社员"; if (club.Master?.Id == user2.Id) { @@ -4495,21 +4660,21 @@ namespace Oshima.FunGame.WebAPI.Controllers { userType = "管理员"; } - builer.AppendLine($"社团身份:{userType}"); - builer.AppendLine($"加入时间:{club.MemberJoinTime[user2.Id].ToString(General.GeneralDateTimeFormatChinese)}"); + builder.AppendLine($"社团身份:{userType}"); + builder.AppendLine($"加入时间:{club.MemberJoinTime[user2.Id].ToString(General.GeneralDateTimeFormatChinese)}"); } count++; } - builer.AppendLine($"页数:{showPage} / {maxPage}"); + builder.AppendLine($"页数:{showPage} / {maxPage}"); } else { - builer.Append($"没有这么多页!当前总页数为 {maxPage},但你请求的是第 {showPage} 页。"); + builder.Append($"没有这么多页!当前总页数为 {maxPage},但你请求的是第 {showPage} 页。"); } break; } - msg = builer.ToString().Trim(); + msg = builder.ToString().Trim(); } else { @@ -5261,9 +5426,9 @@ namespace Oshima.FunGame.WebAPI.Controllers } [HttpPost("exploreregion")] - public async Task<(string, Guid)> ExploreRegion([FromQuery] long? uid = null, [FromQuery] long? id = null, [FromBody] long[]? cids = null) + public async Task<(string, string)> ExploreRegion([FromQuery] long? uid = null, [FromQuery] long? id = null, [FromBody] long[]? cids = null) { - Guid exploreId = Guid.Empty; + string exploreId = ""; await _semaphore.WaitAsync(); try { @@ -5336,27 +5501,20 @@ namespace Oshima.FunGame.WebAPI.Controllers } // 检查角色是否正在探索 - List list = pc.Get>("exploring") ?? []; - if (list.Count > 0) + PluginConfig pc2 = new("exploring", userid.ToString()); + pc2.LoadConfig(); + if (pc2.Count > 0) { - string msg2 = ""; - List remove = []; - foreach (ExploreModel model in list) + // 可能要结算先前的超时探索 + if (FunGameService.SettleExploreAll(pc2, user)) { - // 可能要结算先前的超时探索 - if (model.StartTime.HasValue && (DateTime.Now - model.StartTime.Value).TotalMinutes > FunGameConstant.ExploreTime + 2) - { - if (FunGameService.SettleExplore(model.Guid, list, user, out string notice)) - { - if (notice != "") - { - if (msg2 != "") msg2 += "\r\n"; - msg2 += $"你上次未完成的探索已被自动结算:{notice}"; - } - remove.Add(model.Guid); - } - } - + pc2.SaveConfig(); + } + string msg2 = ""; + foreach (string guid in pc2.Keys) + { + ExploreModel? model = pc2.Get(guid); + if (model is null) continue; IEnumerable exploring = model.CharacterIds.Intersect(characterIds); if (exploring.Any()) { @@ -5365,10 +5523,6 @@ namespace Oshima.FunGame.WebAPI.Controllers $"因为这些角色已经参与了另一场探索:\r\n{model.GetExploreInfo(user.Inventory.Characters, FunGameConstant.Regions)}"; } } - foreach (Guid guid in remove) - { - list.RemoveAll(m => m.Guid == guid); - } if (msg2 != "") { if (msg != "") msg += "\r\n"; @@ -5382,9 +5536,14 @@ namespace Oshima.FunGame.WebAPI.Controllers msg = $"开始探索【{region.Name}】,探索时间预计 {FunGameConstant.ExploreTime} 分钟(系统会自动结算,届时会有提示)。注意:探索期间的角色状态已被锁定,在此期间修改角色属性不会影响战斗结果。" + $"探索成员:[ {FunGameService.GetCharacterGroupInfoByInventorySequence(user.Inventory.Characters, characterIds, " ] / [ ")} ]"; - ExploreModel model = await FunGameService.GenerateExploreModel(region, characterIds, user); - exploreId = model.Guid; - list.Add(model); + ExploreModel model = new() + { + RegionId = region.Id, + CharacterIds = characterIds, + StartTime = DateTime.Now + }; + exploreId = model.Guid.ToString(); + TaskUtility.NewTask(async () => await FunGameService.GenerateExploreModel(model, region, characterIds, user)); if (msg != "") msg += "\r\n"; msg += $"本次消耗探索许可 {reduce} 个,你的剩余探索许可:{exploreTimes} 个。需要注意:探索难度星级一比一兑换探索许可,并且参与探索的角色,都需要消耗相同数量的探索许可。"; @@ -5393,7 +5552,6 @@ namespace Oshima.FunGame.WebAPI.Controllers user.LastTime = DateTime.Now; pc.Add("user", user); pc.Add("exploreTimes", exploreTimes); - pc.Add("exploring", list); pc.SaveConfig(); return (msg, exploreId); @@ -5438,12 +5596,15 @@ namespace Oshima.FunGame.WebAPI.Controllers exploreTimes = FunGameConstant.MaxExploreTimes; } - List list = pc.Get>("exploring") ?? []; - if (list.Count > 0) + PluginConfig pc2 = new("exploring", userid.ToString()); + pc2.LoadConfig(); + if (pc2.Count > 0) { string msg2 = ""; - foreach (ExploreModel model in list) + foreach (string guid in pc2.Keys) { + ExploreModel? model = pc2.Get(guid); + if (model is null) continue; if (msg2 != "") msg2 += "\r\n"; msg2 += model.GetExploreInfo(user.Inventory.Characters, FunGameConstant.Regions); } @@ -5486,12 +5647,13 @@ namespace Oshima.FunGame.WebAPI.Controllers { User user = FunGameService.GetUser(pc); - List list = pc.Get>("exploring") ?? []; - if (list.Count > 0) + PluginConfig pc2 = new("exploring", userid.ToString()); + pc2.LoadConfig(); + if (pc2.Count > 0) { - if (FunGameService.SettleExploreAll(list, user, skip ?? false)) + if (FunGameService.SettleExploreAll(pc2, user, skip ?? false)) { - pc.Add("exploring", list); + pc2.SaveConfig(); msg = $"已完成探索结算。"; } else @@ -5517,7 +5679,7 @@ namespace Oshima.FunGame.WebAPI.Controllers } [HttpPost("exploresettle")] - public string SettleExplore(Guid exploreId, [FromQuery] long? uid = null) + public string SettleExplore(string exploreId, [FromQuery] long? uid = null) { long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11)); @@ -5529,14 +5691,15 @@ namespace Oshima.FunGame.WebAPI.Controllers { User user = FunGameService.GetUser(pc); - List list = pc.Get>("exploring") ?? []; - if (list.Count > 0) + PluginConfig pc2 = new("exploring", userid.ToString()); + pc2.LoadConfig(); + if (pc2.Count > 0) { - if (FunGameService.SettleExplore(exploreId, list, user, out msg)) + if (FunGameService.SettleExplore(exploreId, pc2, user, out msg)) { - list.RemoveAll(m => m.Guid == exploreId); + pc2.Remove(exploreId); + pc2.SaveConfig(); } - pc.Add("exploring", list); } user.LastTime = DateTime.Now; @@ -5712,28 +5875,337 @@ namespace Oshima.FunGame.WebAPI.Controllers } } + [HttpPost("makeoffer")] + public string MakeOffer([FromQuery] long? uid = null, [FromQuery] long? offeree = null) + { + long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11)); + + try + { + PluginConfig pc = new("saved", userid.ToString()); + pc.LoadConfig(); + + string msg = ""; + if (pc.Count > 0) + { + User user = FunGameService.GetUser(pc); + + if (FunGameConstant.UserIdAndUsername.TryGetValue(offeree ?? -1, out User? user2) && user2 != null) + { + long offerId = FunGameService.MakeOffer(user, user2); + msg = $"创建报价成功,报价编号:{offerId},目标玩家:{user2.Id}. {user2.Username}"; + } + else + { + return $"目标玩家不存在。"; + } + + user.LastTime = DateTime.Now; + pc.Add("user", user); + pc.SaveConfig(); + + return msg; + } + else + { + return noSaved; + } + } + catch (Exception e) + { + Logger.LogError(e, "Error: "); + return busy; + } + } + + [HttpPost("additemstooffer")] + public string AddItemsToOffer([FromQuery] long? uid = null, [FromQuery] long? offer = null, [FromQuery] bool isOfferee = true, [FromBody] int[]? itemIds = null) + { + long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11)); + long offerId = offer ?? -1; + int[] itemsIndex = itemIds ?? []; + + try + { + PluginConfig pc = new("saved", userid.ToString()); + pc.LoadConfig(); + + string msg = ""; + if (pc.Count > 0) + { + User user = FunGameService.GetUser(pc); + + if (offerId > 0) + { + msg = FunGameService.AddItemsToOffer(pc, user, offerId, isOfferee, itemsIndex); + } + else + { + msg = "没有找到对应的报价。"; + } + + return msg; + } + else + { + return noSaved; + } + } + catch (Exception e) + { + Logger.LogError(e, "Error: "); + return busy; + } + } + + [HttpPost("sendoffer")] + public string SendOffer([FromQuery] long? uid = null, [FromQuery] long? offerId = null) + { + long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11)); + + try + { + PluginConfig pc = new("saved", userid.ToString()); + pc.LoadConfig(); + + string msg = ""; + if (pc.Count > 0) + { + User user = FunGameService.GetUser(pc); + + msg = FunGameService.SendOffer(user, offerId ?? -1); + + user.LastTime = DateTime.Now; + pc.Add("user", user); + pc.SaveConfig(); + + return msg; + } + else + { + return noSaved; + } + } + catch (Exception e) + { + Logger.LogError(e, "Error: "); + return busy; + } + } + + [HttpPost("respondoffer")] + public string RespondOffer([FromQuery] long? uid = null, [FromQuery] long? offer = null, [FromQuery] bool accept = false) + { + long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11)); + long offerId = offer ?? -1; + + try + { + PluginConfig pc = new("saved", userid.ToString()); + pc.LoadConfig(); + + string msg = ""; + if (pc.Count > 0) + { + User user = FunGameService.GetUser(pc); + + if (offerId > 0) + { + FunGameService.RespondOffer(pc, user, offerId, accept ? OfferActionType.OffereeAccept : OfferActionType.OffereeReject); + } + else + { + msg = "没有找到对应的报价。"; + } + + return msg; + } + else + { + return noSaved; + } + } + catch (Exception e) + { + Logger.LogError(e, "Error: "); + return busy; + } + } + + [HttpPost("getoffer")] + public string GetOffer([FromQuery] long? uid = null, [FromQuery] long? offerId = null, [FromQuery] int? page = null) + { + long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11)); + int showPage = page ?? 1; + if (showPage <= 0) showPage = 1; + + try + { + PluginConfig pc = new("saved", userid.ToString()); + pc.LoadConfig(); + + string msg = ""; + if (pc.Count > 0) + { + User user = FunGameService.GetUser(pc); + + List offers = FunGameService.GetOffer(user, out msg, offerId ?? -1); + + if (msg != "") + { + return msg; + } + + int maxPage = (int)Math.Ceiling((double)offers.Count); + if (maxPage < 1) maxPage = 1; + if (showPage <= maxPage) + { + IEnumerable showOffers = FunGameService.GetPage(offers, showPage, 1); + if (showOffers.Any()) + { + StringBuilder builder = new(); + + foreach (Offer offer in showOffers) + { + User? user1 = null, user2 = null; + if (FunGameConstant.UserIdAndUsername.TryGetValue(offer.Offeror, out User? offeror) && offeror != null) + { + user1 = offeror; + } + if (FunGameConstant.UserIdAndUsername.TryGetValue(offer.Offeror, out User? offeree) && offeree != null) + { + user2 = offeree; + } + + if (user1 is null || user2 is null) continue; + + builder.AppendLine($"☆--- 报价编号:{offer.Id} ---☆"); + builder.AppendLine($"发起方:{user1}"); + builder.AppendLine($"接收方:{user2}"); + builder.AppendLine($"状态:{CommonSet.GetOfferStatus(offer.Status)}"); + + List user1Item = []; + List user2Item = []; + foreach (Item item in user1.Inventory.Items) + { + if (offer.OfferorItems.Contains(item.Guid)) + { + user1Item.Add($"[{ItemSet.GetQualityTypeName(item.QualityType)}]" + ItemSet.GetItemTypeName(item.ItemType) + ":" + item.Name); + } + } + foreach (Item item in user2.Inventory.Items) + { + if (offer.OffereeItems.Contains(item.Guid)) + { + user2Item.Add($"[{ItemSet.GetQualityTypeName(item.QualityType)}]" + ItemSet.GetItemTypeName(item.ItemType) + ":" + item.Name); + } + } + + if (user1Item.Count > 0) + { + builder.AppendLine($"=== 发起方物品 ==="); + builder.AppendLine(string.Join("\r\n", user1Item)); + } + + if (user2Item.Count > 0) + { + builder.AppendLine($"=== 接收方物品 ==="); + builder.AppendLine(string.Join("\r\n", user2Item)); + } + } + + builder.AppendLine($"页数:{showPage} / {maxPage}"); + msg = builder.ToString().Trim(); + } + } + else + { + return $"没有这么多页!当前总页数为 {maxPage},但你请求的是第 {showPage} 页。"; + } + + user.LastTime = DateTime.Now; + pc.Add("user", user); + pc.SaveConfig(); + + return msg; + } + else + { + return noSaved; + } + } + catch (Exception e) + { + Logger.LogError(e, "Error: "); + return busy; + } + } + + [HttpPost("canceloffer")] + public string CancelOffer([FromQuery] long? uid = null, [FromQuery] long? offerId = null) + { + long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11)); + + try + { + PluginConfig pc = new("saved", userid.ToString()); + pc.LoadConfig(); + + string msg = ""; + if (pc.Count > 0) + { + User user = FunGameService.GetUser(pc); + + msg = FunGameService.CancelOffer(user, offerId ?? -1); + + user.LastTime = DateTime.Now; + pc.Add("user", user); + pc.SaveConfig(); + + return msg; + } + else + { + return noSaved; + } + } + catch (Exception e) + { + Logger.LogError(e, "Error: "); + return busy; + } + } + [HttpPost("template")] public string Template([FromQuery] long? uid = null) { long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11)); - PluginConfig pc = new("saved", userid.ToString()); - pc.LoadConfig(); - - string msg = ""; - if (pc.Count > 0) + try { - User user = FunGameService.GetUser(pc); + PluginConfig pc = new("saved", userid.ToString()); + pc.LoadConfig(); - user.LastTime = DateTime.Now; - pc.Add("user", user); - pc.SaveConfig(); + string msg = ""; + if (pc.Count > 0) + { + User user = FunGameService.GetUser(pc); - return msg; + user.LastTime = DateTime.Now; + pc.Add("user", user); + pc.SaveConfig(); + + return msg; + } + else + { + return noSaved; + } } - else + catch (Exception e) { - return noSaved; + Logger.LogError(e, "Error: "); + return busy; } } diff --git a/OshimaWebAPI/Controllers/QQBotController.cs b/OshimaWebAPI/Controllers/QQBotController.cs index ea54e2f..8599ce2 100644 --- a/OshimaWebAPI/Controllers/QQBotController.cs +++ b/OshimaWebAPI/Controllers/QQBotController.cs @@ -191,5 +191,31 @@ namespace Oshima.FunGame.WebAPI.Controllers return Ok(""); } + + [Authorize(AuthenticationSchemes = "CustomBearer")] + [HttpPost("thirdpartytest")] + public async Task ThirdPartyTest(string msg, string openID) + { + if (msg.Trim() == "") return Ok(""); + + ThirdPartyMessage message = new() + { + IsGroup = false, + AuthorOpenId = openID, + OpenId = openID, + Detail = msg, + Id = openID, + Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + }; + + bool result = await FungameService.Handler(message); + + if (!result || message.IsCompleted) + { + return Ok(message.Result); + } + + return Ok(""); + } } } diff --git a/OshimaWebAPI/Services/RainBOTService.cs b/OshimaWebAPI/Services/RainBOTService.cs index 8759b6e..a90d50c 100644 --- a/OshimaWebAPI/Services/RainBOTService.cs +++ b/OshimaWebAPI/Services/RainBOTService.cs @@ -1235,23 +1235,56 @@ namespace Oshima.FunGame.WebAPI.Services return result; } - if (e.Detail.StartsWith("使用", StringComparison.CurrentCultureIgnoreCase)) + if (e.Detail.StartsWith("使用") || e.Detail.StartsWith("批量使用")) { - string detail = e.Detail.Replace("使用", "").Trim(); - if (detail.StartsWith("魔法卡")) + if (e.Detail.StartsWith("批量使用")) { - string pattern = @"\s*魔法卡\s*(?\d+)(?:\s*(?:角色\s*)?(?\d+))?\s*"; + string detail = e.Detail.Replace("批量使用", "").Trim(); + char[] chars = [',', ' ', ',', ';', ';']; + string pattern = @"\s*(?:角色\s*(?\d+))?\s*(?[\d\s,,;;]+)"; + Match match = Regex.Match(detail, pattern); + if (match.Success) + { + string itemIdsString = match.Groups["itemIds"].Value; + string characterId = match.Groups["characterId"].Value; + int[] characterIds = characterId != "" ? [int.Parse(characterId)] : [1]; + int[] itemIds = itemIdsString.Split(chars, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); + if (itemIds.Length > 0) + { + string msg = Controller.UseItem4(uid, (itemIds, characterIds)); + if (msg != "") + { + await SendAsync(e, "批量使用", msg); + } + } + } + } + else if (e.Detail.StartsWith("使用魔法卡")) + { + string detail = e.Detail.Replace("使用", "").Trim(); + string pattern = @"\s*魔法卡\s*(?\d+)(?:\s+(?:(?:角色\s*(?\d+))|(?\d+)))?"; Match match = Regex.Match(detail, pattern); if (match.Success) { string itemId = match.Groups["itemId"].Value; string characterId = match.Groups["characterId"].Value; - bool isCharacter = detail.Contains("角色"); - if (int.TryParse(itemId, out int id) && int.TryParse(characterId, out int id2)) + bool isCharacter = match.Groups["characterId"].Success; + string packageId = match.Groups["packageId"].Value; + if (int.TryParse(itemId, out int id) && id > 0) { - if (id > 0 && id2 > 0) + int targetId = 0; + if (isCharacter && int.TryParse(characterId, out int charId) && charId > 0) { - string msg = Controller.UseItem3(uid, id, id2, isCharacter); + targetId = charId; + } + else if (!isCharacter && int.TryParse(packageId, out int pkgId) && pkgId > 0) + { + targetId = pkgId; + isCharacter = false; + } + if (targetId > 0) + { + string msg = Controller.UseItem3(uid, id, targetId, isCharacter); if (msg != "") { await SendAsync(e, "使用魔法卡", msg); @@ -1262,71 +1295,33 @@ namespace Oshima.FunGame.WebAPI.Services } else { - char[] chars = [',', ' ']; - string pattern = @"\s*(?[^\d]+)\s*(?\d+)\s*(?:角色\s*(?[\d\s]*))?"; + string detail = e.Detail.Replace("使用", "").Trim(); + char[] chars = [',', ' ', ',', ';', ';']; + string pattern = @"^\s*(?:(?\d+)|(?[^\d\s].*?))\s*(?:(?\d+)(?:\s+角色\s*(?[\d\s,,;;]*))?)?$"; Match match = Regex.Match(detail, pattern); if (match.Success) { - string itemName = match.Groups["itemName"].Value.Trim(); - if (int.TryParse(match.Groups["count"].Value, out int count)) + string itemId = match.Groups["itemId"].Value; + string itemPart = match.Groups["itemPart"].Value.Trim(); + string countStr = match.Groups["countPart"].Value; + string characterIdsString = match.Groups["characterIds"].Value; + int[] characterIds = characterIdsString != "" ? [.. characterIdsString.Split(chars, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse)] : [1]; + int count = string.IsNullOrEmpty(countStr) ? 1 : int.Parse(countStr); + + if (!string.IsNullOrEmpty(itemId) && int.TryParse(itemId, out int id)) { - string characterIdsString = match.Groups["characterIds"].Value; - int[] characterIds = characterIdsString != "" ? [.. characterIdsString.Split(chars, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse)] : [1]; - string msg = Controller.UseItem2(uid, itemName, count, characterIds); - if (msg != "") + string msg = Controller.UseItem(uid, id, count, characterIds); + if (!string.IsNullOrEmpty(msg)) { await SendAsync(e, "使用", msg); } } - } - else - { - pattern = @"\s*(?\d+)\s*(?:角色\s*(?[\d\s]*))?"; - match = Regex.Match(detail, pattern); - if (match.Success) + else if(!string.IsNullOrEmpty(itemPart)) { - if (int.TryParse(match.Groups["itemId"].Value, out int itemId)) + string msg = Controller.UseItem2(uid, itemPart, count, characterIds); + if (msg != "") { - string characterIdsString = match.Groups["characterIds"].Value; - int[] characterIds = characterIdsString != "" ? [.. characterIdsString.Split(chars, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse)] : [1]; - string msg = Controller.UseItem(uid, itemId, characterIds); - if (msg != "") - { - await SendAsync(e, "使用", msg); - } - } - } - else - { - pattern = @"\s*(?[^\d]+)\s*(?\d+)\s*"; - match = Regex.Match(detail, pattern); - if (match.Success) - { - string itemName = match.Groups["itemName"].Value.Trim(); - if (int.TryParse(match.Groups["count"].Value, out int count)) - { - string msg = Controller.UseItem2(uid, itemName, count); - if (msg != "") - { - await SendAsync(e, "使用", msg); - } - } - } - else - { - pattern = @"\s*(?\d+)\s*"; - match = Regex.Match(detail, pattern); - if (match.Success) - { - if (int.TryParse(match.Groups["itemId"].Value, out int itemId)) - { - string msg = Controller.UseItem(uid, itemId); - if (msg != "") - { - await SendAsync(e, "使用", msg); - } - } - } + await SendAsync(e, "使用", msg); } } } @@ -2100,7 +2095,7 @@ namespace Oshima.FunGame.WebAPI.Services { string detail = e.Detail.Replace("探索", "").Replace("前往", "").Trim(); string msg = ""; - Guid eid = Guid.Empty; + string eid = ""; string[] strings = detail.Split(' ', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); List cindexs = []; foreach (string s in strings) @@ -2205,7 +2200,7 @@ namespace Oshima.FunGame.WebAPI.Services } if (indexs.Count > 0) { - msg = Controller.LockItem(uid, true, [.. indexs]); + msg = Controller.LockItem(uid, false, [.. indexs]); if (msg.Trim() != "") { await SendAsync(e, "上锁", msg); @@ -2238,6 +2233,159 @@ namespace Oshima.FunGame.WebAPI.Services return result; } + if (e.Detail.StartsWith(value: "创建报价")) + { + string detail = e.Detail.Replace("创建报价", "").Trim(); + string msg = ""; + if (long.TryParse(detail, out long target)) + { + msg = Controller.MakeOffer(uid, target); + if (msg.Trim() != "") + { + await SendAsync(e, "创建报价", msg); + } + } + return result; + } + + if (e.Detail.StartsWith(value: "我的报价")) + { + string detail = e.Detail.Replace("我的报价", "").Trim(); + string msg = ""; + if (int.TryParse(detail, out int page)) + { + msg = Controller.GetOffer(uid, null, page); + if (msg.Trim() != "") + { + await SendAsync(e, "我的报价", msg); + } + } + return result; + } + + if (e.Detail.StartsWith(value: "查报价")) + { + string detail = e.Detail.Replace("查报价", "").Trim(); + string msg = ""; + if (long.TryParse(detail, out long id)) + { + msg = Controller.GetOffer(uid, id); + if (msg.Trim() != "") + { + await SendAsync(e, "查报价", msg); + } + } + return result; + } + + if (e.Detail.StartsWith(value: "发送报价")) + { + string detail = e.Detail.Replace("发送报价", "").Trim(); + string msg = ""; + if (long.TryParse(detail, out long id)) + { + msg = Controller.SendOffer(uid, id); + if (msg.Trim() != "") + { + await SendAsync(e, "发送报价", msg); + } + } + return result; + } + + if (e.Detail.StartsWith(value: "取消报价")) + { + string detail = e.Detail.Replace("取消报价", "").Trim(); + string msg = ""; + if (long.TryParse(detail, out long id)) + { + msg = Controller.CancelOffer(uid, id); + if (msg.Trim() != "") + { + await SendAsync(e, "取消报价", msg); + } + } + return result; + } + + if (e.Detail.StartsWith(value: "接受报价")) + { + string detail = e.Detail.Replace("接受报价", "").Trim(); + string msg = ""; + if (long.TryParse(detail, out long id)) + { + msg = Controller.RespondOffer(uid, id, true); + if (msg.Trim() != "") + { + await SendAsync(e, "接受报价", msg); + } + } + return result; + } + + if (e.Detail.StartsWith(value: "拒绝报价")) + { + string detail = e.Detail.Replace("拒绝报价", "").Trim(); + string msg = ""; + if (long.TryParse(detail, out long id)) + { + msg = Controller.RespondOffer(uid, id, false); + if (msg.Trim() != "") + { + await SendAsync(e, "拒绝报价", msg); + } + } + return result; + } + + if (e.Detail.StartsWith(value: "报价添加物品")) + { + string detail = e.Detail.Replace("报价添加物品", "").Trim(); + string msg = ""; + string[] strings = detail.Split(' ', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); + List indexs = []; + foreach (string s in strings) + { + if (int.TryParse(s, out int c)) + { + indexs.Add(c); + } + } + if (long.TryParse(detail, out long id)) + { + msg = Controller.AddItemsToOffer(uid, id, false, [.. indexs]); + if (msg.Trim() != "") + { + await SendAsync(e, "报价添加物品", msg); + } + } + return result; + } + + if (e.Detail.StartsWith(value: "报价添加对方物品")) + { + string detail = e.Detail.Replace("报价添加对方物品", "").Trim(); + string msg = ""; + string[] strings = detail.Split(' ', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); + List indexs = []; + foreach (string s in strings) + { + if (int.TryParse(s, out int c)) + { + indexs.Add(c); + } + } + if (long.TryParse(detail, out long id)) + { + msg = Controller.AddItemsToOffer(uid, id, true, [.. indexs]); + if (msg.Trim() != "") + { + await SendAsync(e, "报价添加对方物品", msg); + } + } + return result; + } + if (uid == GeneralSettings.Master && e.Detail.StartsWith("重载FunGame", StringComparison.CurrentCultureIgnoreCase)) { string msg = Controller.Relaod(uid);