From 471f897d31df23875ac951ac629208d0f9c7566f Mon Sep 17 00:00:00 2001 From: milimoe Date: Sun, 10 May 2026 22:40:42 +0800 Subject: [PATCH] md 4 --- OshimaServers/Model/CSBettingModels.cs | 25 +++++ OshimaServers/Service/CSBettingService.cs | 105 ++++++++++++++++-- OshimaServers/Service/FunGameService.cs | 16 ++- .../Controllers/CSBettingController.cs | 30 +++++ .../Services/CSBettingInputHandler.cs | 81 +++++++++++++- OshimaWebAPI/Services/RainBOTService.cs | 83 ++++++++++++-- 6 files changed, 320 insertions(+), 20 deletions(-) diff --git a/OshimaServers/Model/CSBettingModels.cs b/OshimaServers/Model/CSBettingModels.cs index 05f03cf..110c300 100644 --- a/OshimaServers/Model/CSBettingModels.cs +++ b/OshimaServers/Model/CSBettingModels.cs @@ -104,6 +104,7 @@ namespace Oshima.FunGame.WebAPI.Model public MatchStatus Status { get; set; } public DateTime StartTime { get; set; } public string Stage { get; set; } = ""; + public string Description { get; set; } = ""; /// /// 竞猜截止时间 @@ -225,4 +226,28 @@ namespace Oshima.FunGame.WebAPI.Model [JsonPropertyName("team2_win_odds")] public decimal? Team2WinOdds { get; set; } } + + public class UpdateMatchRequest + { + [JsonPropertyName("uid")] + public long Uid { get; set; } + + [JsonPropertyName("match_id")] + public int MatchId { get; set; } + + [JsonPropertyName("team1_win_odds")] + public decimal? Team1WinOdds { get; set; } + + [JsonPropertyName("team2_win_odds")] + public decimal? Team2WinOdds { get; set; } + + [JsonPropertyName("start_time")] + public DateTime? StartTime { get; set; } + + [JsonPropertyName("bet_deadline")] + public DateTime? BetDeadline { get; set; } + + [JsonPropertyName("description")] + public string? Description { get; set; } + } } \ No newline at end of file diff --git a/OshimaServers/Service/CSBettingService.cs b/OshimaServers/Service/CSBettingService.cs index 6527e94..4701545 100644 --- a/OshimaServers/Service/CSBettingService.cs +++ b/OshimaServers/Service/CSBettingService.cs @@ -4,6 +4,7 @@ using Milimoe.FunGame.Core.Api.Transmittal; using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Library.Constant; using Oshima.FunGame.OshimaServers.Model; +using Oshima.FunGame.WebAPI.Model; namespace Oshima.FunGame.WebAPI.Services { @@ -147,8 +148,6 @@ namespace Oshima.FunGame.WebAPI.Services return ("暂无比赛赛程。", 1); int offset = (page - 1) * pageSize; - sql.Parameters["@offset"] = offset; - sql.Parameters["@limit"] = pageSize; sql.ExecuteDataSet($@" SELECT m.id, m.team1_name, m.team2_name, m.status, m.start_time, m.stage, @@ -157,8 +156,9 @@ namespace Oshima.FunGame.WebAPI.Services LEFT JOIN csbetting_events e ON m.event_id = e.id ORDER BY CASE m.status WHEN 1 THEN 0 WHEN 0 THEN 1 ELSE 2 END, - m.start_time ASC - LIMIT @limit OFFSET @offset"); + CASE WHEN m.status = 2 THEN m.start_time END DESC, + CASE WHEN m.status != 2 THEN m.start_time END ASC + LIMIT {pageSize} OFFSET {offset}"); if (!sql.Success || sql.DataSet.Tables.Count == 0 || sql.DataSet.Tables[0].Rows.Count == 0) return ("暂无比赛赛程。", 1); @@ -662,11 +662,11 @@ namespace Oshima.FunGame.WebAPI.Services .Where(s => s.Length > 0)]; string optionsJson = System.Text.Json.JsonSerializer.Serialize(options); - // 如果比赛包含比分或 MVP 选项,不允许自定义猜胜者赔率 + // 如果比赛包含比分或 MVP 选项,不允许自定义猜胜者奖励率 bool hasSpecialOption = options.Contains("score") || options.Contains("mvp"); if ((team1WinOdds.HasValue || team2WinOdds.HasValue) && hasSpecialOption) { - error = "比赛包含比分或MVP选项时,不能自定义猜胜者赔率。"; + error = "比赛包含比分或MVP选项时,不能自定义猜胜者奖励率。"; return false; } @@ -674,7 +674,7 @@ namespace Oshima.FunGame.WebAPI.Services decimal t2Odds = team2WinOdds ?? 2.50m; if (t1Odds <= 0 || t2Odds <= 0) { - error = "赔率必须大于0。"; + error = "奖励率必须大于0。"; return false; } @@ -732,6 +732,7 @@ namespace Oshima.FunGame.WebAPI.Services return false; } + sql.Parameters["@mid"] = matchId; sql.Execute("UPDATE csbetting_matches SET status = 1 WHERE id = @mid"); if (sql.Success) { @@ -745,5 +746,95 @@ namespace Oshima.FunGame.WebAPI.Services message = "更新比赛状态失败。"; return false; } + + public static bool UpdateMatch(UpdateMatchRequest request, out string error) + { + error = ""; + using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); + if (sql == null) + { + error = "数据库连接失败。"; + return false; + } + + // 检查比赛是否存在 + sql.Parameters["@mid"] = request.MatchId; + sql.ExecuteDataSet("SELECT status, available_options FROM csbetting_matches WHERE id = @mid"); + if (!sql.Success || sql.DataSet.Tables[0].Rows.Count == 0) + { + error = "比赛不存在。"; + return false; + } + + int status = Convert.ToInt32(sql.DataSet.Tables[0].Rows[0]["status"]); + if (status == 2) + { + error = "比赛已结束,无法修改。"; + return false; + } + + string available = sql.DataSet.Tables[0].Rows[0]["available_options"]?.ToString() ?? "[]"; + bool hasSpecial = available.Contains("score", StringComparison.OrdinalIgnoreCase) || available.Contains("mvp", StringComparison.OrdinalIgnoreCase); + + // 校验奖励率逻辑(同创建比赛) + if ((request.Team1WinOdds.HasValue || request.Team2WinOdds.HasValue) && hasSpecial) + { + error = "比赛包含比分或MVP选项时,不能修改猜胜者奖励率。"; + return false; + } + if ((request.Team1WinOdds.HasValue && request.Team1WinOdds <= 0) || + (request.Team2WinOdds.HasValue && request.Team2WinOdds <= 0)) + { + error = "奖励率必须大于0。"; + return false; + } + + // 构建动态UPDATE + StringBuilder setClause = new(); + if (request.Team1WinOdds.HasValue) + { + sql.Parameters["@t1od"] = request.Team1WinOdds.Value; + setClause.Append("team1_win_odds = @t1od, "); + } + if (request.Team2WinOdds.HasValue) + { + sql.Parameters["@t2od"] = request.Team2WinOdds.Value; + setClause.Append("team2_win_odds = @t2od, "); + } + if (request.StartTime.HasValue) + { + sql.Parameters["@st"] = request.StartTime.Value; + setClause.Append("start_time = @st, "); + } + if (request.BetDeadline.HasValue) + { + sql.Parameters["@ddl"] = request.BetDeadline.Value; + setClause.Append("bet_deadline = @ddl, "); + } + if (request.Description != null) + { + sql.Parameters["@desc"] = (object?)request.Description ?? DBNull.Value; + setClause.Append("description = @desc, "); + } + + if (setClause.Length == 0) + { + error = "没有提供任何修改参数。"; + return false; + } + + setClause.Remove(setClause.Length - 2, 2); // 移除最后的 ", " + sql.Parameters["@mid"] = request.MatchId; + string updateSql = $"UPDATE csbetting_matches SET {setClause} WHERE id = @mid"; + + sql.Execute(updateSql); + if (!sql.Success) + { + error = "修改比赛属性失败。"; + return false; + } + + return true; + } } } diff --git a/OshimaServers/Service/FunGameService.cs b/OshimaServers/Service/FunGameService.cs index be86b55..dd7a9b0 100644 --- a/OshimaServers/Service/FunGameService.cs +++ b/OshimaServers/Service/FunGameService.cs @@ -2585,7 +2585,7 @@ namespace Oshima.FunGame.OshimaServers.Service if (filteredActivities.Any()) { builder.AppendLine($"【{CommonSet.GetActivityStatus(state)}】"); - builder.AppendLine($"{string.Join("\r\n", filteredActivities.Select(a => a.GetIdName() + $"({a.GetTimeString(false)})"))}"); + builder.AppendLine($"{string.Join("\r\n", filteredActivities.Select(a => a.GetIdName().CreateCmdInput($"查活动 {a.Id}") + $"({a.GetTimeString(false)})"))}"); } } @@ -5068,7 +5068,7 @@ namespace Oshima.FunGame.OshimaServers.Service progressString = $"\r\n当前进度:{quest.Progress}/{quest.MaxProgress}"; } - string str = $"{quest.Id}. {quest.Name}\r\n" + + string str = $"{quest.Id}. {quest.Name.CreateCmdInput(BuildQuestCmdInput(quest, activity))}\r\n" + $"{quest.Description}\r\n" + (quest.QuestType == QuestType.Continuous ? $"需要时间:{quest.EstimatedMinutes} 分钟\r\n" : "") + (quest.StartTime.HasValue ? $"开始时间:{quest.StartTime.Value.ToString(General.GeneralDateTimeFormatChinese)}" + @@ -5091,6 +5091,18 @@ namespace Oshima.FunGame.OshimaServers.Service return str + progressString + (quest.SettleTime.HasValue ? $"\r\n结算时间:{quest.SettleTime.Value.ToString(General.GeneralDateTimeFormatChinese)}" : ""); } + public static string BuildQuestCmdInput(Quest quest, Activity? activity = null) + { + if (quest.Status == QuestState.InProgress) + { + return $"做{(activity is null ? "" : "活动")}任务 {quest.Id}"; + } + else + { + return activity is null ? "任务结算" : $"领取奖励 {activity.Id} {quest.Id}"; + } + } + public static void RefreshNotice() { Notices.LoadConfig(); diff --git a/OshimaWebAPI/Controllers/CSBettingController.cs b/OshimaWebAPI/Controllers/CSBettingController.cs index 51443b8..2e30bca 100644 --- a/OshimaWebAPI/Controllers/CSBettingController.cs +++ b/OshimaWebAPI/Controllers/CSBettingController.cs @@ -309,5 +309,35 @@ namespace Oshima.FunGame.WebAPI.Controllers return reply; } } + + [HttpPost("update-match")] + public BotReply UpdateMatch([FromBody] UpdateMatchRequest request) + { + MarkdownMessage md = new() { Content = busy }; + BotReply reply = new() { Markdown = md }; + try + { + if (!FunGameConstant.UserIdAndUsername.TryGetValue(request.Uid, out User? user) || (!user.IsAdmin && !user.IsOperator)) + { + md.Content = "你没有权限执行此操作。"; + return reply; + } + + if (CSBettingService.UpdateMatch(request, out string error)) + { + md.Content = $"比赛 {request.MatchId} 属性修改成功。"; + } + else + { + md.Content = error; + } + return reply; + } + catch (Exception e) + { + Logger.LogError(e, "UpdateMatch 异常"); + return reply; + } + } } } diff --git a/OshimaWebAPI/Services/CSBettingInputHandler.cs b/OshimaWebAPI/Services/CSBettingInputHandler.cs index 6799adf..3eb859d 100644 --- a/OshimaWebAPI/Services/CSBettingInputHandler.cs +++ b/OshimaWebAPI/Services/CSBettingInputHandler.cs @@ -94,7 +94,7 @@ namespace Oshima.FunGame.WebAPI.Services BotReply reply2 = BettingController.GetMyBets(uid, mid: matchId); if (reply.Markdown != null && reply.Markdown.Content != null && !(reply2.Markdown?.Content?.Equals("你还没有任何竞猜记录。") ?? true)) { - reply.Markdown.Content += reply2.Markdown.Content; + reply.Markdown.Content += (reply.Markdown.Content.Contains("点击下方按钮快速竞猜") ? "\r\n" : "") + reply2.Markdown.Content; } await SendAsync(e, "CS赛事竞猜", reply); } @@ -357,7 +357,7 @@ namespace Oshima.FunGame.WebAPI.Services return true; } - // 解析剩余参数:选项和赔率 + // 解析剩余参数:选项和奖励率 List optionParts = []; decimal? team1Odds = null, team2Odds = null; for (int i = 8; i < parts.Length; i++) @@ -427,10 +427,87 @@ namespace Oshima.FunGame.WebAPI.Services return true; } + // 指令:修改比赛 <比赛ID> [参数=值 ...] + if (e.Detail.StartsWith("修改比赛")) + { + e.UseNotice = false; + if (!FunGameConstant.UserIdAndUsername.TryGetValue(uid, out User? user) || (!user.IsAdmin && !user.IsOperator)) + { + await SendAsync(e, "修改比赛", "你没有权限执行此操作。"); + return true; + } + + string detail = e.Detail.Replace("修改比赛", "").Trim(); + string[] parts = detail.Split(' ', StringSplitOptions.RemoveEmptyEntries); + if (parts.Length < 2) + { + await SendAsync(e, "修改比赛", + "格式:修改比赛 <比赛ID> [参数=值]\r\n" + + "可用参数:t1od=<奖励率> t2od=<奖励率> st=<开始时间> ddl=<截止时间> des=<描述>\r\n" + + "时间格式:yyyy-MM-dd HH:mm\r\n" + + "示例:修改比赛 10 t1od=2.8 ddl=2026-05-12 18:00 des=\"决赛,Bo3\""); + return true; + } + + if (!int.TryParse(parts[0], out int matchId)) + { + await SendAsync(e, "修改比赛", "比赛ID必须为数字。"); + return true; + } + + // 解析剩余参数 key=value,支持引号包裹的含空格值 + UpdateMatchRequest request = new() { Uid = uid, MatchId = matchId }; + string remaining = string.Join(" ", parts[1..]); + // 使用正则匹配 key=value,value 可能带双引号 + System.Text.RegularExpressions.MatchCollection matches = GetParamValue().Matches(remaining); + foreach (System.Text.RegularExpressions.Match m in matches) + { + string key = m.Groups[1].Value; + string val = m.Groups[2].Success ? m.Groups[2].Value : m.Groups[3].Value; + + switch (key) + { + case "t1od": + if (decimal.TryParse(val, out decimal t1od)) request.Team1WinOdds = t1od; + else { await SendAsync(e, "修改比赛", "t1od 值无效。"); return true; } + break; + case "t2od": + if (decimal.TryParse(val, out decimal t2od)) request.Team2WinOdds = t2od; + else { await SendAsync(e, "修改比赛", "t2od 值无效。"); return true; } + break; + case "st": + if (DateTime.TryParse(val, out DateTime st)) request.StartTime = st; + else { await SendAsync(e, "修改比赛", "开始时间格式错误,请用 yyyy-MM-dd HH:mm。"); return true; } + break; + case "ddl": + if (DateTime.TryParse(val, out DateTime ddl)) request.BetDeadline = ddl; + else { await SendAsync(e, "修改比赛", "截止时间格式错误,请用 yyyy-MM-dd HH:mm。"); return true; } + break; + case "des": + request.Description = val; // 允许空字符串清空描述 + break; + default: + await SendAsync(e, "修改比赛", $"未知参数:{key}"); + return true; + } + } + + // 调用控制器API + BotReply reply = BettingController.UpdateMatch(request); + reply.Keyboard = new KeyboardMessage() + .AppendButtons(2, + Button.CreateCmdButton("📋 赛事列表", "赛事列表"), + Button.CreateCmdButton("🔍 比赛详情", $"比赛详情 {matchId}")); + await SendAsync(e, "修改比赛", reply); + return true; + } + return false; } [System.Text.RegularExpressions.GeneratedRegex(@"\d+")] private static partial System.Text.RegularExpressions.Regex GetFirstNumber(); + [System.Text.RegularExpressions.GeneratedRegex(@"(\w+)=(?:""([^""]*)""|(\S+))")] + private static partial System.Text.RegularExpressions.Regex GetParamValue(); } } diff --git a/OshimaWebAPI/Services/RainBOTService.cs b/OshimaWebAPI/Services/RainBOTService.cs index de2beb8..04ee789 100644 --- a/OshimaWebAPI/Services/RainBOTService.cs +++ b/OshimaWebAPI/Services/RainBOTService.cs @@ -1322,6 +1322,7 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "签到") { BotReply reply = Controller.SignIn(uid); + reply.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("帮助", "帮助")); await SendAsync(e, "签到", reply); return result; } @@ -2074,9 +2075,15 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "每日商店") { BotReply rpy = Controller.ShowDailyStore(uid); - rpy.Keyboard = new KeyboardMessage().AppendButtons(2, [ - Button.CreateCmdButton("商店查看", "商店查看", false), - Button.CreateCmdButton("商店购买", "商店购买", false) + rpy.Keyboard = new KeyboardMessage().AppendButtons(4, [ + Button.CreateCmdButton("查看1", "商店查看 1", false), + Button.CreateCmdButton("查看2", "商店查看 2", false), + Button.CreateCmdButton("查看3", "商店查看 3", false), + Button.CreateCmdButton("查看4", "商店查看 4", false), + Button.CreateCmdButton("购买1", "商店购买 1", false), + Button.CreateCmdButton("购买2", "商店购买 2", false), + Button.CreateCmdButton("购买3", "商店购买 3", false), + Button.CreateCmdButton("购买4", "商店购买 4", false) ]); await SendAsync(e, "商店", rpy); return result; @@ -2131,6 +2138,7 @@ namespace Oshima.FunGame.WebAPI.Services { reply = Controller.SystemStoreShowInfo(uid, model.StoreRegion, model.StoreName, id); } + reply.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("购买此商品", $"商店购买 {id}", false)); await SendAsync(e, "商店", reply); } return result; @@ -2191,7 +2199,7 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "探索结算") { BotReply reply = Controller.SettleExploreAll(uid); - await SendAsync(e, "探索结算", string.Join("\r\n", reply)); + await SendAsync(e, "探索结算", reply); return result; } @@ -2268,14 +2276,14 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "生命之泉") { BotReply reply = Controller.SpringOfLife(uid); - await SendAsync(e, "生命之泉", string.Join("\r\n", reply)); + await SendAsync(e, "生命之泉", reply); return result; } if (e.Detail == "酒馆" || e.Detail == "上酒") { BotReply reply = Controller.Pub(uid); - await SendAsync(e, "酒馆", string.Join("\r\n", reply)); + await SendAsync(e, "酒馆", reply); return result; } @@ -2284,7 +2292,7 @@ namespace Oshima.FunGame.WebAPI.Services if (FunGameService.Activities.FirstOrDefault(a => a.Name == "毕业季") is Activity activity && activity.Status == ActivityState.InProgress) { BotReply reply = Controller.CreateGiftBox(uid, "毕业礼包", true, 2); - await SendAsync(e, "毕业礼包", string.Join("\r\n", reply)); + await SendAsync(e, "毕业礼包", reply); } else { @@ -2296,7 +2304,7 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "活动" || e.Detail == "活动中心") { BotReply reply = Controller.GetEvents(uid); - await SendAsync(e, "活动中心", string.Join("\r\n", reply)); + await SendAsync(e, "活动中心", reply); return result; } @@ -2728,6 +2736,10 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "后勤部") { BotReply reply = Controller.ShowSystemStore(uid, "铎京城", "dokyo_logistics"); + reply.Keyboard = new KeyboardMessage().AppendButtons(2, [ + Button.CreateCmdButton("商店查看", "商店查看", false), + Button.CreateCmdButton("商店购买", "商店购买", false) + ]); await SendAsync(e, "商店", reply); return result; } @@ -2735,6 +2747,10 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "武器商会") { BotReply reply = Controller.ShowSystemStore(uid, "铎京城", "dokyo_weapons"); + reply.Keyboard = new KeyboardMessage().AppendButtons(2, [ + Button.CreateCmdButton("商店查看", "商店查看", false), + Button.CreateCmdButton("商店购买", "商店购买", false) + ]); await SendAsync(e, "商店", reply); return result; } @@ -2742,6 +2758,10 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "杂货铺") { BotReply reply = Controller.ShowSystemStore(uid, "铎京城", "dokyo_yuki"); + reply.Keyboard = new KeyboardMessage().AppendButtons(2, [ + Button.CreateCmdButton("商店查看", "商店查看", false), + Button.CreateCmdButton("商店购买", "商店购买", false) + ]); await SendAsync(e, "商店", reply); return result; } @@ -2749,6 +2769,10 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "基金会") { BotReply reply = Controller.ShowSystemStore(uid, "铎京城", "dokyo_welfare"); + reply.Keyboard = new KeyboardMessage().AppendButtons(2, [ + Button.CreateCmdButton("商店查看", "商店查看", false), + Button.CreateCmdButton("商店购买", "商店购买", false) + ]); await SendAsync(e, "商店", reply); return result; } @@ -2756,6 +2780,10 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "锻造商店") { BotReply reply = Controller.ShowSystemStore(uid, "铎京城", "dokyo_forge"); + reply.Keyboard = new KeyboardMessage().AppendButtons(2, [ + Button.CreateCmdButton("商店查看", "商店查看", false), + Button.CreateCmdButton("商店购买", "商店购买", false) + ]); await SendAsync(e, "商店", reply); return result; } @@ -2763,6 +2791,10 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "赛马商店") { BotReply reply = Controller.ShowSystemStore(uid, "铎京城", "dokyo_horseracing"); + reply.Keyboard = new KeyboardMessage().AppendButtons(2, [ + Button.CreateCmdButton("商店查看", "商店查看", false), + Button.CreateCmdButton("商店购买", "商店购买", false) + ]); await SendAsync(e, "商店", reply); return result; } @@ -2770,6 +2802,10 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail == "共斗商店") { BotReply reply = Controller.ShowSystemStore(uid, "铎京城", "dokyo_cooperative"); + reply.Keyboard = new KeyboardMessage().AppendButtons(2, [ + Button.CreateCmdButton("商店查看", "商店查看", false), + Button.CreateCmdButton("商店购买", "商店购买", false) + ]); await SendAsync(e, "商店", reply); return result; } @@ -2806,6 +2842,10 @@ namespace Oshima.FunGame.WebAPI.Services default: break; } + reply.Keyboard = new KeyboardMessage().AppendButtons(2, [ + Button.CreateCmdButton("商店查看", "商店查看", false), + Button.CreateCmdButton("商店购买", "商店购买", false) + ]); await SendAsync(e, "商店", reply); } return result; @@ -2841,7 +2881,12 @@ namespace Oshima.FunGame.WebAPI.Services FunGameService.GenerateForgeResult(user, model, true); if (model.ResultString != "") { - await SendAsync(e, "模拟锻造配方", model.ResultString); + BotReply reply = new() + { + Markdown = new() { Content = model.ResultString } + }; + reply = CreateForgeSystemButtons(reply); + await SendAsync(e, "模拟锻造配方", reply); } return result; } @@ -2868,6 +2913,7 @@ namespace Oshima.FunGame.WebAPI.Services } BotReply reply = Controller.ForgeItem_Create(uid, recipeItems); + reply = CreateForgeSystemButtons(reply); await SendAsync(e, "锻造配方", reply); return result; } @@ -2875,6 +2921,7 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail.StartsWith("模拟锻造")) { BotReply reply = Controller.ForgeItem_Simulate(uid); + reply = CreateForgeSystemButtons(reply); await SendAsync(e, "模拟锻造", reply); return result; } @@ -2882,6 +2929,7 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail.StartsWith("取消锻造")) { BotReply reply = Controller.ForgeItem_Cancel(uid); + reply = CreateForgeSystemButtons(reply); await SendAsync(e, "取消锻造", reply); return result; } @@ -2889,6 +2937,7 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail.StartsWith("确认开始锻造")) { BotReply reply = Controller.ForgeItem_Complete(uid); + reply = CreateForgeSystemButtons(reply); await SendAsync(e, "确认开始锻造", reply); return result; } @@ -2896,6 +2945,7 @@ namespace Oshima.FunGame.WebAPI.Services if (e.Detail.StartsWith("锻造信息")) { BotReply reply = Controller.ForgeItem_Info(uid); + reply = CreateForgeSystemButtons(reply); await SendAsync(e, "锻造信息", reply); return result; } @@ -2910,6 +2960,7 @@ namespace Oshima.FunGame.WebAPI.Services if (r != -1 && q != -1) { BotReply reply = Controller.ForgeItem_Master(uid, r, q); + reply = CreateForgeSystemButtons(reply); await SendAsync(e, "大师锻造", reply); } } @@ -3523,6 +3574,20 @@ namespace Oshima.FunGame.WebAPI.Services return real; } + public BotReply CreateForgeSystemButtons(BotReply reply) + { + reply.Keyboard ??= new KeyboardMessage(); + reply.Keyboard.AppendButtonsWithNewRow(2, [ + Button.CreateCmdButton("创建配方", "锻造配方", false), + Button.CreateCmdButton("模拟配方", "模拟锻造配方", false), + Button.CreateCmdButton("锻造信息", "锻造信息", false), + Button.CreateCmdButton("取消锻造", "取消锻造", false), + Button.CreateCmdButton("模拟锻造", "模拟锻造", false), + Button.CreateCmdButton("确认锻造", "确认开始锻造", false) + ]); + return reply; + } + public BotReply CreateMarkdownFromText(string text) { return new()