From 2f969d2ebde2b09f966e19de82e2fde2dc0c5100 Mon Sep 17 00:00:00 2001 From: milimoe Date: Sun, 3 May 2026 17:43:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B4=BB=E5=8A=A8=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E9=80=BB=E8=BE=91=EF=BC=8C=E6=B7=BB=E5=8A=A0markdown?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E5=8F=91=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OshimaServers/Service/FunGameService.cs | 43 +++-- OshimaWebAPI/Controllers/FunGameController.cs | 1 + OshimaWebAPI/Controllers/QQBotController.cs | 54 ++++-- OshimaWebAPI/Models/QQBot.cs | 162 ++++++++++++++++++ OshimaWebAPI/OshimaWebAPI.cs | 2 +- OshimaWebAPI/Services/QQBotService.cs | 79 +++++++-- OshimaWebAPI/Services/RainBOTService.cs | 32 +++- 7 files changed, 331 insertions(+), 42 deletions(-) diff --git a/OshimaServers/Service/FunGameService.cs b/OshimaServers/Service/FunGameService.cs index f4032f6..f41e24d 100644 --- a/OshimaServers/Service/FunGameService.cs +++ b/OshimaServers/Service/FunGameService.cs @@ -2549,14 +2549,26 @@ namespace Oshima.FunGame.OshimaServers.Service } ActivitiesEventCache.RemoveAll(willRemove.Contains); } + foreach (Activity activity in Activities) + { + if (user != null && (activity.Status == ActivityState.InProgress || activity.Status == ActivityState.Ended)) + { + if (SettleQuest(user, activity.Quests, activity)) + { + update = true; + } + } + if (activity.Predecessor != -1 && Activities.FirstOrDefault(a => a.Id == activity.Predecessor) is Activity preActivity) + { + activity.PredecessorStatus = preActivity.Status; + activity.UpdateState(); + update = true; + } + } if (update) { foreach (Activity activity in Activities) { - if (user != null && (activity.Status == ActivityState.InProgress || activity.Status == ActivityState.Ended)) - { - SettleQuest(user, activity.Quests, activity); - } activities.Add(activity.Id.ToString(), activity); } activities.SaveConfig(); @@ -2565,7 +2577,7 @@ namespace Oshima.FunGame.OshimaServers.Service StringBuilder builder = new(); builder.AppendLine("★☆★ 活动中心 ★☆★"); - ActivityState[] status = [ActivityState.InProgress, ActivityState.Upcoming, ActivityState.Future, ActivityState.Ended]; + ActivityState[] status = [ActivityState.InProgress, ActivityState.ClaimPeriod, ActivityState.Upcoming, ActivityState.Future, ActivityState.Ended]; foreach (ActivityState state in status) { IEnumerable filteredActivities = activities.Values.Where(a => a.Status == state); @@ -2599,7 +2611,7 @@ namespace Oshima.FunGame.OshimaServers.Service GetEventCenter(user); if (Activities.FirstOrDefault(a => a.Id == id) is Activity activity) { - string result = activity.ToString(); + string result = GetActivityString(activity, true, false, user); if (user != null) { EntityModuleConfig userActivities = new("activities", user.Id.ToString()); @@ -2634,6 +2646,20 @@ namespace Oshima.FunGame.OshimaServers.Service return "该活动已删除!"; } + public static void SaveActivities() + { + lock (Activities) + { + EntityModuleConfig activities = new("activities", "activities"); + activities.LoadConfig(); + foreach (Activity activity in Activities) + { + activities.Add(activity.Id.ToString(), activity); + } + activities.SaveConfig(); + } + } + public static bool AddEventActivity(Activity activity, EntityModuleConfig userActivities) { if (activity.Id == 7 && activity.Status == ActivityState.InProgress) @@ -4997,10 +5023,7 @@ namespace Oshima.FunGame.OshimaServers.Service { for (int i = 0; i < qty; i++) { - if (FunGameConstant.AllItems.FirstOrDefault(i => i.Name == item.Name) != null) - { - AddItemToUserInventory(user, item, copyLevel: item.ItemType == ItemType.MagicCard); - } + AddItemToUserInventory(user, item, copyLevel: item.ItemType == ItemType.MagicCard); } } } diff --git a/OshimaWebAPI/Controllers/FunGameController.cs b/OshimaWebAPI/Controllers/FunGameController.cs index aeafabe..0112176 100644 --- a/OshimaWebAPI/Controllers/FunGameController.cs +++ b/OshimaWebAPI/Controllers/FunGameController.cs @@ -6664,6 +6664,7 @@ namespace Oshima.FunGame.WebAPI.Controllers { msg = awardString; activity.RegisterAwardedUser(user.Id, quest); + FunGameService.SaveActivities(); } else { diff --git a/OshimaWebAPI/Controllers/QQBotController.cs b/OshimaWebAPI/Controllers/QQBotController.cs index 8ad3467..bc6db44 100644 --- a/OshimaWebAPI/Controllers/QQBotController.cs +++ b/OshimaWebAPI/Controllers/QQBotController.cs @@ -22,7 +22,7 @@ namespace Oshima.FunGame.WebAPI.Controllers private RainBOTService FungameService { get; set; } = fungameService; [HttpPost] - public IActionResult Post([FromBody] Payload? payload) + public async Task Post([FromBody] Payload? payload) { if (payload is null) { @@ -40,7 +40,7 @@ namespace Oshima.FunGame.WebAPI.Controllers else if (payload.Op == 0) { // 处理其他事件 - return HandleEventAsync(payload); + return await HandleEventAsync(payload); } else { @@ -95,7 +95,7 @@ namespace Oshima.FunGame.WebAPI.Controllers return Ok(response); } - private IActionResult HandleEventAsync(Payload payload) + private async Task HandleEventAsync(Payload payload) { if (Logger.IsEnabled(LogLevel.Debug)) Logger.LogDebug("处理事件:{EventType}, 数据:{Data}", payload.EventType, payload.Data); @@ -119,21 +119,55 @@ namespace Oshima.FunGame.WebAPI.Controllers } // TODO if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("收到来自用户 {c2cMessage.Author.UserOpenId} 的消息:{c2cMessage.Content}", c2cMessage.Author.UserOpenId, c2cMessage.Content); - //// 上传图片 + // 上传图片 //string url = $"{Request.Scheme}://{Request.Host}{Request.PathBase}/images/zi/dj1.png"; - //var (fileUuid, fileInfo, ttl, error) = await _service.UploadC2CMediaAsync(c2cMessage.Author.UserOpenId, 1, url); - //_if (Logger.IsEnabled(LogLevel.Debug)) Logger.LogDebug("发送的图片地址:{url}", url); - //if (string.IsNullOrEmpty(error)) + //UploadMediaResult uploadMediaResult = await Service.UploadC2CMediaAsync(c2cMessage.Author.UserOpenId, 1, url); + //if (Logger.IsEnabled(LogLevel.Debug)) Logger.LogDebug("发送的图片地址:{url}", url); + //if (string.IsNullOrEmpty(uploadMediaResult.Error)) //{ // // 回复消息 - // await _service.SendC2CMessageAsync(c2cMessage.Author.UserOpenId, $"你发送的消息是:{c2cMessage.Content}", msgId: c2cMessage.Id); + // await Service.SendC2CMessageAsync(c2cMessage.Author.UserOpenId, $"你发送的消息是:{c2cMessage.Content}", msgId: c2cMessage.Id); // // 回复富媒体消息 - // await _service.SendC2CMessageAsync(c2cMessage.Author.UserOpenId, "", msgType: 7, media: new { file_info = fileInfo }, msgId: c2cMessage.Id); + // await Service.SendC2CMessageAsync(c2cMessage.Author.UserOpenId, "", msgType: 7, media: new { file_info = uploadMediaResult.FileInfo }, msgId: c2cMessage.Id); //} //else //{ - // _if (Logger.IsEnabled(LogLevel.Error)) Logger.LogError("上传图片失败:{error}", error); + // if (Logger.IsEnabled(LogLevel.Error)) Logger.LogError("上传图片失败:{error}", uploadMediaResult.Error); //} + // 发 md 示例 + //// 1. 带蓝字链接 + //MarkdownMessage mdMsg = new() + //{ + // Content = "请选择:\n" + //}; + //// 2. 带按钮 + //KeyboardMessage kbMsg = new() + //{ + // Content = new() + // { + // Rows = [ + // new() + // { + // Buttons = [ + // new() + // { + // Id = "btn1", + // RenderData = new RenderData { Label = "同意", VisitedLabel = "已同意", Style = 1 }, + // Action = new Models.Action + // { + // Type = 2, + // Data = "我同意服务条款", + // Enter = true, + // Reply = false, + // Permission = new Permission { Type = 2 } + // } + // } + // ] + // } + // ] + // } + //}; + //await Service.SendC2CMarkdownAsync(c2cMessage.AuthorOpenId, mdMsg, kbMsg, c2cMessage.Id); TaskUtility.NewTask(async () => await FungameService.Handler(c2cMessage, data)); } else diff --git a/OshimaWebAPI/Models/QQBot.cs b/OshimaWebAPI/Models/QQBot.cs index d1d604b..b1be436 100644 --- a/OshimaWebAPI/Models/QQBot.cs +++ b/OshimaWebAPI/Models/QQBot.cs @@ -213,6 +213,35 @@ namespace Oshima.FunGame.WebAPI.Models public int Ttl { get; set; } } + public class UploadMediaResult + { + /// + /// 文件 UUID,成功时有值 + /// + public string? FileUuid { get; set; } + + /// + /// 文件信息,成功时有值 + /// + public string? FileInfo { get; set; } + + /// + /// 有效期(秒) + /// + public int Ttl { get; set; } + + /// + /// 错误信息,成功时为 null + /// + public string? Error { get; set; } + + /// + /// 是否上传成功 + /// + [JsonIgnore] + public bool IsSuccess => string.IsNullOrEmpty(Error); + } + public class AccessTokenResponse { [JsonPropertyName("access_token")] @@ -226,4 +255,137 @@ namespace Oshima.FunGame.WebAPI.Models { public string RequestUrl { get; set; } = ""; } + public class MarkdownMessage + { + /// + /// 自定义 Markdown(和模板 ID 互斥,只能用一种方式) + /// + [JsonPropertyName("content")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Content { get; set; } + + /// + /// 模板 ID + /// + [JsonPropertyName("custom_template_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? CustomTemplateId { get; set; } + + /// + /// 模板参数列表(仅在模板模式下使用) + /// + [JsonPropertyName("params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? Params { get; set; } + } + + public class MarkdownParam + { + [JsonPropertyName("key")] + public string Key { get; set; } = ""; + + [JsonPropertyName("values")] + public List Values { get; set; } = []; + } + + public class KeyboardMessage + { + /// + /// 模板按钮 ID(与 content 互斥) + /// + [JsonPropertyName("id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Id { get; set; } + + /// + /// 自定义按钮内容 + /// + [JsonPropertyName("content")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public KeyboardContent? Content { get; set; } + } + + public class KeyboardContent + { + [JsonPropertyName("rows")] + public List Rows { get; set; } = []; + } + + public class Row + { + [JsonPropertyName("buttons")] + public List