From bacc34238598d199bd4cdfc59063b6b67080d934 Mon Sep 17 00:00:00 2001 From: milimoe Date: Fri, 18 Jul 2025 00:02:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A7=98=E5=A2=83=E6=8C=91?= =?UTF-8?q?=E6=88=98=EF=BC=8C=E4=BC=98=E5=8C=96=E6=8E=A2=E7=B4=A2=E5=A5=96?= =?UTF-8?q?=E5=8A=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OshimaCore/Constant/TypeEnum.cs | 14 + OshimaServers/Service/FunGameConstant.cs | 24 ++ OshimaServers/Service/FunGameOrderList.cs | 8 +- OshimaServers/Service/FunGameService.cs | 390 ++++++++++++++++-- OshimaWebAPI/Controllers/FunGameController.cs | 98 ++++- OshimaWebAPI/Services/RainBOTService.cs | 136 ++++-- 6 files changed, 604 insertions(+), 66 deletions(-) diff --git a/OshimaCore/Constant/TypeEnum.cs b/OshimaCore/Constant/TypeEnum.cs index 0b5042d..149bf44 100644 --- a/OshimaCore/Constant/TypeEnum.cs +++ b/OshimaCore/Constant/TypeEnum.cs @@ -10,4 +10,18 @@ Misfortune, GreatMisfortune } + + public enum InstanceType + { + Explore, + Currency, + Material, + RegionItem, + EXP, + CharacterLevelBreak, + SkillLevelUp, + RogueLike, + Team, + PVP + } } diff --git a/OshimaServers/Service/FunGameConstant.cs b/OshimaServers/Service/FunGameConstant.cs index b2ecfe7..1305175 100644 --- a/OshimaServers/Service/FunGameConstant.cs +++ b/OshimaServers/Service/FunGameConstant.cs @@ -24,6 +24,8 @@ namespace Oshima.FunGame.OshimaServers.Service public static List Equipment { get; } = []; public static List Items { get; } = []; public static List DrawCardItems { get; } = []; + public static List CharacterLevelBreakItems { get; } = []; + public static List SkillLevelUpItems { get; } = []; public static Dictionary> ExploreItems { get; } = []; public static List ItemSkills { get; } = []; public static List AllItems { get; } = []; @@ -303,6 +305,26 @@ namespace Oshima.FunGame.OshimaServers.Service new 铎京城() ]; + private readonly static Dictionary _precomputeTotalExperience = []; + public static Dictionary PrecomputeTotalExperience + { + get + { + if (_precomputeTotalExperience.Count == 0) + { + double sum = 0; + _precomputeTotalExperience[0] = 0; + for (int i = 2; i <= General.GameplayEquilibriumConstant.MaxLevel; i++) + { + sum += General.GameplayEquilibriumConstant.EXPUpperLimit[i - 1]; + _precomputeTotalExperience[i] = sum; + } + return _precomputeTotalExperience; + } + return _precomputeTotalExperience; + } + } + public static Dictionary ExploreResultProbabilities { get; } = new() { { ExploreResult.General, 0.45 }, @@ -376,6 +398,8 @@ namespace Oshima.FunGame.OshimaServers.Service { QualityType.Gold, (67000, 130000) } }; + public static string[] GreekAlphabet { get; } = ["α", "β", "γ", "δ", "ε", "ζ", "η", "θ", "ι", "κ", "λ", "μ", "ν", "ξ", "ο", "π", "ρ", "σ", "τ", "υ", "φ", "χ", "ψ", "ω"]; + public static string[] CommonSurnames { get; } = [ "顾", "沈", "陆", "楚", "白", "苏", "叶", "萧", "莫", "司马", "欧阳", "上官", "慕容", "尉迟", "司徒", "轩辕", "端木", "南宫", "长孙", "百里", diff --git a/OshimaServers/Service/FunGameOrderList.cs b/OshimaServers/Service/FunGameOrderList.cs index bbbaacf..a93ba21 100644 --- a/OshimaServers/Service/FunGameOrderList.cs +++ b/OshimaServers/Service/FunGameOrderList.cs @@ -69,7 +69,7 @@ {"生命之泉", "使用金币回复角色状态"}, }; - public static Dictionary QuestHelp { get; } = new() { + public static Dictionary PlayHelp { get; } = new() { {"任务列表", "查看今日任务列表"}, {"做任务 <任务序号>", "开始指定任务"}, {"任务信息", "查看进行中任务详情"}, @@ -79,6 +79,12 @@ {"查地区 <地区序号>", "查看指定地区信息"}, {"探索 <地区序号> <{角色序号...}>", "探索指定地区(可多角色)"}, {"探索结算", "结算所有未完成的探索"}, + {"挑战金币秘境 <难度>", "以小队挑战金币秘境,秘境难度1-5"}, + {"挑战材料秘境 <难度>", "以小队挑战材料秘境,秘境难度1-5"}, + {"挑战经验秘境 <难度>", "以小队挑战经验秘境,秘境难度1-5"}, + {"挑战地区秘境 <难度>", "以小队挑战地区锻造材料秘境,秘境难度1-5"}, + {"挑战突破秘境 <难度>", "以小队挑战角色突破材料秘境,秘境难度1-5"}, + {"挑战技能秘境 <难度>", "以小队挑战技能升级材料秘境,秘境难度1-5"}, }; public static Dictionary ClubHelp { get; } = new() { diff --git a/OshimaServers/Service/FunGameService.cs b/OshimaServers/Service/FunGameService.cs index 724c95b..b3044f6 100644 --- a/OshimaServers/Service/FunGameService.cs +++ b/OshimaServers/Service/FunGameService.cs @@ -1,3 +1,4 @@ +using System.Reflection; using System.Text; using Milimoe.FunGame.Core.Api.Transmittal; using Milimoe.FunGame.Core.Api.Utility; @@ -76,6 +77,8 @@ namespace Oshima.FunGame.OshimaServers.Service } FunGameConstant.DrawCardItems.AddRange(FunGameConstant.AllItems.Where(i => !FunGameConstant.ItemCanNotDrawCard.Contains(i.ItemType))); + FunGameConstant.CharacterLevelBreakItems.AddRange([new 升华之印(), new 流光之印(), new 永恒之印()]); + FunGameConstant.SkillLevelUpItems.AddRange([new 技能卷轴(), new 智慧之果(), new 奥术符文(), new 混沌之核()]); FunGameConstant.AllItems.AddRange(FunGameConstant.ExploreItems.Values.SelectMany(list => list)); @@ -1961,22 +1964,7 @@ namespace Oshima.FunGame.OshimaServers.Service { if (FunGameConstant.AllItems.FirstOrDefault(i => i.Name == item.Name) != null) { - Item newItem = item.Copy(); - newItem.User = user; - if (newItem.QualityType >= QualityType.Orange) newItem.IsLock = true; - SetSellAndTradeTime(newItem); - int min = 0, max = 0; - if (FunGameConstant.PriceRanges.TryGetValue(item.QualityType, out (int Min, int Max) range)) - { - (min, max) = (range.Min, range.Max); - } - double price = Random.Shared.Next(min, max) * 0.35; - newItem.Price = price; - user.Inventory.Items.Add(newItem); - // 连接到任务系统 - AddExploreItemCache(user.Id, item.Name); - // 连接到活动系统 - ActivitiesItemCache.Add(item.Name); + AddItemToUserInventory(user, item); } } } @@ -2556,7 +2544,7 @@ namespace Oshima.FunGame.OshimaServers.Service int exp = 0; for (int i = 0; i < characterCount; i++) { - exp += Random.Shared.Next(100, 300) * diff; + exp += Random.Shared.Next(300, 750) * diff; } model.Awards["exp"] = exp; exploreString += $"额外获得了:{exp} 点经验值(探索队员们平分)!"; @@ -2595,7 +2583,8 @@ namespace Oshima.FunGame.OshimaServers.Service // 开始战斗 Team team1 = new($"{user.Username}的探索小队", squad); Team team2 = new($"{region.Name}", enemys); - List msgs = await FunGameActionQueue.NewAndStartTeamGame([team1, team2], showAllRound: true); + FunGameActionQueue actionQueue = new(); + List msgs = await actionQueue.StartTeamGame([team1, team2], showAllRound: true); if (msgs.Count > 2) { msgs = msgs[^2..]; @@ -2608,11 +2597,15 @@ namespace Oshima.FunGame.OshimaServers.Service { credits += Random.Shared.Next(400, 650) * diff; } + if (actionQueue.GamingQueue.EarnedMoney.Count > 0) + { + credits += actionQueue.GamingQueue.EarnedMoney.Where(kv => squad.Contains(kv.Key)).Sum(kv => kv.Value); + } model.CreditsAward = credits; exp = 0; for (int i = 0; i < characterCount; i++) { - exp += Random.Shared.Next(250, 520) * diff; + exp += Random.Shared.Next(370, 860) * diff; } model.Awards["exp"] = exp; int materials = 0; @@ -2628,7 +2621,7 @@ namespace Oshima.FunGame.OshimaServers.Service count += Math.Max(1, Random.Shared.Next(1, 4) * diff / 2); } model.Awards[item.Name] = count; - award = $"{credits} {General.GameplayEquilibriumConstant.InGameCurrency}," + $"{exp} 点经验值(探索队员们平分)," + + award = $"{credits} {General.GameplayEquilibriumConstant.InGameCurrency}(包含战斗中击杀奖励)," + $"{exp} 点经验值(探索队员们平分)," + $"{materials} {General.GameplayEquilibriumConstant.InGameMaterial}," + $"以及 {count} 个{item.Name}"; if (Random.Shared.NextDouble() > 0.6) { @@ -2751,22 +2744,7 @@ namespace Oshima.FunGame.OshimaServers.Service { for (int i = 0; i < model.Awards[name]; i++) { - Item newItem = item.Copy(); - newItem.User = user; - if (newItem.QualityType >= QualityType.Orange) newItem.IsLock = true; - SetSellAndTradeTime(newItem); - int min = 0, max = 0; - if (FunGameConstant.PriceRanges.TryGetValue(item.QualityType, out (int Min, int Max) range)) - { - (min, max) = (range.Min, range.Max); - } - double price = Random.Shared.Next(min, max) * 0.35; - newItem.Price = price; - user.Inventory.Items.Add(newItem); - // 连接到任务系统 - AddExploreItemCache(user.Id, item.Name); - // 连接到活动系统 - ActivitiesItemCache.Add(item.Name); + AddItemToUserInventory(user, item); } } } @@ -3350,5 +3328,345 @@ namespace Oshima.FunGame.OshimaServers.Service } return "服务器繁忙,请稍后再试。"; } + + public static void AddItemToUserInventory(User user, Item item, bool hasLock = true, bool hasSellAndTradeTime = true, bool hasPrice = true, double price = 0, bool toExploreCache = true, bool toActivitiesCache = true) + { + Item newItem = item.Copy(); + newItem.User = user; + if (hasLock && newItem.QualityType >= QualityType.Orange) newItem.IsLock = true; + if (hasSellAndTradeTime) SetSellAndTradeTime(newItem); + if (hasPrice) + { + if (price == 0) + { + int min = 0, max = 0; + if (FunGameConstant.PriceRanges.TryGetValue(item.QualityType, out (int Min, int Max) range)) + { + (min, max) = (range.Min, range.Max); + } + price = Random.Shared.Next(min, max) * 0.35; + } + newItem.Price = price; + } + user.Inventory.Items.Add(newItem); + // 连接到任务系统 + if (toExploreCache) AddExploreItemCache(user.Id, item.Name); + // 连接到活动系统 + if (toActivitiesCache) ActivitiesItemCache.Add(item.Name); + } + + public static async Task FightInstance(InstanceType type, int difficulty, User user, Character[] squad) + { + if (difficulty <= 0) difficulty = 1; + else if (difficulty > 5) difficulty = 5; + + StringBuilder builder = new(); + + // 生成敌人 + int enemyCount = difficulty switch + { + 1 => 2, + 2 => 3, + 3 => 4, + 4 => 5, + _ => 6 + }; + + List enemys = []; + for (int i = 0; i < enemyCount; i++) + { + Character? enemy = FunGameConstant.Regions.SelectMany(r => r.Units).OrderBy(o => Random.Shared.Next()).FirstOrDefault(); + if (enemy != null) + { + enemy = enemy.Copy(); + int dcount = enemys.Count(e => e.Name == enemy.Name); + if (dcount > 0 && FunGameConstant.GreekAlphabet.Length > dcount) enemy.Name += FunGameConstant.GreekAlphabet[dcount - 1]; + enemys.Add(enemy); + } + } + + Item[] weapons = [.. FunGameConstant.Equipment.Where(i => i.Id.ToString().StartsWith("11") && (int)i.QualityType == 5)]; + Item[] armors = [.. FunGameConstant.Equipment.Where(i => i.Id.ToString().StartsWith("12") && (int)i.QualityType == 5)]; + Item[] shoes = [.. FunGameConstant.Equipment.Where(i => i.Id.ToString().StartsWith("13") && (int)i.QualityType == 5)]; + Item[] accessory = [.. FunGameConstant.Equipment.Where(i => i.Id.ToString().StartsWith("14") && (int)i.QualityType == 5)]; + Item[] consumables = [.. FunGameConstant.AllItems.Where(i => i.ItemType == ItemType.Consumable && i.IsInGameItem)]; + int cLevel = difficulty * 8; + int sLevel = difficulty; + int mLevel = difficulty + 1; + int naLevel = mLevel; + foreach (Character enemy_loop in enemys) + { + EnhanceBoss(enemy_loop, weapons, armors, shoes, accessory, consumables, cLevel, sLevel, mLevel, naLevel, false, false, true); + } + + // 开始战斗 + Team team1 = new($"{user.Username}的小队", squad); + Team team2 = new($"{General.GameplayEquilibriumConstant.InGameCurrency}秘境", enemys); + FunGameActionQueue actionQueue = new(); + List msgs = await actionQueue.StartTeamGame([team1, team2], showAllRound: true); + if (msgs.Count > 2) + { + msgs = msgs[^2..]; + } + int award = 0; + int characterCount = squad.Length; + builder.AppendLine($"☆--- {team2.Name}挑战 ---☆"); + builder.AppendLine(string.Join("\r\n", msgs)); + if (enemys.All(c => c.HP <= 0)) + { + builder.Append($"探索小队战胜了敌人!获得了:"); + switch (type) + { + case InstanceType.Currency: + for (int i = 0; i < characterCount; i++) + { + award += Random.Shared.Next(550, 1050) * difficulty; + } + user.Inventory.Credits += award; + // 这个只是展示,实际上在战斗过程中已经加过了 + if (actionQueue.GamingQueue.EarnedMoney.Count > 0) + { + award += actionQueue.GamingQueue.EarnedMoney.Where(kv => squad.Contains(kv.Key)).Sum(kv => kv.Value); + } + builder.AppendLine($"{award} {General.GameplayEquilibriumConstant.InGameCurrency}(包含战斗中击杀奖励)!"); + break; + case InstanceType.Material: + for (int i = 0; i < characterCount; i++) + { + award += Random.Shared.Next(4, 9) * difficulty; + } + user.Inventory.Materials += award; + builder.AppendLine($"{award} {General.GameplayEquilibriumConstant.InGameMaterial}!"); + break; + case InstanceType.EXP: + for (int i = 0; i < characterCount; i++) + { + award += Random.Shared.Next(570, 1260) * difficulty; + } + double overflowExp = 0; + double avgExp = award / characterCount; + int small = 0, medium = 0, large = 0; + award = 0; + foreach (Character character in squad) + { + double currentExp = FunGameConstant.PrecomputeTotalExperience[character.Level] + character.EXP; + if (currentExp + avgExp > FunGameConstant.PrecomputeTotalExperience[General.GameplayEquilibriumConstant.MaxLevel]) + { + overflowExp = Math.Min(FunGameConstant.PrecomputeTotalExperience[General.GameplayEquilibriumConstant.MaxLevel], currentExp) + avgExp - FunGameConstant.PrecomputeTotalExperience[General.GameplayEquilibriumConstant.MaxLevel]; + while (overflowExp > 0) + { + if (overflowExp >= 1000) + { + large++; + overflowExp -= 1000; + } + else if (overflowExp >= 500) + { + medium++; + overflowExp -= 500; + } + else if (overflowExp >= 200) + { + small++; + overflowExp -= 200; + } + else + { + small++; + overflowExp = 0; + } + } + } + else + { + character.EXP += avgExp; + award += (int)avgExp; + } + } + List expBook = []; + if (large > 0) + { + expBook.Add($"{large} 个大经验书"); + for (int i = 0; i < large; i++) + { + AddItemToUserInventory(user, new 大经验书()); + } + } + if (medium > 0) + { + expBook.Add($"{medium} 个中经验书"); + for (int i = 0; i < medium; i++) + { + AddItemToUserInventory(user, new 中经验书()); + } + } + if (small > 0) + { + expBook.Add($"{small} 个小经验书"); + for (int i = 0; i < small; i++) + { + AddItemToUserInventory(user, new 小经验书()); + } + } + builder.AppendLine($"{award} 点经验值(分配给经验未满的角色们){(expBook.Count > 0 ? $",附赠:{string.Join("、", expBook)}" : "")}!"); + break; + case InstanceType.RegionItem: + List regionItems = []; + for (int i = 0; i < characterCount; i++) + { + OshimaRegion region = FunGameConstant.Regions[Random.Shared.Next(FunGameConstant.Regions.Count)]; + Item item = FunGameConstant.ExploreItems[region][Random.Shared.Next(FunGameConstant.ExploreItems[region].Count)]; + award = Math.Max(2, Random.Shared.Next(2, 5) * difficulty / 2); + regionItems.Add($"{award} 个 {item.Name}(来自{region.Name})"); + AddItemToUserInventory(user, item); + } + builder.AppendLine($"{string.Join("、", regionItems)}!"); + break; + case InstanceType.CharacterLevelBreak: + List characterLevelBreakItems = []; + for (int i = 0; i < characterCount; i++) + { + Item item = FunGameConstant.CharacterLevelBreakItems[Random.Shared.Next(FunGameConstant.CharacterLevelBreakItems.Count)]; + award = Math.Max(1, Random.Shared.Next(1, 4) * difficulty / 2); + characterLevelBreakItems.Add($"{award} 个 {item.Name}"); + AddItemToUserInventory(user, item); + } + builder.AppendLine($"{string.Join("、", characterLevelBreakItems)}!"); + break; + case InstanceType.SkillLevelUp: + List skillLevelUpItems = []; + for (int i = 0; i < characterCount; i++) + { + Item item = FunGameConstant.SkillLevelUpItems[Random.Shared.Next(FunGameConstant.SkillLevelUpItems.Count)]; + award = Math.Max(1, Random.Shared.Next(1, 4) * difficulty / 2); + skillLevelUpItems.Add($"{award} 个 {item.Name}"); + AddItemToUserInventory(user, item); + } + builder.AppendLine($"{string.Join("、", skillLevelUpItems)}!"); + break; + default: + break; + } + } + else + { + builder.Append($"小队未能战胜敌人,"); + IEnumerable deadEnemys = enemys.Where(c => c.HP <= 0); + if (!deadEnemys.Any()) + { + builder.AppendLine("无法获取秘境奖励!"); + } + else + { + builder.Append("但是获得了战斗失败补偿:"); + // 根据死亡敌人的数量生成补偿奖励 + int count = deadEnemys.Count(); + switch (type) + { + case InstanceType.Currency: + award = 100 * difficulty * count; + user.Inventory.Credits += award; + // 这个只是展示,实际上在战斗过程中已经加过了 + if (actionQueue.GamingQueue.EarnedMoney.Count > 0) + { + award += actionQueue.GamingQueue.EarnedMoney.Where(kv => squad.Contains(kv.Key)).Sum(kv => kv.Value); + } + builder.AppendLine($"{award} {General.GameplayEquilibriumConstant.InGameCurrency}(包含战斗中击杀奖励)!"); + break; + case InstanceType.Material: + award = (int)(0.5 * difficulty * count); + if (award <= 0) award = 1; + user.Inventory.Materials += award; + builder.AppendLine($"{award} {General.GameplayEquilibriumConstant.InGameMaterial}!"); + break; + case InstanceType.EXP: + award = 300 * difficulty * count; + double overflowExp = 0; + double avgExp = (award / characterCount); + int small = 0, medium = 0, large = 0; + award = 0; + foreach (Character character in squad) + { + double currentExp = FunGameConstant.PrecomputeTotalExperience[character.Level] + character.EXP; + if (currentExp + avgExp > FunGameConstant.PrecomputeTotalExperience[General.GameplayEquilibriumConstant.MaxLevel]) + { + overflowExp = Math.Min(FunGameConstant.PrecomputeTotalExperience[General.GameplayEquilibriumConstant.MaxLevel], currentExp) + avgExp - FunGameConstant.PrecomputeTotalExperience[General.GameplayEquilibriumConstant.MaxLevel]; + while (overflowExp > 0) + { + if (overflowExp >= 1000) + { + large++; + overflowExp -= 1000; + } + else if (overflowExp >= 500) + { + medium++; + overflowExp -= 500; + } + else if (overflowExp >= 200) + { + small++; + overflowExp -= 200; + } + else + { + small++; + overflowExp = 0; + } + } + } + else + { + character.EXP += avgExp; + award += (int)avgExp; + } + } + List expBook = []; + if (large > 0) + { + expBook.Add($"{large} 个大经验书"); + for (int i = 0; i < large; i++) + { + AddItemToUserInventory(user, new 大经验书()); + } + } + if (medium > 0) + { + expBook.Add($"{medium} 个中经验书"); + for (int i = 0; i < medium; i++) + { + AddItemToUserInventory(user, new 中经验书()); + } + } + if (small > 0) + { + expBook.Add($"{small} 个小经验书"); + for (int i = 0; i < small; i++) + { + AddItemToUserInventory(user, new 小经验书()); + } + } + builder.AppendLine($"{award} 点经验值(分配给经验未满的角色们){(expBook.Count > 0 ? $",附赠:{string.Join("、", expBook)}" : "")}!"); + break; + case InstanceType.RegionItem: + List regionItems = []; + for (int i = 0; i < count; i++) + { + OshimaRegion region = FunGameConstant.Regions[Random.Shared.Next(FunGameConstant.Regions.Count)]; + Item item = FunGameConstant.ExploreItems[region][Random.Shared.Next(FunGameConstant.ExploreItems[region].Count)]; + award = 1; + regionItems.Add($"{award} 个 {item.Name}(来自{region.Name})"); + AddItemToUserInventory(user, item); + } + builder.AppendLine($"{string.Join("、", regionItems)}!"); + break; + default: + break; + } + } + } + + return builder.ToString().Trim(); + } } } diff --git a/OshimaWebAPI/Controllers/FunGameController.cs b/OshimaWebAPI/Controllers/FunGameController.cs index b6b7235..34b5b25 100644 --- a/OshimaWebAPI/Controllers/FunGameController.cs +++ b/OshimaWebAPI/Controllers/FunGameController.cs @@ -10,6 +10,7 @@ using Milimoe.FunGame.Core.Library.Common.Event; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.SQLScript.Entity; using Oshima.Core.Configs; +using Oshima.Core.Constant; using Oshima.FunGame.OshimaModules.Characters; using Oshima.FunGame.OshimaModules.Items; using Oshima.FunGame.OshimaModules.Regions; @@ -1703,10 +1704,10 @@ namespace Oshima.FunGame.WebAPI.Controllers itemsCanUsedIndex = string.Join(",", itemsCanUsed.Select(kv => kv.Key)); } - var itemsSellable = items.Where(kv => kv.Value.IsSellable); + var itemsSellable = items.Where(kv => kv.Value.IsSellable && !kv.Value.IsLock); string itemsSellableIndex = string.Join(",", itemsSellable.Select(kv => kv.Key)); - var itemsTradable = items.Where(kv => kv.Value.IsTradable); + var itemsTradable = items.Where(kv => kv.Value.IsTradable && !kv.Value.IsLock); string itemsTradableIndex = string.Join(",", itemsTradable.Select(kv => kv.Key)); str += $"物品序号:{itemsIndex}\r\n"; @@ -6808,9 +6809,12 @@ namespace Oshima.FunGame.WebAPI.Controllers msg = "你没有权限使用此指令。"; } - user.LastTime = DateTime.Now; - pc.Add("user", user); - pc.SaveConfig(); + if (user.Id != target) + { + user.LastTime = DateTime.Now; + pc.Add("user", user); + pc.SaveConfig(); + } return msg; } @@ -6924,6 +6928,90 @@ namespace Oshima.FunGame.WebAPI.Controllers } } + [HttpPost("fightinstance")] + public async Task FightInstance([FromQuery] long? uid = null, [FromQuery] int type = 0, [FromQuery] int difficulty = 1) + { + 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); + int exploreTimes = 0; + + int[] supportedInstanceType = [(int)InstanceType.Currency, (int)InstanceType.Material, (int)InstanceType.EXP, (int)InstanceType.RegionItem]; + if (!supportedInstanceType.Contains(type)) + { + msg = $"秘境类型无效。"; + } + else if (user.Inventory.Squad.Count == 0) + { + msg = $"你尚未设置小队,请先设置1-4名角色!"; + } + else + { + Character[] squad = [.. user.Inventory.Characters.Where(c => user.Inventory.Squad.Contains(c.Id))]; + if (squad.All(c => c.HP < c.MaxHP * 0.1)) + { + msg = $"小队角色均重伤未愈,当前生命值低于 10%,请先等待生命值自动回复或重组小队!\r\n" + + $"当前小队角色如下:\r\n{FunGameService.GetSquadInfo(user.Inventory.Characters, user.Inventory.Squad)}"; + } + else + { + // 检查探索许可 + int reduce = difficulty * squad.Length; + if (pc.TryGetValue("exploreTimes", out object? value) && int.TryParse(value.ToString(), out exploreTimes)) + { + if (exploreTimes <= 0) + { + exploreTimes = 0; + msg = $"今日的探索许可已用完,无法再继续挑战秘境。"; + } + else if (reduce > exploreTimes) + { + msg = $"本次秘境挑战需要消耗 {reduce} 个探索许可,超过了你的剩余探索许可数量({exploreTimes} 个),请减少小队的角色数量或更改难度系数。" + + $"\r\n需要注意:难度系数一比一兑换探索许可,并且参与挑战的角色,都需要消耗相同数量的探索许可。"; + } + } + else + { + exploreTimes = FunGameConstant.MaxExploreTimes; + } + + if (msg == "") + { + exploreTimes -= reduce; + msg = await FunGameService.FightInstance((InstanceType)type, difficulty, user, squad); + if (msg != "") msg += "\r\n"; + msg += $"本次秘境挑战消耗探索许可 {reduce} 个,你的剩余探索许可:{exploreTimes} 个。"; + } + } + } + + user.LastTime = DateTime.Now; + pc.Add("user", user); + pc.Add("exploreTimes", exploreTimes); + pc.SaveConfig(); + + return msg; + } + else + { + return noSaved; + } + } + catch (Exception e) + { + Logger.LogError(e, "Error: {e}", e); + return busy; + } + } + [HttpPost("template")] public string Template([FromQuery] long? uid = null) { diff --git a/OshimaWebAPI/Services/RainBOTService.cs b/OshimaWebAPI/Services/RainBOTService.cs index 93afa68..5009b70 100644 --- a/OshimaWebAPI/Services/RainBOTService.cs +++ b/OshimaWebAPI/Services/RainBOTService.cs @@ -7,6 +7,7 @@ using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Library.Constant; using Oshima.Core.Configs; +using Oshima.Core.Constant; using Oshima.FunGame.OshimaServers.Service; using Oshima.FunGame.WebAPI.Constant; using Oshima.FunGame.WebAPI.Controllers; @@ -30,7 +31,7 @@ namespace Oshima.FunGame.WebAPI.Services Statics.RunningPlugin?.Controller.WriteLine(title, Milimoe.FunGame.Core.Library.Constant.LogLevel.Debug); if (msg is ThirdPartyMessage third) { - third.Result = "\r\n" + content.Trim(); + third.Result += "\r\n" + content.Trim(); third.IsCompleted = true; return; } @@ -168,7 +169,7 @@ namespace Oshima.FunGame.WebAPI.Services 2、角色帮助 3、物品帮助 4、战斗帮助 -5、任务帮助 +5、玩法帮助 6、社团帮助 7、活动帮助 8、商店帮助 @@ -195,10 +196,10 @@ namespace Oshima.FunGame.WebAPI.Services int page = e.Detail.Length > 4 && int.TryParse(e.Detail[4..], out int p) ? p : 1; await SendHelp(e, FunGameOrderList.BattleHelp, "战斗帮助", page); } - else if (e.Detail.StartsWith("任务帮助")) + else if (e.Detail.StartsWith("玩法帮助")) { int page = e.Detail.Length > 4 && int.TryParse(e.Detail[4..], out int p) ? p : 1; - await SendHelp(e, FunGameOrderList.QuestHelp, "任务帮助", page); + await SendHelp(e, FunGameOrderList.PlayHelp, "玩法帮助", page); } else if (e.Detail.StartsWith("社团帮助")) { @@ -496,40 +497,35 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail.StartsWith("生成指定")) { e.UseNotice = false; - string pattern = @"生成指定(\w+)魔法卡\s*(\d+)\s*(?:(\d+)\s+(\d+)\s+(\d+)(?:\s+(\d+))?)?(?:\s+(\d+))?(?:\s*给\s*(\d+))?"; + string pattern = @"生成指定(\w+)魔法卡\s*(\d+)(?:(?:\s*(\d+)\s+(\d+)\s+(\d+)(?:\s+(\d+))?)|(?:\s*(\d+)(?!\s*\d)))?(?:\s*给\s*(\d+))?"; Regex regex = new(pattern, RegexOptions.IgnoreCase); Match match = regex.Match(e.Detail); - if (match.Success) + if (match.Success && ((match.Groups[3].Success && match.Groups[4].Success && match.Groups[5].Success) || match.Groups[7].Success)) { string quality = match.Groups[1].Value; long magicID = long.Parse(match.Groups[2].Value); - int paramCount = match.Groups.Cast().Count(g => g.Success && g.Index > match.Groups[2].Index && g.Index < (match.Groups[8].Success ? match.Groups[8].Index : int.MaxValue)); - int str = 0, agi = 0, intelligence = 0, count = 1; long targetUserID = uid; - // 检查参数数量的有效性 - if (paramCount != 0 && paramCount != 1 && paramCount != 3 && paramCount != 4) - { - await SendAsync(e, "熟圣之力", "参数数量错误!可选参数必须为 1个(count)、3个(str, agi, intelligence)或4个(str, agi, intelligence, count)。"); - return result; - } - - if (paramCount == 1) - { - count = int.Parse(match.Groups[6].Success ? match.Groups[6].Value : match.Groups[7].Value); - } - else if (paramCount == 3 || paramCount == 4) + // 检查是否匹配到 str agi intelligence 模式 (Group 3, 4, 5) + if (match.Groups[3].Success && match.Groups[4].Success && match.Groups[5].Success) { str = int.Parse(match.Groups[3].Value); agi = int.Parse(match.Groups[4].Value); intelligence = int.Parse(match.Groups[5].Value); - if (paramCount == 4) + + // 如果此模式下有 count (Group 6) + if (match.Groups[6].Success) { count = int.Parse(match.Groups[6].Value); } } + // 否则,检查是否匹配到单独的 count 模式 (Group 7) + else if (match.Groups[7].Success) + { + count = int.Parse(match.Groups[7].Value); + } if (count <= 0) { @@ -550,7 +546,8 @@ namespace Oshima.FunGame.WebAPI.Services } else { - await SendAsync(e, "熟圣之力", "指令格式错误!正确格式:生成指定<品质>魔法卡 [str agi intelligence] [count]"); + await SendAsync(e, "熟圣之力", "指令格式错误!请检查格式:\r\n1、生成指定<品质>魔法卡 [str agi intelligence] [count] [给 ]\r\n" + + "2、生成指定<品质>魔法卡 [count] [给 ]\r\n注意:[str agi intelligence] 可选块的三个参数都必须完整提供。"); } return result; } @@ -1578,7 +1575,7 @@ namespace Oshima.FunGame.WebAPI.Services msgs = await Controller.FightCustom2(uid, detail.Trim(), true); } List real = []; - if (msgs.Count >= 2) + if (msgs.Count > 2) { if (msgs.Count < 20) { @@ -1602,8 +1599,9 @@ namespace Oshima.FunGame.WebAPI.Services } else { - real.Add(msgs[^2]); + real.Add(string.Join("\r\n", msgs[^8..^2])); } + real.Add(msgs[^2]); real.Add(msgs[^1]); } else @@ -2634,6 +2632,96 @@ namespace Oshima.FunGame.WebAPI.Services return result; } + if (e.Detail.StartsWith("挑战金币秘境")) + { + string detail = e.Detail.Replace("挑战金币秘境", "").Trim(); + string msg = ""; + if (int.TryParse(detail, out int diff)) + { + msg = await Controller.FightInstance(uid, (int)InstanceType.Currency, diff); + if (msg.Trim() != "") + { + await SendAsync(e, "挑战金币秘境", msg); + } + } + return result; + } + + if (e.Detail.StartsWith("挑战材料秘境")) + { + string detail = e.Detail.Replace("挑战材料秘境", "").Trim(); + string msg = ""; + if (int.TryParse(detail, out int diff)) + { + msg = await Controller.FightInstance(uid, (int)InstanceType.Material, diff); + if (msg.Trim() != "") + { + await SendAsync(e, "挑战材料秘境", msg); + } + } + return result; + } + + if (e.Detail.StartsWith("挑战经验秘境")) + { + string detail = e.Detail.Replace("挑战经验秘境", "").Trim(); + string msg = ""; + if (int.TryParse(detail, out int diff)) + { + msg = await Controller.FightInstance(uid, (int)InstanceType.EXP, diff); + if (msg.Trim() != "") + { + await SendAsync(e, "挑战经验秘境", msg); + } + } + return result; + } + + if (e.Detail.StartsWith("挑战地区秘境")) + { + string detail = e.Detail.Replace("挑战地区秘境", "").Trim(); + string msg = ""; + if (int.TryParse(detail, out int diff)) + { + msg = await Controller.FightInstance(uid, (int)InstanceType.RegionItem, diff); + if (msg.Trim() != "") + { + await SendAsync(e, "挑战地区秘境", msg); + } + } + return result; + } + + if (e.Detail.StartsWith("挑战突破秘境")) + { + string detail = e.Detail.Replace("挑战突破秘境", "").Trim(); + string msg = ""; + if (int.TryParse(detail, out int diff)) + { + msg = await Controller.FightInstance(uid, (int)InstanceType.CharacterLevelBreak, diff); + if (msg.Trim() != "") + { + await SendAsync(e, "挑战突破秘境", msg); + } + } + return result; + } + + if (e.Detail.StartsWith("挑战技能秘境")) + { + string detail = e.Detail.Replace("挑战技能秘境", "").Trim(); + string msg = ""; + if (int.TryParse(detail, out int diff)) + { + msg = await Controller.FightInstance(uid, (int)InstanceType.SkillLevelUp, diff); + if (msg.Trim() != "") + { + await SendAsync(e, "挑战技能秘境", msg); + } + } + return result; + } + if (uid == GeneralSettings.Master && e.Detail.StartsWith("重载FunGame", StringComparison.CurrentCultureIgnoreCase)) { string msg = Controller.Relaod(uid);