md 改造

This commit is contained in:
milimoe 2026-05-06 01:34:21 +08:00
parent 2f969d2ebd
commit 9306de8b80
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
7 changed files with 673 additions and 230 deletions

View File

@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace Oshima.FunGame.WebAPI.Models
namespace Oshima.FunGame.OshimaServers.Models
{
public class Payload
{
@ -87,6 +87,149 @@ namespace Oshima.FunGame.WebAPI.Models
public string ImageUrl { get; set; }
}
public class BotReply
{
// 纯文本内容(兼容旧版)
public string? Text { get; set; }
// Markdown 消息(与 Text 互斥,若提供则发送 Markdown
public MarkdownMessage? Markdown { get; set; }
// Markdown 附带键盘(仅当 Markdown 不为 null 时有效)
public KeyboardMessage? Keyboard { get; set; }
// 方便从 string 隐式转换,旧代码无感知
public static implicit operator BotReply(string text) => new() { Text = text };
}
public static class BotReplyExtension
{
/// <summary>
/// 增加键盘按钮
/// </summary>
/// <param name="kb">键盘消息</param>
/// <param name="btnCountPerRow">每行按钮数量,自动检查如果超过则新建行</param>
/// <param name="buttons">按钮</param>
/// <returns></returns>
public static KeyboardMessage AppendButtons(this KeyboardMessage kb, int btnCountPerRow, params IEnumerable<Button> buttons)
{
if (btnCountPerRow < 1)
btnCountPerRow = 1;
kb.Content ??= new KeyboardContent
{
Rows = []
};
List<Row> rows = kb.Content.Rows;
// 找到当前可用的最后一个 Row或新建一个
Row? currentRow = rows.Count > 0 ? rows[^1] : null;
foreach (Button button in buttons)
{
if (currentRow is null || currentRow.Buttons.Count >= btnCountPerRow)
{
currentRow = new Row { Buttons = [] };
rows.Add(currentRow);
}
currentRow.Buttons.Add(button);
}
return kb;
}
/// <summary>
/// 新增一行,然后在该行增加键盘按钮
/// </summary>
/// <param name="kb">键盘消息</param>
/// <param name="btnCountPerRow">每行按钮数量,自动检查如果超过则新建行</param>
/// <param name="buttons">按钮</param>
/// <returns></returns>
public static KeyboardMessage AppendButtonsWithNewRow(this KeyboardMessage kb, int btnCountPerRow, params IEnumerable<Button> buttons)
{
if (btnCountPerRow < 1)
btnCountPerRow = 1;
kb.Content ??= new KeyboardContent
{
Rows = []
};
List<Row> rows = kb.Content.Rows;
Row? currentRow = null;
foreach (Button button in buttons)
{
if (currentRow is null || currentRow.Buttons.Count >= btnCountPerRow)
{
currentRow = new Row { Buttons = [] };
rows.Add(currentRow);
}
currentRow.Buttons.Add(button);
}
return kb;
}
/// <summary>
/// 添加通用分类键盘组件
/// </summary>
/// <param name="kb"></param>
/// <param name="command"></param>
/// <param name="currentPage"></param>
/// <param name="totalPages"></param>
/// <returns></returns>
public static KeyboardMessage AddPaginationRow(this KeyboardMessage kb, string command, int currentPage, int totalPages)
{
List<Button> buttons = [];
// 首页和上一页
if (currentPage > 1)
{
buttons.Add(Button.CreateCmdButton("<<", $"{command}1", enter: true, style: 1));
buttons.Add(Button.CreateCmdButton("<", $"{command}{currentPage - 1}", enter: true, style: 1));
}
// 页码指示和跳转
buttons.Add(Button.CreateCmdButton($"{currentPage} / {totalPages}", $"{command} ", enter: false, style: 1));
// 下一页和末页
if (currentPage < totalPages)
{
buttons.Add(Button.CreateCmdButton(">", $"{command}{currentPage + 1}", enter: true, style: 1));
buttons.Add(Button.CreateCmdButton(">>", $"{command}{totalPages}", enter: true, style: 1));
}
return kb.AppendButtonsWithNewRow(5, buttons);
}
/// <summary>
/// 创建一个 qqbot-cmd-input 标签字符串。点击后 text 会填充到输入框show 为展示文本。
/// </summary>
/// <param name="show">按钮或链接展示的文本</param>
/// <param name="text">填充到输入框的指令文本</param>
/// <param name="thisIsText">交换两个参数(指示 this 为 text</param>
/// <returns>形如 &lt;qqbot-cmd-input text="..." show="..."/&gt; 的字符串</returns>
public static string CreateCmdInput(this string show, string text, bool thisIsText = false)
{
// 转义双引号(避免属性值被截断)
string escapedText = text.Replace("\"", "&quot;");
string escapedShow = show.Replace("\"", "&quot;");
if (thisIsText)
{
return $"<qqbot-cmd-input text=\"{escapedShow}\" show=\"{escapedText}\"/>";
}
return $"<qqbot-cmd-input text=\"{escapedText}\" show=\"{escapedShow}\"/>";
}
/// <summary>
/// 创建展示文本与填充内容相同的 qqbot-cmd-input 标签。
/// </summary>
public static string CreateCmdInput(this string text) => CreateCmdInput(text, text);
}
public class ThirdPartyMessage : IBotMessage
{
[JsonPropertyName("id")]
@ -255,6 +398,7 @@ namespace Oshima.FunGame.WebAPI.Models
{
public string RequestUrl { get; set; } = "";
}
public class MarkdownMessage
{
/// <summary>
@ -327,6 +471,70 @@ namespace Oshima.FunGame.WebAPI.Models
[JsonPropertyName("action")]
public Action Action { get; set; } = new();
/// <summary>
/// 创建一个指令按钮Type = 2点击后发送指定指令文本。
/// </summary>
/// <param name="label">按钮默认显示文本</param>
/// <param name="data">指令文本(填充或发送的内容)</param>
/// <param name="enter">true = 点击直接发送消息false = 仅填充到输入框</param>
/// <param name="reply">是否引用当前消息(仅在 Type = 2 且 enter = true 时有效)</param>
/// <param name="visitedLabel">点击后显示的文本,为 null 则与 label 相同</param>
/// <param name="style">按钮样式0 = 灰色1 = 蓝色</param>
/// <param name="permissionType">权限类型0 = 指定用户1 = 管理者2 = 所有人</param>
/// <returns></returns>
public static Button CreateCmdButton(string label, string data, bool enter = true, bool reply = false, string? visitedLabel = null, int style = 1, int permissionType = 2)
{
return new Button
{
Id = Guid.NewGuid().ToString(),
RenderData = new RenderData
{
Label = label,
VisitedLabel = visitedLabel ?? label,
Style = style
},
Action = new Action
{
Type = 2,
Data = data,
Enter = enter,
Reply = reply,
Permission = new Permission { Type = permissionType }
}
};
}
/// <summary>
/// 创建一个指令按钮Type = 1点击后向服务器发送 INTERACTION_CREATE 事件。
/// </summary>
/// <param name="label">按钮默认显示文本</param>
/// <param name="data">指令文本(填充或发送的内容)</param>
/// <param name="enter">true = 点击直接发送消息false = 仅填充到输入框</param>
/// <param name="reply">是否引用当前消息(仅在 Type = 2 且 enter = true 时有效)</param>
/// <param name="visitedLabel">点击后显示的文本,为 null 则与 label 相同</param>
/// <param name="style">按钮样式0 = 灰色1 = 蓝色</param>
/// <param name="permissionType">权限类型0 = 指定用户1 = 管理者2 = 所有人</param>
/// <returns></returns>
public static Button CreateInteractionButton(string label, string data, string? visitedLabel = null, int style = 1, int permissionType = 2)
{
return new Button
{
Id = Guid.NewGuid().ToString(),
RenderData = new RenderData
{
Label = label,
VisitedLabel = visitedLabel ?? label,
Style = style
},
Action = new Action
{
Type = 1,
Data = data,
Permission = new Permission { Type = permissionType }
}
};
}
}
public class RenderData
@ -362,7 +570,7 @@ namespace Oshima.FunGame.WebAPI.Models
public string Data { get; set; } = "";
/// <summary>
/// 回调数据,机器人后台会收到 INTERACTION_CREATE 事件data 会回传
/// 当 Type = 2 时true = 直接发送消息false = 填充输入框
/// </summary>
[JsonPropertyName("enter")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@ -388,4 +596,76 @@ namespace Oshima.FunGame.WebAPI.Models
[JsonPropertyName("type")]
public int Type { get; set; }
}
public class InteractionEvent
{
[JsonPropertyName("id")]
public string Id { get; set; } = "";
[JsonPropertyName("type")]
public int Type { get; set; }
[JsonPropertyName("chat_type")]
public int ChatType { get; set; }
[JsonPropertyName("timestamp")]
public string Timestamp { get; set; } = "";
[JsonPropertyName("guild_id")]
public string GuildId { get; set; } = "";
[JsonPropertyName("channel_id")]
public string ChannelId { get; set; } = "";
[JsonPropertyName("group_openid")]
public string GroupOpenId { get; set; } = "";
[JsonPropertyName("user_openid")]
public string UserOpenId { get; set; } = "";
[JsonPropertyName("version")]
public int Version { get; set; }
[JsonPropertyName("application_id")]
public string ApplicationId { get; set; } = "";
[JsonPropertyName("data")]
public InteractionData Data { get; set; } = new();
}
public class InteractionData
{
[JsonPropertyName("type")]
public int Type { get; set; }
[JsonPropertyName("resolved")]
public InteractionResolved? Resolved { get; set; }
[JsonPropertyName("feature")]
public InteractionFeature? Feature { get; set; }
}
public class InteractionResolved
{
[JsonPropertyName("button_id")]
public string ButtonId { get; set; } = "";
[JsonPropertyName("button_data")]
public string ButtonData { get; set; } = "";
[JsonPropertyName("message_id")]
public string MessageId { get; set; } = "";
[JsonPropertyName("user_id")]
public string UserId { get; set; } = "";
}
public class InteractionFeature
{
[JsonPropertyName("type")]
public int Type { get; set; }
[JsonPropertyName("data")]
public string Data { get; set; } = "";
}
}

View File

@ -3,6 +3,7 @@ using System.Text;
using Milimoe.FunGame.Core.Api.Transmittal;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Oshima.Core.Constant;
using Oshima.FunGame.OshimaModules.Characters;
@ -13,6 +14,7 @@ using Oshima.FunGame.OshimaModules.Regions;
using Oshima.FunGame.OshimaModules.Skills;
using Oshima.FunGame.OshimaModules.Units;
using Oshima.FunGame.OshimaServers.Model;
using Oshima.FunGame.OshimaServers.Models;
using ProjectRedbud.FunGame.SQLQueryExtension;
namespace Oshima.FunGame.OshimaServers.Service
@ -2709,7 +2711,7 @@ namespace Oshima.FunGame.OshimaServers.Service
Dictionary<Character, int> characters = inventory
.Select((character, index) => new { character, index })
.ToDictionary(x => x.character, x => x.index + 1);
return $"{(squad.Length > 0 ? string.Join(separator, squad.Select(c => $"#{characters[c]}. {c.ToStringWithLevelWithOutUser()}")) : "")}";
return $"{(squad.Length > 0 ? string.Join(separator, squad.Select(c => $"#{characters[c]}. {c.ToStringWithLevelWithOutUser()}".CreateCmdInput($"{characters[c]}"))) : "")}";
}
public static string GetCharacterGroupInfoByInventorySequence(IEnumerable<Character> inventory, IEnumerable<long> characterIds, string separator = "\r\n")
@ -2919,7 +2921,7 @@ namespace Oshima.FunGame.OshimaServers.Service
count += Math.Max(1, Random.Shared.Next(1, 4) * diff / 2);
}
model.Awards[item.Name] = count;
award = $" {count} 个{item.Name}";
award = $" {count} 个{item.Name.CreateCmdInput($"{item.Name}")}";
break;
default:
break;
@ -2938,7 +2940,7 @@ namespace Oshima.FunGame.OshimaServers.Service
if (squad.All(c => c.HP <= 0))
{
model.Result = ExploreResult.Nothing;
exploreString = $"探索小队遭遇强大的敌人{enemy.Name}偷袭,狼狈而逃!(什么也没有获得,请检查角色的状态";
exploreString = $"探索小队遭遇强大的敌人{enemy.Name}偷袭,狼狈而逃!(什么也没有获得,请检查角色的状态;或" + "生命之泉".CreateCmdInput() + "";
}
else
{
@ -3005,7 +3007,7 @@ namespace Oshima.FunGame.OshimaServers.Service
}
model.Awards[item.Name] = count;
award = $"{credits} {General.GameplayEquilibriumConstant.InGameCurrency}(包含战斗中击杀奖励)," + $"{exp} 点经验值(探索队员们平分)," +
$"{materials} {General.GameplayEquilibriumConstant.InGameMaterial}" + $"以及 {count} 个{item.Name}";
$"{materials} {General.GameplayEquilibriumConstant.InGameMaterial}" + $"以及 {count} 个{item.Name.CreateCmdInput($"{item.Name}")}";
if (Random.Shared.NextDouble() > 0.6)
{
QualityType qualityType = QualityType.Blue;
@ -3025,7 +3027,7 @@ namespace Oshima.FunGame.OshimaServers.Service
string itemquality = ItemSet.GetQualityTypeName(itemDrop.QualityType);
string itemtype = ItemSet.GetItemTypeName(itemDrop.ItemType) + (itemDrop.ItemType == ItemType.Weapon && itemDrop.WeaponType != WeaponType.None ? "-" + ItemSet.GetWeaponTypeName(itemDrop.WeaponType) : "");
if (itemtype != "") itemtype = $"|{itemtype}";
award += $"!额外获得了:[{itemquality + itemtype}]{itemDrop.Name}";
award += $"!额外获得了:[{itemquality + itemtype}]{itemDrop.Name.CreateCmdInput($"{itemDrop.Name}")}";
}
}
exploreString = $"{exploreString}\r\n{string.Join("\r\n", msgs)}\r\n探索小队战胜了{enemy.Name}!获得了:{award}";
@ -3042,7 +3044,7 @@ namespace Oshima.FunGame.OshimaServers.Service
{
Item item = FunGameConstant.ExploreItems[region][Random.Shared.Next(FunGameConstant.ExploreItems[region].Count)];
model.Awards[item.Name] = deadEnemys.Count();
award = $"{deadEnemys.Count()} 个{item.Name}";
award = $"{deadEnemys.Count()} 个{item.Name.CreateCmdInput($"{item.Name}")}";
exploreString += $"但是获得了补偿:{award}";
}
}
@ -3072,7 +3074,7 @@ namespace Oshima.FunGame.OshimaServers.Service
string itemquality = ItemSet.GetQualityTypeName(itemEarned.QualityType);
string itemtype = ItemSet.GetItemTypeName(itemEarned.ItemType) + (itemEarned.ItemType == ItemType.Weapon && itemEarned.WeaponType != WeaponType.None ? "-" + ItemSet.GetWeaponTypeName(itemEarned.WeaponType) : "");
if (itemtype != "") itemtype = $"|{itemtype}";
award += $"[{itemquality + itemtype}]{itemEarned.Name}";
award += $"[{itemquality + itemtype}]{itemEarned.Name.CreateCmdInput($"{itemEarned.Name}")}";
}
break;
case ExploreResult.Event:
@ -3995,7 +3997,7 @@ namespace Oshima.FunGame.OshimaServers.Service
List<string> expBook = [];
if (large > 0)
{
expBook.Add($"{large} 个大经验书");
expBook.Add($"{large} 个" + "大经验书".CreateCmdInput($"我的物品大经验书"));
for (int i = 0; i < large; i++)
{
AddItemToUserInventory(user, new ());
@ -4003,7 +4005,7 @@ namespace Oshima.FunGame.OshimaServers.Service
}
if (medium > 0)
{
expBook.Add($"{medium} 个中经验书");
expBook.Add($"{medium} 个" + "中经验书".CreateCmdInput($"我的物品中经验书"));
for (int i = 0; i < medium; i++)
{
AddItemToUserInventory(user, new ());
@ -4011,7 +4013,7 @@ namespace Oshima.FunGame.OshimaServers.Service
}
if (small > 0)
{
expBook.Add($"{small} 个小经验书");
expBook.Add($"{small} 个" + "小经验书".CreateCmdInput($"我的物品小经验书"));
for (int i = 0; i < small; i++)
{
AddItemToUserInventory(user, new ());
@ -4041,7 +4043,7 @@ namespace Oshima.FunGame.OshimaServers.Service
region ??= FunGameConstant.Regions[Random.Shared.Next(FunGameConstant.Regions.Count)];
item ??= region.Crops.ToList()[Random.Shared.Next(region.Crops.Count)];
award = difficulty + Random.Shared.Next(0, 3);
regionItems.Add($"{award} 个{item.Name}(来自{region.Name}");
regionItems.Add($"{award} 个{item.Name.CreateCmdInput($"{item.Name}")}(来自{region.Name.CreateCmdInput($"{region.Id}")}");
for (int j = 0; j < award; j++)
{
AddItemToUserInventory(user, item, copyLevel: item.ItemType == ItemType.MagicCard);
@ -4068,7 +4070,7 @@ namespace Oshima.FunGame.OshimaServers.Service
}
item ??= FunGameConstant.CharacterLevelBreakItems[Random.Shared.Next(FunGameConstant.CharacterLevelBreakItems.Count)];
award = difficulty + Random.Shared.Next(0, 3);
characterLevelBreakItems.Add($"{award} 个{item.Name}");
characterLevelBreakItems.Add($"{award} 个{item.Name.CreateCmdInput($"{item.Name}")}");
for (int j = 0; j < award; j++)
{
AddItemToUserInventory(user, item, copyLevel: item.ItemType == ItemType.MagicCard);
@ -4095,7 +4097,7 @@ namespace Oshima.FunGame.OshimaServers.Service
}
item ??= FunGameConstant.SkillLevelUpItems[Random.Shared.Next(FunGameConstant.SkillLevelUpItems.Count)];
award = difficulty + Random.Shared.Next(0, 3);
skillLevelUpItems.Add($"{award} 个{item.Name}");
skillLevelUpItems.Add($"{award} 个{item.Name.CreateCmdInput($"{item.Name}")}");
for (int j = 0; j < award; j++)
{
AddItemToUserInventory(user, item, copyLevel: item.ItemType == ItemType.MagicCard);
@ -4138,7 +4140,7 @@ namespace Oshima.FunGame.OshimaServers.Service
magicCards[ItemSet.GetQualityTypeName(item.QualityType)] = 1;
}
}
builder.AppendLine($"{string.Join("", magicCards.Select(kv => $"{kv.Value} {kv.Key}"))}");
builder.AppendLine($"{string.Join("", magicCards.Select(kv => $"{kv.Value} {kv.Key}"))}" + "查看库存".CreateCmdInput($"我的库存魔法卡"));
break;
default:
break;

View File

@ -15,6 +15,7 @@ using Oshima.FunGame.OshimaModules.Items;
using Oshima.FunGame.OshimaModules.Models;
using Oshima.FunGame.OshimaModules.Regions;
using Oshima.FunGame.OshimaServers.Model;
using Oshima.FunGame.OshimaServers.Models;
using Oshima.FunGame.OshimaServers.Service;
using ProjectRedbud.FunGame.SQLQueryExtension;
@ -4431,8 +4432,17 @@ namespace Oshima.FunGame.WebAPI.Controllers
}
[HttpPost("checkquestlist")]
public string CheckQuestList([FromQuery] long? uid = null)
public BotReply CheckQuestList([FromQuery] long? uid = null)
{
MarkdownMessage md = new()
{
Content = busy
};
BotReply reply = new()
{
Markdown = md
};
long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
PluginConfig pc = FunGameService.GetUserConfig(userid, out _);
@ -4448,12 +4458,14 @@ namespace Oshima.FunGame.WebAPI.Controllers
FunGameService.SetUserConfigAndReleaseSemaphoreSlim(userid, pc, user);
return msg;
md.Content = msg;
return reply;
}
else
{
FunGameService.ReleaseUserSemaphoreSlim(userid);
return noSaved;
md.Content = noSaved;
return reply;
}
}
@ -5830,8 +5842,17 @@ namespace Oshima.FunGame.WebAPI.Controllers
}
[HttpPost("showdailystore")]
public string ShowDailyStore([FromQuery] long? uid = null)
public BotReply ShowDailyStore([FromQuery] long? uid = null)
{
MarkdownMessage md = new()
{
Content = busy
};
BotReply reply = new()
{
Markdown = md
};
long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
PluginConfig pc = FunGameService.GetUserConfig(userid, out _);
@ -5846,12 +5867,14 @@ namespace Oshima.FunGame.WebAPI.Controllers
stores.SaveConfig();
FunGameService.SetUserConfigAndReleaseSemaphoreSlim(userid, pc, user);
return msg;
md.Content = msg;
return reply;
}
else
{
FunGameService.ReleaseUserSemaphoreSlim(userid);
return noSaved;
md.Content = noSaved;
return reply;
}
}
@ -6377,8 +6400,17 @@ namespace Oshima.FunGame.WebAPI.Controllers
}
[HttpPost("exploresettle")]
public string SettleExplore(string exploreId, [FromQuery] long? uid = null)
public BotReply SettleExplore([FromQuery] string exploreId, [FromQuery] long? uid = null, [FromQuery] string command = "")
{
MarkdownMessage md = new()
{
Content = busy
};
BotReply reply = new()
{
Markdown = md
};
long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
PluginConfig pc = FunGameService.GetUserConfig(userid, out _);
@ -6401,12 +6433,18 @@ namespace Oshima.FunGame.WebAPI.Controllers
FunGameService.SetUserConfigAndReleaseSemaphoreSlim(userid, pc, user);
return msg;
md.Content = msg;
if (command != "")
{
reply.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("再探再报", command, permissionType: 0));
}
return reply;
}
else
{
FunGameService.ReleaseUserSemaphoreSlim(userid);
return noSaved;
md.Content = noSaved;
return reply;
}
}
@ -9357,14 +9395,22 @@ namespace Oshima.FunGame.WebAPI.Controllers
}
[HttpPost("getuserdailyitem")]
public string GetUserDailyItem([FromQuery] long uid = -1, [FromQuery] string daily = "")
public BotReply GetUserDailyItem([FromQuery] long uid = -1, [FromQuery] string daily = "")
{
MarkdownMessage md = new()
{
Content = busy
};
BotReply reply = new()
{
Markdown = md
};
try
{
PluginConfig pc = FunGameService.GetUserConfig(uid, out bool isTimeout);
if (isTimeout)
{
return busy;
return reply;
}
string msg = "";
@ -9380,7 +9426,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
string itemName = match.Groups[1].Value;
if (FunGameConstant.UserDailyItems.FirstOrDefault(i => i.Name == itemName) is Item item)
{
msg = $"恭喜你获得了幸运物【{itemName}】,已发放至库存~";
msg = $"恭喜你获得了幸运物【{itemName.CreateCmdInput($"{itemName}")}】,已发放至{"".CreateCmdInput("")}";
FunGameService.AddItemToUserInventory(user, item);
}
}
@ -9395,21 +9441,22 @@ namespace Oshima.FunGame.WebAPI.Controllers
Price = 0
};
user.Inventory.Items.Add(item);
msg += "\r\n圣诞温暖相伴元旦好运相随在节日的钟声里收获惊喜成功参加【双旦活动】你获得了一张【十连奖券】";
msg += $"\r\n圣诞温暖相伴元旦好运相随在节日的钟声里收获惊喜成功参加【{"".CreateCmdInput($"{activity.Id}")}】,你获得了一张【{"".CreateCmdInput("")}】!";
}
FunGameService.SetUserConfigButNotRelease(uid, pc, user);
return msg;
md.Content = msg;
}
else
{
return $"温馨提醒:【创建存档】后获取运势可领取同款幸运物的收藏品,全部收集可兑换强大装备哦~";
md.Content = $"温馨提醒:【{"".CreateCmdInput()}】后获取运势可领取同款幸运物的收藏品,全部收集可兑换强大装备哦~";
}
return reply;
}
catch (Exception e)
{
if (Logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error)) Logger.LogError(e, "Error: {e}", e);
return busy;
return reply;
}
finally
{
@ -9452,6 +9499,50 @@ namespace Oshima.FunGame.WebAPI.Controllers
}
}
[HttpPost("template2")]
public BotReply Template2([FromQuery] long uid = -1)
{
MarkdownMessage md = new()
{
Content = busy
};
BotReply reply = new()
{
Markdown = md
};
try
{
PluginConfig pc = FunGameService.GetUserConfig(uid, out bool isTimeout);
if (isTimeout)
{
return reply;
}
string msg = "";
if (pc.Count > 0)
{
User user = FunGameService.GetUser(pc);
FunGameService.SetUserConfigButNotRelease(uid, pc, user);
return msg;
}
else
{
md.Content = noSaved;
return reply;
}
}
catch (Exception e)
{
if (Logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error)) Logger.LogError(e, "Error: {e}", e);
return reply;
}
finally
{
FunGameService.ReleaseUserSemaphoreSlim(uid);
}
}
[HttpGet("reload")]
public string Relaod([FromQuery] long? master = null)
{

View File

@ -5,8 +5,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Milimoe.FunGame.Core.Api.Utility;
using Oshima.FunGame.WebAPI.Models;
using Oshima.FunGame.OshimaServers.Models;
using Oshima.FunGame.WebAPI.Services;
using Rebex.Security.Cryptography;
@ -22,7 +21,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
private RainBOTService FungameService { get; set; } = fungameService;
[HttpPost]
public async Task<IActionResult> Post([FromBody] Payload? payload)
public IActionResult Post([FromBody] Payload? payload)
{
if (payload is null)
{
@ -40,13 +39,13 @@ namespace Oshima.FunGame.WebAPI.Controllers
else if (payload.Op == 0)
{
// 处理其他事件
return await HandleEventAsync(payload);
return HandleEventAsync(payload);
}
else
{
if (Logger.IsEnabled(LogLevel.Warning)) Logger.LogWarning("未处理操作码:{payload.Op}", payload.Op);
return Ok();
}
return Ok();
}
catch (Exception e)
{
@ -84,7 +83,6 @@ namespace Oshima.FunGame.WebAPI.Controllers
string signature = Convert.ToHexString(result).ToLower(CultureInfo.InvariantCulture);
ValidationResponse response = new()
{
PlainToken = validationPayload.PlainToken,
@ -95,7 +93,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
return Ok(response);
}
private async Task<IActionResult> HandleEventAsync(Payload payload)
private IActionResult HandleEventAsync(Payload payload)
{
if (Logger.IsEnabled(LogLevel.Debug)) Logger.LogDebug("处理事件:{EventType}, 数据:{Data}", payload.EventType, payload.Data);
@ -120,7 +118,7 @@ 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";
//string url = $"{RequestUrl}/images/zi/dj1.png";
//UploadMediaResult uploadMediaResult = await Service.UploadC2CMediaAsync(c2cMessage.Author.UserOpenId, 1, url);
//if (Logger.IsEnabled(LogLevel.Debug)) Logger.LogDebug("发送的图片地址:{url}", url);
//if (string.IsNullOrEmpty(uploadMediaResult.Error))
@ -168,7 +166,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
// }
//};
//await Service.SendC2CMarkdownAsync(c2cMessage.AuthorOpenId, mdMsg, kbMsg, c2cMessage.Id);
TaskUtility.NewTask(async () => await FungameService.Handler(c2cMessage, data));
Task.Run(async () => await FungameService.Handler(c2cMessage, data));
}
else
{
@ -189,7 +187,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("收到来自群组 {groupAtMessage.GroupOpenId} 的消息:{groupAtMessage.Content}", groupAtMessage.GroupOpenId, groupAtMessage.Content);
// 回复消息
//await _service.SendGroupMessageAsync(groupAtMessage.GroupOpenId, $"你发送的消息是:{groupAtMessage.Content}", msgId: groupAtMessage.Id);
TaskUtility.NewTask(async () => await FungameService.Handler(groupAtMessage, data));
Task.Run(async () => await FungameService.Handler(groupAtMessage, data));
}
else
{
@ -197,6 +195,30 @@ namespace Oshima.FunGame.WebAPI.Controllers
return BadRequest("无效的群聊消息数据格式");
}
break;
case "INTERACTION_CREATE":
InteractionEvent? interaction = JsonSerializer.Deserialize<InteractionEvent>(payload.Data.ToString() ?? "");
if (interaction != null)
{
// 提取按钮ID和数据
string buttonId = interaction.Data?.Resolved?.ButtonId ?? "";
string buttonData = interaction.Data?.Resolved?.ButtonData ?? "";
if (Logger.IsEnabled(LogLevel.Information))
{
Logger.LogInformation("收到按钮点击ButtonId={buttonId}, Data={buttonData}, User={user}", buttonId, buttonData, interaction.UserOpenId);
}
// TODO
//if (interaction.ChatType == 1)
//{
// Task.Run(async () => await Service.SendGroupMessageAsync(interaction.GroupOpenId, $"你点击了按钮:{buttonData}"));
//}
//else if (interaction.ChatType == 2)
//{
// Task.Run(async () => await Service.SendC2CMessageAsync(interaction.UserOpenId, $"你点击了按钮:{buttonData}"));
//}
}
break;
default:
if (Logger.IsEnabled(LogLevel.Warning)) Logger.LogWarning("未定义事件:{EventType}", payload.EventType);
break;
@ -206,7 +228,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
catch (JsonException e)
{
if (Logger.IsEnabled(LogLevel.Error)) Logger.LogError("反序列化过程遇到错误:{e}", e);
return BadRequest("Invalid JSON format");
return BadRequest("无效的 JSON 格式");
}
catch (Exception e)
{

View File

@ -13,10 +13,10 @@ using Oshima.Core.Constant;
using Oshima.FunGame.OshimaModules.Characters;
using Oshima.FunGame.OshimaModules.Items;
using Oshima.FunGame.OshimaModules.Models;
using Oshima.FunGame.OshimaServers.Models;
using Oshima.FunGame.OshimaServers.Service;
using Oshima.FunGame.WebAPI.Constant;
using Oshima.FunGame.WebAPI.Controllers;
using Oshima.FunGame.WebAPI.Models;
using Oshima.FunGame.WebAPI.Services;
using ProjectRedbud.FunGame.SQLQueryExtension;
using TaskScheduler = Milimoe.FunGame.Core.Api.Utility.TaskScheduler;

View File

@ -4,7 +4,7 @@ using System.Text.Json;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Oshima.FunGame.WebAPI.Models;
using Oshima.FunGame.OshimaServers.Models;
namespace Oshima.FunGame.WebAPI.Services
{

View File

@ -9,6 +9,7 @@ using Milimoe.FunGame.Core.Library.Constant;
using Oshima.Core.Configs;
using Oshima.Core.Constant;
using Oshima.FunGame.OshimaModules.Models;
using Oshima.FunGame.OshimaServers.Models;
using Oshima.FunGame.OshimaServers.Service;
using Oshima.FunGame.WebAPI.Constant;
using Oshima.FunGame.WebAPI.Controllers;
@ -27,7 +28,29 @@ namespace Oshima.FunGame.WebAPI.Services
private IMemoryCache MemoryCache { get; set; } = memoryCache;
private TestController TestController { get; set; } = testController;
private async Task SendAsync(IBotMessage msg, string title, string content, int msgType = 0, object? media = null, int? msgSeq = null)
private async Task SendAsync(IBotMessage msg, string title, BotReply reply, int? msgSeq = null)
{
if (reply.Markdown != null)
{
// 发送 Markdown + 键盘
await SendMarkdownAsync(msg, title, reply.Markdown, reply.Keyboard, msgSeq);
}
else if (reply.Keyboard != null)
{
// 发送 文本 + 键盘
await SendMarkdownAsync(msg, title, new()
{
Content = reply.Text
}, reply.Keyboard, msgSeq);
}
else
{
// 发送纯文本
await SendTextAsync(msg, title, reply.Text ?? string.Empty, msgSeq: msgSeq);
}
}
private async Task SendTextAsync(IBotMessage msg, string title, string content, int msgType = 0, object? media = null, int? msgSeq = null)
{
Statics.RunningPlugin?.Controller.WriteLine(title, Milimoe.FunGame.Core.Library.Constant.LogLevel.Debug);
if (msg is ThirdPartyMessage third)
@ -72,31 +95,36 @@ namespace Oshima.FunGame.WebAPI.Services
if (msg.UseNotice && msg.FunGameUID > 0 && FunGameService.UserNotice.TryGetValue(msg.FunGameUID, out HashSet<string>? msgs) && msgs != null)
{
FunGameService.UserNotice.Remove(msg.FunGameUID, out _);
await SendAsync(msg, "离线未读信箱", $"☆--- 离线未读信箱 ---☆\r\n{string.Join("\r\n", msgs)}", 0, null, 5);
await SendTextAsync(msg, "离线未读信箱", $"☆--- 离线未读信箱 ---☆\r\n{string.Join("\r\n", msgs)}", 0, null, 5);
}
}
private async Task SendHelp(IBotMessage e, Dictionary<string, string> helpDict, string helpName, int currentPage)
{
e.UseNotice = false;
if (currentPage <= 0) currentPage = 1;
int pageSize = 15;
int totalPages = (helpDict.Count + pageSize - 1) / pageSize;
int totalPages = helpDict.MaxPage(pageSize);
StringBuilder result = new($"《筽祀牻》{helpName}指令(第 {currentPage}/{totalPages} 页)\n");
int index = (currentPage - 1) * pageSize + 1;
foreach ((string cmd, string desc) in FunGameOrderList.GetPage(helpDict, currentPage, pageSize))
foreach ((string cmd, string desc) in helpDict.GetPage(currentPage, pageSize))
{
result.AppendLine($"{index}. {cmd}{(desc != "" ? "" + desc : "")}");
index++;
}
if (currentPage < totalPages)
{
result.AppendLine($"发送【{helpName}{currentPage + 1}】查看下一页");
}
KeyboardMessage kb = new KeyboardMessage().AddPaginationRow(helpName, currentPage, totalPages);
await SendAsync(e, "筽祀牻", result.ToString());
await SendAsync(e, "筽祀牻", new BotReply()
{
Markdown = new()
{
Content = result.ToString()
},
Keyboard = kb
});
}
public async Task<bool> Handler(IBotMessage e, OtherData data)
@ -206,32 +234,40 @@ namespace Oshima.FunGame.WebAPI.Services
_ => ""
};
string? fi = "";
string? err = "";
try
// 传统派已离场
//string? fi = "";
//string? err = "";
//try
//{
// UploadMediaResult uploadMediaResult = e.IsGroup ? await Service.UploadGroupMediaAsync(e.OpenId, 1, img) : await Service.UploadC2CMediaAsync(e.OpenId, 1, img);
// fi = uploadMediaResult.FileInfo;
// err = uploadMediaResult.Error;
//}
//catch (Exception ex)
//{
// err = ex.ToString();
//}
//if (string.IsNullOrEmpty(err))
//{
// await SendTextAsync(e, "每日运势", daily.daily, 7, new { file_info = fi });
//}
//else
//{
// if (Logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error)) Logger.LogError("上传图片失败:{error}", err);
// await SendAsync(e, "每日运势", daily.daily);
//}
// 使用md
await SendAsync(e, "每日运势", new BotReply()
{
UploadMediaResult uploadMediaResult = e.IsGroup ? await Service.UploadGroupMediaAsync(e.OpenId, 1, img) : await Service.UploadC2CMediaAsync(e.OpenId, 1, img);
fi = uploadMediaResult.FileInfo;
err = uploadMediaResult.Error;
}
catch (Exception ex)
{
err = ex.ToString();
}
if (string.IsNullOrEmpty(err))
{
await SendAsync(e, "每日运势", daily.daily, 7, new { file_info = fi });
}
else
{
if (Logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error)) Logger.LogError("上传图片失败:{error}", err);
await SendAsync(e, "每日运势", daily.daily);
}
string msg = Controller.GetUserDailyItem(uid, daily.daily);
if (msg != "")
{
await SendAsync(e, "运势幸运物发放", msg, msgSeq: 3);
}
Markdown = new()
{
Content = $"{daily.daily}\r\n![text #256px #256px]({img})"
}
});
BotReply rpy = Controller.GetUserDailyItem(uid, daily.daily);
await SendAsync(e, "运势幸运物发放", rpy, msgSeq: 3);
}
else
{
@ -243,18 +279,24 @@ namespace Oshima.FunGame.WebAPI.Services
{
e.UseNotice = false;
FunGameService.RefreshNotice();
if (FunGameService.Notices.Count > 0)
List<string> msgs = [];
DateTime now = DateTime.Now;
foreach (NoticeModel notice in FunGameService.Notices.Values)
{
List<string> msgs = [];
DateTime now = DateTime.Now;
foreach (NoticeModel notice in FunGameService.Notices.Values)
if (now >= notice.StartTime && now <= notice.EndTime)
{
if (now >= notice.StartTime && now <= notice.EndTime)
{
msgs.Add(notice.ToString());
}
msgs.Add(notice.ToString());
}
await SendAsync(e, "公告", string.Join("\r\n", msgs));
}
if (msgs.Count > 0)
{
await SendAsync(e, "公告", new BotReply()
{
Markdown = new()
{
Content = $"系统公告列表:\r\n```\r\n{string.Join("\r\n", msgs)}\r\n```"
}
});
}
else
{
@ -341,20 +383,26 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail == "帮助")
{
e.UseNotice = false;
await SendAsync(e, "筽祀牻", @$"欢迎使用《筽祀牻》游戏指令帮助系统!
await SendAsync(e, "筽祀牻", new BotReply()
{
Markdown = new()
{
Content = @$"欢迎使用《筽祀牻》游戏指令帮助系统!
{FunGameInfo.FunGame_Version}
1
2
3
4
5
6
7
8
");
1<qqbot-cmd-input text="" "" show=""""/>
2<qqbot-cmd-input text="" "" show=""""/>
3<qqbot-cmd-input text="" "" show=""""/>
4<qqbot-cmd-input text="" "" show=""""/>
5<qqbot-cmd-input text="" "" show=""""/>
6<qqbot-cmd-input text="" "" show=""""/>
7<qqbot-cmd-input text="" "" show=""""/>
8<qqbot-cmd-input text="" "" show=""""/>
"
}
});
}
if (e.Detail.StartsWith("存档帮助"))
@ -405,13 +453,9 @@ namespace Oshima.FunGame.WebAPI.Services
{
FunGameSimulation = true;
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: 0);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(5500);
}
BotReply rpy = MergeToMarkdown("模拟结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("FunGame模拟", $"FunGame模拟"));
await SendAsync(e, "筽祀牻", rpy, msgSeq: 1);
FunGameSimulation = false;
}
else
@ -428,13 +472,9 @@ namespace Oshima.FunGame.WebAPI.Services
{
FunGameSimulation = true;
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: 0, hasMap: true);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(5500);
}
BotReply rpy = MergeToMarkdown("模拟结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("个人地图模拟", $"个人地图模拟"));
await SendAsync(e, "筽祀牻", rpy, msgSeq: 1);
FunGameSimulation = false;
}
else
@ -457,13 +497,9 @@ namespace Oshima.FunGame.WebAPI.Services
{
FunGameSimulation = true;
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: maxRespawnTimesMix);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(5500);
}
BotReply rpy = MergeToMarkdown("模拟结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("混战模拟", $"混战模拟"));
await SendAsync(e, "筽祀牻", rpy, msgSeq: 1);
FunGameSimulation = false;
}
else
@ -487,13 +523,9 @@ namespace Oshima.FunGame.WebAPI.Services
{
FunGameSimulation = true;
List<string> msgs = await Controller.GetTest(false, true);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(5500);
}
BotReply rpy = MergeToMarkdown("模拟结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("FunGame团队模拟", $"FunGame团队模拟"));
await SendAsync(e, "筽祀牻", rpy, msgSeq: 1);
FunGameSimulation = false;
}
else
@ -510,13 +542,9 @@ namespace Oshima.FunGame.WebAPI.Services
{
FunGameSimulation = true;
List<string> msgs = await Controller.GetTest(false, true, hasMap: true);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(5500);
}
BotReply rpy = MergeToMarkdown("模拟结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("团队地图模拟", $"团队地图模拟"));
await SendAsync(e, "筽祀牻", rpy, msgSeq: 1);
FunGameSimulation = false;
}
else
@ -533,13 +561,9 @@ namespace Oshima.FunGame.WebAPI.Services
{
FunGameSimulation = true;
List<string> msgs = await Controller.GetTestDebug(false, true, hasMap: true);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(5500);
}
BotReply rpy = MergeToMarkdown("模拟结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("团队调试模拟", $"团队调试模拟"));
await SendAsync(e, "筽祀牻", rpy, msgSeq: 1);
FunGameSimulation = false;
}
else
@ -789,11 +813,16 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail == "我的存档")
{
string msg = Controller.ShowSaved(uid);
if (msg != "")
{
await SendAsync(e, "我的存档", "\r\n" + msg);
}
BotReply rpy = Controller.ShowSaved(uid);
rpy.Keyboard = new KeyboardMessage().AppendButtons(3, [
Button.CreateCmdButton("签到", "签到"),
Button.CreateCmdButton("帮助", "帮助"),
Button.CreateCmdButton("运势", "我的运势"),
Button.CreateCmdButton("库存", "我的库存"),
Button.CreateCmdButton("任务", "任务列表"),
Button.CreateCmdButton("商店", "每日商店")
]);
await SendAsync(e, "我的存档", rpy);
return result;
}
@ -881,17 +910,17 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail == "角色改名")
{
e.UseNotice = false;
await SendAsync(e, "改名", "\r\n为防止玩家手误更改自己的昵称请在该指令前添加【确认】二字即使用【确认角色改名】指令。");
BotReply rpy = "为防止玩家手误更改自己的昵称,请在该指令前添加【确认】二字,即使用【确认角色改名】指令。";
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("确认", "确认角色改名", false));
await SendAsync(e, "改名", rpy);
return result;
}
if (e.Detail == "确认角色改名")
{
string msg = Controller.ReName(uid);
if (msg != "")
{
await SendAsync(e, "改名", "\r\n" + msg);
}
BotReply rpy = Controller.ReName(uid);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("查询改名", "查询改名"));
await SendAsync(e, "改名", rpy);
return result;
}
@ -1005,8 +1034,10 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail.StartsWith("自定义改名"))
{
e.UseNotice = false;
await SendAsync(e, "改名", "\r\n自定义改名说明自定义改名需要库存中存在至少一张未上锁、且未处于交易、市场出售状态的改名卡提交改名申请后需要等待审核。" +
"在审核期间,改名卡将会被系统锁定,无法取消、重复提交申请,也不能解锁、分解、交易、出售该改名卡。如已知悉请在该指令前添加【确认】二字,即使用【确认自定义改名】指令。");
BotReply rpy = "自定义改名说明:自定义改名需要库存中存在至少一张未上锁、且未处于交易、市场出售状态的改名卡,提交改名申请后需要等待审核。" +
"在审核期间,改名卡将会被系统锁定,无法取消、重复提交申请,也不能解锁、分解、交易、出售该改名卡。如已知悉请在该指令前添加【确认】二字,即使用【确认自定义改名】指令。";
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("确认", "确认自定义改名", false));
await SendAsync(e, "改名", rpy);
return result;
}
@ -1024,11 +1055,12 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail == "角色重随")
{
string msg = Controller.RandomCustomCharacter(uid, false);
if (msg != "")
{
await SendAsync(e, "角色重随", "\r\n" + msg);
}
BotReply rpy = Controller.RandomCustomCharacter(uid, false);
rpy.Keyboard = new KeyboardMessage().AppendButtons(2, [
Button.CreateCmdButton("取消角色重随", "取消角色重随", false, style: 0),
Button.CreateCmdButton("确认角色重随", "确认角色重随", false),
]);
await SendAsync(e, "角色重随", rpy);
return result;
}
@ -1044,11 +1076,9 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail == "取消角色重随")
{
string msg = Controller.CancelRandomCustomCharacter(uid);
if (msg != "")
{
await SendAsync(e, "角色重随", "\r\n" + msg);
}
BotReply rpy = Controller.CancelRandomCustomCharacter(uid);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("角色重随", "角色重随", false));
await SendAsync(e, "角色重随", rpy);
return result;
}
@ -1057,7 +1087,15 @@ namespace Oshima.FunGame.WebAPI.Services
List<string> msgs = Controller.DrawCard(uid);
if (msgs.Count > 0)
{
await SendAsync(e, "抽卡", "\r\n" + string.Join("\r\n", msgs));
BotReply rpy = MergeToMarkdown("抽卡结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(2, [
Button.CreateCmdButton("抽卡", "抽卡"),
Button.CreateCmdButton("十连抽卡", "十连抽卡"),
]).AppendButtonsWithNewRow(2, [
Button.CreateCmdButton("钻石抽卡", "钻石抽卡"),
Button.CreateCmdButton("钻石十连抽卡", "钻石十连抽卡"),
]);
await SendAsync(e, "抽卡", rpy);
}
return result;
}
@ -1067,7 +1105,15 @@ namespace Oshima.FunGame.WebAPI.Services
List<string> msgs = Controller.DrawCards(uid);
if (msgs.Count > 0)
{
await SendAsync(e, "十连抽卡", "\r\n" + string.Join("\r\n", msgs));
BotReply rpy = MergeToMarkdown("抽卡结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(2, [
Button.CreateCmdButton("抽卡", "抽卡"),
Button.CreateCmdButton("十连抽卡", "十连抽卡"),
]).AppendButtonsWithNewRow(2, [
Button.CreateCmdButton("钻石抽卡", "钻石抽卡"),
Button.CreateCmdButton("钻石十连抽卡", "钻石十连抽卡"),
]);
await SendAsync(e, "十连抽卡", rpy);
}
return result;
}
@ -1077,7 +1123,15 @@ namespace Oshima.FunGame.WebAPI.Services
List<string> msgs = Controller.DrawCard_Material(uid);
if (msgs.Count > 0)
{
await SendAsync(e, "钻石抽卡", "\r\n" + string.Join("\r\n", msgs));
BotReply rpy = MergeToMarkdown("抽卡结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(2, [
Button.CreateCmdButton("抽卡", "抽卡"),
Button.CreateCmdButton("十连抽卡", "十连抽卡"),
]).AppendButtonsWithNewRow(2, [
Button.CreateCmdButton("钻石抽卡", "钻石抽卡"),
Button.CreateCmdButton("钻石十连抽卡", "钻石十连抽卡"),
]);
await SendAsync(e, "钻石抽卡", rpy);
}
return result;
}
@ -1087,7 +1141,15 @@ namespace Oshima.FunGame.WebAPI.Services
List<string> msgs = Controller.DrawCards_Material(uid);
if (msgs.Count > 0)
{
await SendAsync(e, "钻石十连抽卡", "\r\n" + string.Join("\r\n", msgs));
BotReply rpy = MergeToMarkdown("抽卡结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(2, [
Button.CreateCmdButton("抽卡", "抽卡"),
Button.CreateCmdButton("十连抽卡", "十连抽卡"),
]).AppendButtonsWithNewRow(2, [
Button.CreateCmdButton("钻石抽卡", "钻石抽卡"),
Button.CreateCmdButton("钻石十连抽卡", "钻石十连抽卡"),
]);
await SendAsync(e, "钻石十连抽卡", rpy);
}
return result;
}
@ -1358,11 +1420,9 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail == "任务列表")
{
string msg = Controller.CheckQuestList(uid);
if (msg != "")
{
await SendAsync(e, "任务列表", "\r\n" + msg);
}
BotReply rpy = Controller.CheckQuestList(uid);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("做任务", "做任务", false));
await SendAsync(e, "任务列表", rpy);
return result;
}
@ -1845,13 +1905,9 @@ namespace Oshima.FunGame.WebAPI.Services
{
msgs = await Controller.FightCustom2(uid, detail.Trim(), true);
}
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "完整决斗", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(1500);
}
BotReply rpy = MergeToMarkdown("战斗结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("再次决斗", $"完整决斗{eqq}"));
await SendAsync(e, "完整决斗", rpy, msgSeq: 1);
return result;
}
@ -1867,13 +1923,9 @@ namespace Oshima.FunGame.WebAPI.Services
{
msgs = await Controller.FightCustom2(uid, detail.Trim(), false);
}
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "决斗", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(1500);
}
BotReply rpy = MergeToMarkdown("战斗结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("再次决斗", $"决斗{eqq}"));
await SendAsync(e, "决斗", rpy, msgSeq: 1);
return result;
}
@ -1889,13 +1941,9 @@ namespace Oshima.FunGame.WebAPI.Services
{
msgs = await Controller.FightCustomTeam2(uid, detail.Trim(), true);
}
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "完整决斗", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(1500);
}
BotReply rpy = MergeToMarkdown("战斗结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("再次决斗", $"小队决斗{eqq}"));
await SendAsync(e, "小队决斗", rpy, msgSeq: 1);
return result;
}
@ -1925,13 +1973,9 @@ namespace Oshima.FunGame.WebAPI.Services
if (int.TryParse(detail.Trim(), out int index))
{
msgs = await Controller.FightBossTeam(uid, index, true);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "BOSS", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(1500);
}
BotReply rpy = MergeToMarkdown("战斗结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("小队讨伐boss", $"小队讨伐boss"));
await SendAsync(e, "BOSS", rpy, msgSeq: 1);
}
else
{
@ -1947,13 +1991,9 @@ namespace Oshima.FunGame.WebAPI.Services
if (int.TryParse(detail.Trim(), out int index))
{
msgs = await Controller.FightBoss(uid, index, true);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "BOSS", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(1500);
}
BotReply rpy = MergeToMarkdown("战斗结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("讨伐boss", $"讨伐boss"));
await SendAsync(e, "BOSS", rpy, msgSeq: 1);
}
else
{
@ -2309,11 +2349,12 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail == "每日商店")
{
string msg = Controller.ShowDailyStore(uid);
if (msg != "")
{
await SendAsync(e, "商店", "\r\n" + msg);
}
BotReply rpy = Controller.ShowDailyStore(uid);
rpy.Keyboard = new KeyboardMessage().AppendButtons(2, [
Button.CreateCmdButton("商店查看", "商店查看", false),
Button.CreateCmdButton("商店购买", "商店购买", false)
]);
await SendAsync(e, "商店", rpy);
return result;
}
@ -2445,6 +2486,7 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail.StartsWith("探索") || e.Detail.StartsWith("前往"))
{
string originalDetail = e.Detail;
string detail = e.Detail.Replace("探索", "").Replace("前往", "").Trim();
string msg = "";
string eid = "";
@ -2467,11 +2509,8 @@ namespace Oshima.FunGame.WebAPI.Services
_ = Task.Run(async () =>
{
await Task.Delay(FunGameConstant.ExploreTime * 60 * 1000);
msg = Controller.SettleExplore(eid, uid);
if (msg.Trim() != "")
{
await SendAsync(e, "探索", msg, msgSeq: 2);
}
BotReply rpy = Controller.SettleExplore(eid, uid, originalDetail);
await SendAsync(e, "探索", rpy, msgSeq: 2);
});
}
else if (cindexs.Count > 5)
@ -2487,6 +2526,7 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail.StartsWith("小队探索"))
{
string originalDetail = e.Detail;
string detail = e.Detail.Replace("小队探索", "").Trim();
string msg = "";
string eid = "";
@ -2509,11 +2549,8 @@ namespace Oshima.FunGame.WebAPI.Services
_ = Task.Run(async () =>
{
await Task.Delay(FunGameConstant.ExploreTime * 60 * 1000);
msg = Controller.SettleExplore(eid, uid);
if (msg.Trim() != "")
{
await SendAsync(e, "探索", msg, msgSeq: 2);
}
BotReply rpy = Controller.SettleExplore(eid, uid, originalDetail);
await SendAsync(e, "探索", rpy, msgSeq: 2);
});
}
else
@ -3727,13 +3764,9 @@ namespace Oshima.FunGame.WebAPI.Services
return result;
}
(Room room, List<string> msgs) = await Controller.RoomRunGame(uid);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "房间", msg.Trim(), msgSeq: count++);
if (count <= real.Count) await Task.Delay(1500);
}
BotReply rpy = MergeToMarkdown("该局游戏结果如下:", msgs);
rpy.Keyboard = new KeyboardMessage().AppendButtons(1, Button.CreateCmdButton("快速重新开始", $"快速重新开始"));
await SendAsync(e, "房间", rpy, msgSeq: 1);
OnlineService.ReSetRoomState(room.Roomid);
}
else
@ -3948,6 +3981,21 @@ namespace Oshima.FunGame.WebAPI.Services
return await Handler(e, data);
}
public BotReply MergeToMarkdown(string subtitle, List<string> msgs)
{
if (msgs.Count > 30)
{
msgs = [.. msgs[..15], .. msgs[^15..]];
}
return new()
{
Markdown = new()
{
Content = $"{subtitle}```\r\n{string.Join("\r\n", msgs)}\r\n```"
}
};
}
public List<string> MergeMessages(List<string> msgs)
{
List<string> real = [];