From 34501cf7a85fd64324d366c4e2080f5c81ae3486 Mon Sep 17 00:00:00 2001 From: milimoe Date: Fri, 31 Oct 2025 19:48:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E6=8A=80=E8=83=BD=E3=80=81=E7=A7=98?= =?UTF-8?q?=E5=A2=83=E6=8C=91=E6=88=98=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OshimaModules/Modules/SkillModule.cs | 1 + OshimaModules/Skills/被动/强攻.cs | 2 +- OshimaModules/Skills/被动/黑暗收割.cs | 71 +++++++++++ OshimaServers/Service/FunGameService.cs | 9 +- OshimaWebAPI/Controllers/FunGameController.cs | 117 ++++++++++-------- OshimaWebAPI/OshimaWebAPI.cs | 2 +- OshimaWebAPI/Services/RainBOTService.cs | 13 +- 7 files changed, 154 insertions(+), 61 deletions(-) create mode 100644 OshimaModules/Skills/被动/黑暗收割.cs diff --git a/OshimaModules/Modules/SkillModule.cs b/OshimaModules/Modules/SkillModule.cs index a22a6db..8a85b9b 100644 --- a/OshimaModules/Modules/SkillModule.cs +++ b/OshimaModules/Modules/SkillModule.cs @@ -128,6 +128,7 @@ namespace Oshima.FunGame.OshimaModules (long)PassiveID.致命节奏 => new 致命节奏(), (long)PassiveID.强攻 => new 强攻(), (long)PassiveID.电刑 => new 电刑(), + (long)PassiveID.黑暗收割 => new 黑暗收割(), (long)ItemPassiveID.攻击之爪 => new 攻击之爪技能(), (long)ItemActiveID.经验书 => new 经验书技能(), (long)ItemActiveID.礼包 => new 礼包技能(), diff --git a/OshimaModules/Skills/被动/强攻.cs b/OshimaModules/Skills/被动/强攻.cs index a1f4e89..b2add24 100644 --- a/OshimaModules/Skills/被动/强攻.cs +++ b/OshimaModules/Skills/被动/强攻.cs @@ -26,7 +26,7 @@ namespace Oshima.FunGame.OshimaModules.Skills { public override long Id => Skill.Id; public override string Name => Skill.Name; - public override string Description => $"连续3次普通攻击同一目标时,造成额外的 {额外伤害系数 * 100:0.##}% 伤害并使其进入易损状态,后续承受伤害提升 {易损伤害提升百分比 * 100:0.##}%,持续 {易损持续时间:0.##} {GameplayEquilibriumConstant.InGameTime}。"; + public override string Description => $"连续 3 次普通攻击同一目标时,造成额外的 {额外伤害系数 * 100:0.##}% 伤害并使其进入易损状态,后续承受伤害提升 {易损伤害提升百分比 * 100:0.##}%,持续 {易损持续时间:0.##} {GameplayEquilibriumConstant.InGameTime}。"; private double 易损伤害提升百分比 => Skill.Character != null ? 0.15 + Skill.Character.Level * 0.004 : 0.15; private double 额外伤害系数 => Skill.Character != null ? 0.06 + Skill.Character.Level * 0.005 : 0.06; diff --git a/OshimaModules/Skills/被动/黑暗收割.cs b/OshimaModules/Skills/被动/黑暗收割.cs new file mode 100644 index 0000000..66b8bb8 --- /dev/null +++ b/OshimaModules/Skills/被动/黑暗收割.cs @@ -0,0 +1,71 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 黑暗收割 : Skill + { + public override long Id => (long)PassiveID.黑暗收割; + public override string Name => "黑暗收割"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override string DispelDescription => Effects.Count > 0 ? Effects.First().DispelDescription : ""; + + public 黑暗收割(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 黑暗收割特效(this)); + } + + public override IEnumerable AddPassiveEffectToCharacter() + { + return Effects; + } + } + + public class 黑暗收割特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"对一半以下生命值的目标造成伤害时,将收集其灵魂以永久提升自身伤害,每个灵魂提供 {额外伤害提升 * 100:0.##}% 伤害加成。最多收集 {最多灵魂数量} 个灵魂。" + + $"若自身死亡,灵魂将损失一半。(当前灵魂数量:{当前灵魂数量} 个;伤害提升:{当前灵魂数量 * 额外伤害提升 * 100:0.##}%)"; + + private static double 额外伤害提升 => 0.02; + private int 当前灵魂数量 { get; set; } = 0; + private int 最多灵魂数量 => Skill.Character != null ? 10 + Skill.Character.Level / 10 * 5 : 10; + private bool 触发标记 { get; set; } = false; + + public override double AlterExpectedDamageBeforeCalculation(Character character, Character enemy, double damage, bool isNormalAttack, DamageType damageType, MagicType magicType, Dictionary totalDamageBonus) + { + if (character == Skill.Character && (enemy.HP / enemy.MaxHP) < 0.5) + { + 触发标记 = true; + return damage * 当前灵魂数量 * 额外伤害提升; + } + return 0; + } + + public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult) + { + if (触发标记 && character == Skill.Character && (damageResult == DamageResult.Normal || damageResult == DamageResult.Critical) && 当前灵魂数量 < 最多灵魂数量) + { + 触发标记 = false; + 当前灵魂数量++; + WriteLine($"[ {character} ] 通过黑暗收割收集了一个灵魂!当前灵魂数:{当前灵魂数量}"); + } + } + + public override void AfterDeathCalculation(Character death, Character? killer, Dictionary continuousKilling, Dictionary earnedMoney) + { + if (death == Skill.Character && 当前灵魂数量 > 0) + { + int lost = 当前灵魂数量 / 2; + 当前灵魂数量 -= lost; + WriteLine($"[ {death} ] 因死亡损失了 [ {lost} ] 个灵魂!"); + } + } + + public override void OnTurnEnd(Character character) + { + 触发标记 = false; + } + } +} diff --git a/OshimaServers/Service/FunGameService.cs b/OshimaServers/Service/FunGameService.cs index 10e7d43..ab18f03 100644 --- a/OshimaServers/Service/FunGameService.cs +++ b/OshimaServers/Service/FunGameService.cs @@ -52,7 +52,7 @@ namespace Oshima.FunGame.OshimaServers.Service FunGameConstant.PassiveSkills.AddRange([new META马(), new 心灵之火(), new 魔法震荡(), new 灵能反射(), new 智慧与力量(), new 致命打击(), new 毁灭之势(), new 枯竭打击(), new 破釜沉舟(), new 累积之压(), new 敏捷之刃(), new 弱者猎手()]); - FunGameConstant.CommonPassiveSkills.AddRange([new 征服者(), new 致命节奏(), new 强攻(), new 电刑()]); + FunGameConstant.CommonPassiveSkills.AddRange([new 征服者(), new 致命节奏(), new 强攻(), new 电刑(), new 黑暗收割()]); FunGameConstant.Magics.AddRange([new 冰霜攻击(), new 火之矢(), new 水之矢(), new 风之轮(), new 石之锤(), new 心灵之霞(), new 次元上升(), new 暗物质(), new 回复术(), new 治愈术(), new 复苏术(), new 圣灵术(), new 时间加速(), new 时间减速(), new 反魔法领域(), new 沉默十字(), new 虚弱领域(), new 混沌烙印(), new 凝胶稠絮(), @@ -3594,7 +3594,7 @@ namespace Oshima.FunGame.OshimaServers.Service if (toActivitiesCache) ActivitiesItemCache.Add(item.Name); } - public static async Task FightInstance(InstanceType type, int difficulty, User user, Character[] squad) + public static async Task<(bool, string)> FightInstance(InstanceType type, int difficulty, User user, Character[] squad) { if (difficulty <= 0) difficulty = 1; else if (difficulty > 5) difficulty = 5; @@ -3736,7 +3736,8 @@ namespace Oshima.FunGame.OshimaServers.Service int characterCount = squad.Length; builder.AppendLine($"☆--- {team2.Name}挑战 ---☆"); builder.AppendLine(string.Join("\r\n", msgs)); - if (enemys.All(c => c.HP <= 0)) + bool result = enemys.All(c => c.HP <= 0); + if (result) { builder.Append($"小队战胜了敌人!获得了:"); switch (type) @@ -4112,7 +4113,7 @@ namespace Oshima.FunGame.OshimaServers.Service } } - return builder.ToString().Trim(); + return (result, builder.ToString().Trim()); } public static Store? GetRegionStore(EntityModuleConfig stores, User user, string storeRegion, string storeName) diff --git a/OshimaWebAPI/Controllers/FunGameController.cs b/OshimaWebAPI/Controllers/FunGameController.cs index e9a12ab..06201c4 100644 --- a/OshimaWebAPI/Controllers/FunGameController.cs +++ b/OshimaWebAPI/Controllers/FunGameController.cs @@ -16,6 +16,7 @@ using Oshima.FunGame.OshimaModules.Models; using Oshima.FunGame.OshimaModules.Regions; using Oshima.FunGame.OshimaServers.Model; using Oshima.FunGame.OshimaServers.Service; +using ProjectRedbud.FunGame.SQLQueryExtension; namespace Oshima.FunGame.WebAPI.Controllers { @@ -440,53 +441,74 @@ namespace Oshima.FunGame.WebAPI.Controllers } [HttpPost("createsaved")] - public string CreateSaved([FromQuery] long? uid = null, [FromQuery] string? name = null) + public string CreateSaved([FromQuery] long? uid = null, [FromQuery] string? openid = null) { - string username = FunGameService.GenerateRandomChineseUserName(); using SQLHelper? sqlHelper = Factory.OpenFactory.GetSQLHelper(); - if (name != null && sqlHelper != null) + if (openid is null || openid.Trim() == "") + { + return "创建存档失败,未提供接入ID!"; + } + + if (sqlHelper != null) { try { - if (name.Trim() == "") - { - return "未提供接入ID!"; - } - Logger.LogInformation("[Reg] 接入ID:{name}", name); - sqlHelper.ExecuteDataSet(FunGameService.Select_CheckAutoKey(sqlHelper, name)); + Logger.LogInformation("[Reg] 接入ID:{openid}", openid); + sqlHelper.ExecuteDataSet(FunGameService.Select_CheckAutoKey(sqlHelper, openid)); if (sqlHelper.Success) { - return "你已经创建过存档!"; + return "你已经创建过存档!请使用【还原存档】指令或联系管理员处理。"; } - string password = name.Encrypt(name); sqlHelper.NewTransaction(); - sqlHelper.Execute(UserQuery.Insert_Register(sqlHelper, username, password, "", "", name)); - if (sqlHelper.Result == SQLResult.Success) + // 检查UID的用户在数据库中是否存在,如果已经存在则将OpenID(对应AutoKey字段)绑定到此用户上而不是创建新用户 + User? user = sqlHelper.GetUserById(uid ?? 0); + string username = ""; + if (user is null) { - sqlHelper.ExecuteDataSet(FunGameService.Select_CheckAutoKey(sqlHelper, name)); - if (sqlHelper.Success) + bool exist = true; + do { - User user = Factory.GetUser(sqlHelper.DataSet); - sqlHelper.Commit(); - user.Inventory.Credits = 5000; - Character character = new CustomCharacter(FunGameConstant.CustomCharacterId, username, nickname: username); - character.Recovery(); - user.Inventory.Characters.Add(character); - FunGameConstant.UserIdAndUsername[user.Id] = user; - PluginConfig pc = FunGameService.GetUserConfig(user.Id, out _); - FunGameService.SetUserConfigAndReleaseSemaphoreSlim(user.Id, pc, user); - return $"创建存档成功!你的昵称是【{username}】。"; + username = "FunOsm-" + Verification.CreateVerifyCode(VerifyCodeType.MixVerifyCode, 8); + if (sqlHelper.ExecuteDataRow(UserQuery.Select_IsExistUsername(sqlHelper, username)) is null) + { + exist = false; + } + } while (exist); + // 使用这种方法注册的用户,没有邮箱和UserKey,因此无法通过常规方式登录FunGame标准系统 + string password = Verification.CreateVerifyCode(VerifyCodeType.MixVerifyCode, 6).Encrypt(openid); + sqlHelper.RegisterUser(username, password, "", "", openid); + if (sqlHelper.Result == SQLResult.Success) + { + sqlHelper.ExecuteDataSet(FunGameService.Select_CheckAutoKey(sqlHelper, openid)); + if (sqlHelper.Success) + { + user = Factory.GetUser(sqlHelper.DataSet); + } + else + { + sqlHelper.Rollback(); + return "无法处理注册,创建存档失败!"; + } } else { + sqlHelper.Rollback(); return "无法处理注册,创建存档失败!"; } } - else - { - sqlHelper.Rollback(); - } + username = user.Username; + user.AutoKey = openid; + user.Inventory.Credits = 5000; + Character character = new CustomCharacter(FunGameConstant.CustomCharacterId, username, nickname: username); + character.Recovery(); + user.Inventory.Characters.Add(character); + FunGameConstant.UserIdAndUsername[user.Id] = user; + sqlHelper.UpdateUser(user); + sqlHelper.Commit(); + PluginConfig pc = FunGameService.GetUserConfig(user.Id, out _); + FunGameService.SetUserConfigAndReleaseSemaphoreSlim(user.Id, pc, user); + return $"创建存档成功!你的昵称是【{username}】。"; } catch (Exception e) { @@ -495,26 +517,8 @@ namespace Oshima.FunGame.WebAPI.Controllers } return "无法处理注册,创建存档失败!"; } - else if (uid != null && uid != 0) - { - PluginConfig pc = FunGameService.GetUserConfig(uid.Value, out _); - if (pc.Count == 0) - { - User user = Factory.GetUser(uid.Value, username, DateTime.Now, DateTime.Now, uid + "@qq.com", username); - user.Inventory.Credits = 5000; - user.Inventory.Characters.Add(new CustomCharacter(uid.Value, username)); - FunGameConstant.UserIdAndUsername[uid.Value] = user; - FunGameService.SetUserConfigAndReleaseSemaphoreSlim(uid.Value, pc, user); - return $"创建存档成功!你的昵称是【{username}】。"; - } - else - { - FunGameService.ReleaseUserSemaphoreSlim(uid.Value); - return "你已经创建过存档!"; - } - } - return "创建存档失败!"; + return "创建存档失败,SQL 服务不可用!"; } [HttpPost("restoresaved")] @@ -7685,6 +7689,7 @@ namespace Oshima.FunGame.WebAPI.Controllers { PluginConfig pc = FunGameService.GetUserConfig(userid, out _); + bool result = false; string msg = ""; if (pc.Count > 0) { @@ -7732,10 +7737,17 @@ namespace Oshima.FunGame.WebAPI.Controllers if (msg == "") { - exploreTimes -= reduce; - msg = await FunGameService.FightInstance((InstanceType)type, difficulty, user, squad); + (result, msg) = await FunGameService.FightInstance((InstanceType)type, difficulty, user, squad); if (msg != "") msg += "\r\n"; - msg += $"本次秘境挑战消耗探索许可 {reduce} 个,你的剩余探索许可:{exploreTimes} 个。"; + if (result) + { + exploreTimes -= reduce; + msg += $"本次秘境挑战消耗探索许可 {reduce} 个,你的剩余探索许可:{exploreTimes} 个。"; + } + else + { + msg += $"本次秘境挑战失败,不消耗任何探索许可,请继续加油!你的剩余探索许可:{exploreTimes} 个。"; + } } pc.Add("exploreTimes", exploreTimes); @@ -8234,8 +8246,7 @@ namespace Oshima.FunGame.WebAPI.Controllers } } - double points = 0; - if (pc.TryGetValue("forgepoints", out object? value) && double.TryParse(value.ToString(), out points)) + if (pc.TryGetValue("forgepoints", out object? value) && double.TryParse(value.ToString(), out double points)) { points += model.ResultPoints; } diff --git a/OshimaWebAPI/OshimaWebAPI.cs b/OshimaWebAPI/OshimaWebAPI.cs index afc6ce3..23c40b1 100644 --- a/OshimaWebAPI/OshimaWebAPI.cs +++ b/OshimaWebAPI/OshimaWebAPI.cs @@ -58,7 +58,7 @@ namespace Oshima.FunGame.WebAPI Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }; - bool result = bot.Handler(message).GetAwaiter().GetResult(); + bool result = bot.HandlerByConsole(message).GetAwaiter().GetResult(); if (!result || message.IsCompleted) { diff --git a/OshimaWebAPI/Services/RainBOTService.cs b/OshimaWebAPI/Services/RainBOTService.cs index fdc1b4c..82968e4 100644 --- a/OshimaWebAPI/Services/RainBOTService.cs +++ b/OshimaWebAPI/Services/RainBOTService.cs @@ -624,7 +624,7 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "创建存档") { e.UseNotice = false; - string msg = Controller.CreateSaved(name: openid); + string msg = Controller.CreateSaved(uid, openid); if (msg != "") { await SendAsync(e, "创建存档", "\r\n" + msg); @@ -1455,7 +1455,7 @@ namespace Oshima.FunGame.WebAPI.Services string itemIdsString = match.Groups["itemIds"].Value; string characterId = match.Groups["characterId"].Value; int[] characterIds = characterId != "" ? [int.Parse(characterId)] : [1]; - int[] itemIds = itemIdsString.Split(FunGameConstant.SplitChars, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); + int[] itemIds = [.. itemIdsString.Split(FunGameConstant.SplitChars, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse)]; if (itemIds.Length > 0) { string msg = Controller.UseItem4(uid, (itemIds, characterIds)); @@ -3648,6 +3648,15 @@ namespace Oshima.FunGame.WebAPI.Services return false; } + public async Task HandlerByConsole(IBotMessage e) + { + if (MemoryCache.Get(e.AuthorOpenId) is null) + { + MemoryCache.Set(e.AuthorOpenId, 1L, TimeSpan.FromMinutes(10)); + } + return await Handler(e); + } + public List MergeMessages(List msgs) { List real = [];