mirror of
https://github.com/oshima-studios/OshimaGameModule.git
synced 2026-01-21 06:58:23 +00:00
添加多人游戏房间
This commit is contained in:
parent
c994bd2054
commit
a23802bdb0
@ -47,6 +47,7 @@
|
||||
创生之印 = 18012,
|
||||
法则精粹 = 18013,
|
||||
大师锻造券 = 18014,
|
||||
钻石 = 18998,
|
||||
探索许可 = 18999
|
||||
}
|
||||
|
||||
|
||||
13
OshimaModules/Items/SpecialItem/钻石.cs
Normal file
13
OshimaModules/Items/SpecialItem/钻石.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
using Milimoe.FunGame.Core.Library.Constant;
|
||||
|
||||
namespace Oshima.FunGame.OshimaModules.Items
|
||||
{
|
||||
public class 钻石() : Item(ItemType.SpecialItem)
|
||||
{
|
||||
public override long Id => (long)SpecialItemID.钻石;
|
||||
public override string Name => "钻石";
|
||||
public override string Description => "钻石是筽祀牻大陆通用的稀有矿物,是第二流通货币。钻石可以以稳定的 1:200 兑换率兑换大陆第一流通货币金币。";
|
||||
public override QualityType QualityType => QualityType.White;
|
||||
}
|
||||
}
|
||||
@ -36,6 +36,8 @@ namespace Oshima.FunGame.OshimaModules.Models
|
||||
public static Dictionary<long, LastStoreModel> UserLastVisitStore { get; } = [];
|
||||
public static ConcurrentDictionary<string, SemaphoreSlim> UserSemaphoreSlims { get; } = [];
|
||||
public static SemaphoreSlim MarketSemaphoreSlim { get; } = new(1, 1);
|
||||
public static Dictionary<string, Room> Rooms { get; set; } = [];
|
||||
public static Dictionary<long, Room> UsersInRoom { get; set; } = [];
|
||||
public static ItemType[] ItemCanUsed => [ItemType.Consumable, ItemType.MagicCard, ItemType.SpecialItem, ItemType.GiftBox, ItemType.Others];
|
||||
public static ItemType[] ItemCanNotDrawCard => [ItemType.Collectible, ItemType.QuestItem, ItemType.GiftBox, ItemType.Others];
|
||||
public static char[] SplitChars => [',', ' ', ',', ';', ';'];
|
||||
|
||||
@ -56,6 +56,7 @@ namespace Oshima.FunGame.OshimaModules
|
||||
(long)SpecialItemID.创生之印 => new 创生之印(),
|
||||
(long)SpecialItemID.法则精粹 => new 法则精粹(),
|
||||
(long)SpecialItemID.大师锻造券 => new 大师锻造券(),
|
||||
(long)SpecialItemID.钻石 => new 钻石(),
|
||||
(long)SpecialItemID.探索许可 => new 探索许可(),
|
||||
(long)ConsumableID.小回复药 => new 小回复药(),
|
||||
(long)ConsumableID.中回复药 => new 中回复药(),
|
||||
|
||||
@ -36,6 +36,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
||||
{
|
||||
template = CreateNewForgeStore();
|
||||
}
|
||||
else if (storeName == "dokyo_horseracing")
|
||||
{
|
||||
template = CreateNewHorseRacingStore();
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
||||
@ -109,6 +113,15 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
||||
}
|
||||
return $"现有锻造积分:{forgePoints:0.##}";
|
||||
}
|
||||
else if (storeName == "dokyo_horseracing")
|
||||
{
|
||||
double horseRacingPoints = 0;
|
||||
if (pc.TryGetValue("horseRacingPoints", out object? value) && double.TryParse(value.ToString(), out double points))
|
||||
{
|
||||
horseRacingPoints = points;
|
||||
}
|
||||
return $"现有赛马积分:{horseRacingPoints:0.##}";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -124,6 +137,7 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
||||
{
|
||||
EntityModuleConfig<Store> storeTemplate = new("stores", "dokyo");
|
||||
storeTemplate.LoadConfig();
|
||||
|
||||
Store? store = storeTemplate.Get("dokyo_forge");
|
||||
if (store is null)
|
||||
{
|
||||
@ -136,6 +150,20 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
||||
store.CopyGoodsToNextRefreshGoods(newStore.Goods);
|
||||
}
|
||||
storeTemplate.Add("dokyo_forge", store);
|
||||
|
||||
store = storeTemplate.Get("dokyo_horseracing");
|
||||
if (store is null)
|
||||
{
|
||||
store = CreateNewHorseRacingStore();
|
||||
}
|
||||
else
|
||||
{
|
||||
Store newStore = CreateNewHorseRacingStore();
|
||||
store.NextRefreshGoods.Clear();
|
||||
store.CopyGoodsToNextRefreshGoods(newStore.Goods);
|
||||
}
|
||||
storeTemplate.Add("dokyo_horseracing", store);
|
||||
|
||||
storeTemplate.SaveConfig();
|
||||
}
|
||||
|
||||
@ -143,6 +171,7 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
||||
{
|
||||
Store store = new("锻造积分商店")
|
||||
{
|
||||
GetNewerGoodsOnVisiting = true,
|
||||
AutoRefresh = true,
|
||||
RefreshInterval = 3,
|
||||
NextRefreshDate = DateTime.Today.AddHours(4),
|
||||
@ -161,5 +190,22 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
||||
}
|
||||
return store;
|
||||
}
|
||||
|
||||
private static Store CreateNewHorseRacingStore()
|
||||
{
|
||||
Store store = new("赛马积分商店")
|
||||
{
|
||||
GetNewerGoodsOnVisiting = true,
|
||||
AutoRefresh = true,
|
||||
RefreshInterval = 1,
|
||||
NextRefreshDate = DateTime.Today.AddHours(4),
|
||||
GlobalStock = true,
|
||||
};
|
||||
Item item = new 钻石();
|
||||
store.AddItem(item, -1);
|
||||
store.SetPrice(1, "赛马积分", 5);
|
||||
store.Goods[1].Quota = 300;
|
||||
return store;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,6 +136,8 @@ namespace Oshima.FunGame.OshimaServers
|
||||
{
|
||||
FunGameService.RefreshSavedCache();
|
||||
Controller.WriteLine("读取 FunGame 存档缓存", LogLevel.Debug);
|
||||
OnlineService.RoomsAutoDisband();
|
||||
Controller.WriteLine("清除空闲房间", LogLevel.Debug);
|
||||
}, true);
|
||||
TaskScheduler.Shared.AddTask("刷新每日任务", new TimeSpan(4, 0, 0), () =>
|
||||
{
|
||||
|
||||
132
OshimaServers/Model/Horse.cs
Normal file
132
OshimaServers/Model/Horse.cs
Normal file
@ -0,0 +1,132 @@
|
||||
using System.Text;
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
|
||||
namespace Oshima.FunGame.OshimaServers.Model
|
||||
{
|
||||
public class Horse(User user)
|
||||
{
|
||||
public long Id => user.Id;
|
||||
public string Name => user.Username;
|
||||
|
||||
// 基础属性,技能会在此基础上进行增减
|
||||
private int _step = 1;
|
||||
private int _hr = 1;
|
||||
private int _hp = 3;
|
||||
|
||||
public int MaxHP { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 每回合行动的步数
|
||||
/// </summary>
|
||||
public int Step
|
||||
{
|
||||
get
|
||||
{
|
||||
return _step;
|
||||
}
|
||||
set
|
||||
{
|
||||
_step = Math.Max(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前生命值
|
||||
/// </summary>
|
||||
public int HP
|
||||
{
|
||||
get
|
||||
{
|
||||
return _hp;
|
||||
}
|
||||
set
|
||||
{
|
||||
_hp = Math.Min(MaxHP, Math.Max(0, value));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 每回合恢复的HP值
|
||||
/// </summary>
|
||||
public int HPRecovery
|
||||
{
|
||||
get
|
||||
{
|
||||
return _hr;
|
||||
}
|
||||
set
|
||||
{
|
||||
_hr = Math.Max(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 马匹当前在赛道上的位置
|
||||
/// </summary>
|
||||
public int CurrentPosition { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 马匹拥有的永久技能
|
||||
/// </summary>
|
||||
public HashSet<HorseSkill> Skills { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 马匹当前正在生效的技能效果列表
|
||||
/// </summary>
|
||||
public List<ActiveSkillEffect> ActiveEffects { get; set; } = [];
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 技能定义
|
||||
/// </summary>
|
||||
public class HorseSkill(Horse? horse = null)
|
||||
{
|
||||
public Horse? Horse { get; set; } = horse;
|
||||
public string Name { get; set; } = "";
|
||||
public bool ToEnemy { get; set; } = false;
|
||||
public int AddStep { get; set; } = 0;
|
||||
public int ReduceStep { get; set; } = 0;
|
||||
public int AddHP { get; set; } = 0;
|
||||
public int ReduceHP { get; set; } = 0;
|
||||
public int AddHR { get; set; } = 0;
|
||||
public int ReduceHR { get; set; } = 0;
|
||||
public int ChangePosition { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 技能发动概率,1表示每回合都发动
|
||||
/// </summary>
|
||||
public double CastProbability { get; set; } = 1;
|
||||
/// <summary>
|
||||
/// 技能持续回合数,默认1回合(即立即生效并结束)
|
||||
/// </summary>
|
||||
public int Duration { get; set; } = 1;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder builder = new();
|
||||
|
||||
if (AddStep > 0) builder.Append($"每回合将额外移动 {AddStep} 步!");
|
||||
if (ReduceStep > 0) builder.Append($"每回合将少移动 {ReduceStep} 步!");
|
||||
if (AddHP > 0) builder.AppendLine($"恢复了 {AddHP} 点生命值!");
|
||||
if (ReduceHP > 0) builder.Append($"受到了 {ReduceHP} 点伤害!");
|
||||
if (AddHR > 0) builder.Append($"每回合将额外恢复 {AddHR} 点生命值!");
|
||||
if (ReduceHR > 0) builder.Append($"每回合将少恢复 {ReduceHR} 点生命值!");
|
||||
if (ChangePosition != 0) builder.Append($"{(ChangePosition > 0 ? "前进" : "后退")}了 {Math.Abs(ChangePosition)} 步!");
|
||||
|
||||
return builder.ToString().Trim();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于追踪马匹身上正在生效的技能效果
|
||||
/// </summary>
|
||||
public class ActiveSkillEffect(HorseSkill skill)
|
||||
{
|
||||
public HorseSkill Skill { get; } = skill;
|
||||
public int RemainDuration { get; set; } = skill.Duration;
|
||||
}
|
||||
}
|
||||
306
OshimaServers/Model/HorseRacing.cs
Normal file
306
OshimaServers/Model/HorseRacing.cs
Normal file
@ -0,0 +1,306 @@
|
||||
using System.Text;
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
using Oshima.FunGame.OshimaModules.Models;
|
||||
|
||||
namespace Oshima.FunGame.OshimaServers.Model
|
||||
{
|
||||
public static class HorseRacing
|
||||
{
|
||||
private const int MaxTurns = 100;
|
||||
private static readonly Random _random = new();
|
||||
|
||||
public static Dictionary<long, int> RunHorseRacing(List<string> msgs, Room room)
|
||||
{
|
||||
Dictionary<long, int> userPoints = [];
|
||||
|
||||
StringBuilder builder = new();
|
||||
builder.AppendLine("--- 参赛选手 ---");
|
||||
|
||||
List<Horse> horses = [];
|
||||
foreach (User user in room.UserAndIsReady.Keys)
|
||||
{
|
||||
if (FunGameConstant.UserIdAndUsername.TryGetValue(user.Id, out User? temp) && temp != null)
|
||||
{
|
||||
user.Username = temp.Username;
|
||||
}
|
||||
Horse horse = new(user);
|
||||
AssignRandomSkills(horse);
|
||||
horses.Add(horse);
|
||||
builder.AppendLine($"[ {horse}({horse.HP}) ] 已准备就绪!初始步数: {horse.Step}, 生命值: {horse.HP}, 每回合恢复生命值: {horse.HPRecovery}");
|
||||
if (horse.Skills.Count != 0)
|
||||
{
|
||||
builder.AppendLine($"[ {horse}({horse.HP}) ] 拥有技能: {string.Join(",", horse.Skills.Select(s => $"{s.Name}(持续 {s.Duration} 回合)"))}");
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine("\r\n--- 比赛开始! ---");
|
||||
|
||||
int maxLength = _random.Next(8, 16);
|
||||
builder.AppendLine($"本次抽取赛道长度:{maxLength} 步!");
|
||||
|
||||
for (int turn = 1; turn <= MaxTurns; turn++)
|
||||
{
|
||||
builder.AppendLine($"\r\n--- 第 {turn} 回合 ---");
|
||||
bool raceFinished = false;
|
||||
Dictionary<Horse, int> turnSteps = [];
|
||||
Dictionary<Horse, Dictionary<HorseSkill, Horse>> turnSkills = [];
|
||||
|
||||
// 先触发技能,后面一起结算,不然技能下个回合才能触发
|
||||
foreach (Horse horse in horses)
|
||||
{
|
||||
turnSkills.TryAdd(horse, []);
|
||||
// 触发永久技能
|
||||
foreach (HorseSkill skill in horse.Skills)
|
||||
{
|
||||
if (_random.NextDouble() < skill.CastProbability)
|
||||
{
|
||||
Horse target = horse;
|
||||
if (skill.ToEnemy)
|
||||
{
|
||||
target = horses.OrderBy(o => _random.Next(horses.Count)).First(h => h != horse);
|
||||
}
|
||||
turnSkills[horse].Add(skill, target);
|
||||
target.ActiveEffects.Add(new ActiveSkillEffect(skill));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Horse horse in horses)
|
||||
{
|
||||
turnSteps[horse] = 0;
|
||||
int effectiveStep = horse.Step; // 从基础步数开始计算
|
||||
int effectiveHPRecovery = horse.HPRecovery; // 从基础HP恢复开始计算
|
||||
List<string> turnEvents = []; // 记录本回合发生的事件
|
||||
|
||||
// 触发永久技能
|
||||
Dictionary<HorseSkill, Horse> skills = turnSkills[horse];
|
||||
foreach (HorseSkill skill in skills.Keys)
|
||||
{
|
||||
Horse target = skills[skill];
|
||||
// 如果是敌人
|
||||
if (skill.Duration > 0)
|
||||
{
|
||||
turnEvents.Add($"✨ 发动了 [ {skill.Name} ],持续 {skill.Duration} 回合!{(skill.ToEnemy ? $"[ {target} ] " : "")}{skill}");
|
||||
}
|
||||
else
|
||||
{
|
||||
turnEvents.Add($"✨ 发动了 [ {skill.Name} ]!{(skill.ToEnemy ? $"[ {target} ] " : "")}{skill}");
|
||||
}
|
||||
}
|
||||
|
||||
// 处理正在生效的持续技能效果
|
||||
List<ActiveSkillEffect> expiredEffects = [];
|
||||
foreach (ActiveSkillEffect activeEffect in horse.ActiveEffects)
|
||||
{
|
||||
HorseSkill skill = activeEffect.Skill;
|
||||
// 应用持续效果
|
||||
effectiveStep += skill.AddStep - skill.ReduceStep;
|
||||
effectiveHPRecovery += skill.AddHR - skill.ReduceHR;
|
||||
horse.HP += skill.AddHP - skill.ReduceHP;
|
||||
horse.CurrentPosition += skill.ChangePosition;
|
||||
turnSteps[horse] += skill.ChangePosition;
|
||||
|
||||
Horse? source = skill.Horse;
|
||||
if (source != null && source != horse) turnEvents.Add($"💥 受到了 [ {skill.Name}(来自:{source})] 的影响,{skill}");
|
||||
|
||||
activeEffect.RemainDuration--;
|
||||
if (activeEffect.RemainDuration <= 0)
|
||||
{
|
||||
expiredEffects.Add(activeEffect);
|
||||
}
|
||||
}
|
||||
// 移除已结束的持续效果
|
||||
foreach (ActiveSkillEffect expiredEffect in expiredEffects)
|
||||
{
|
||||
horse.ActiveEffects.Remove(expiredEffect);
|
||||
}
|
||||
|
||||
// 随机事件
|
||||
if (_random.NextDouble() < 0.5)
|
||||
{
|
||||
HorseSkill eventSkill = GenerateRandomEventSkill();
|
||||
// 随机事件技能也可能持续多回合
|
||||
if (eventSkill.Duration > 0)
|
||||
{
|
||||
horse.ActiveEffects.Add(new ActiveSkillEffect(eventSkill));
|
||||
turnEvents.Add($"💥 遭遇随机事件 [ {eventSkill.Name} ],持续 {eventSkill.Duration} 回合!{eventSkill}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果没有持续时间(Duration=0),则立即应用效果
|
||||
effectiveStep += eventSkill.AddStep - eventSkill.ReduceStep;
|
||||
effectiveHPRecovery += eventSkill.AddHR - eventSkill.ReduceHR;
|
||||
horse.HP += eventSkill.AddHP - eventSkill.ReduceHP;
|
||||
turnEvents.Add($"💥 遭遇随机事件 [ {eventSkill.Name} ]!{eventSkill}");
|
||||
}
|
||||
}
|
||||
|
||||
// 恢复HP,基于计算后的有效HP恢复值
|
||||
int hp = horse.HP;
|
||||
horse.HP += effectiveHPRecovery;
|
||||
if (hp != horse.HP)
|
||||
{
|
||||
builder.AppendLine($"[ {horse}({horse.HP}) ] ❤️ 生命值恢复至 {horse.HP} 点(+{effectiveHPRecovery})。");
|
||||
}
|
||||
|
||||
if (horse.HP <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 确保步数不为负
|
||||
effectiveStep = Math.Max(0, effectiveStep);
|
||||
horse.CurrentPosition += effectiveStep; // 移动
|
||||
|
||||
turnSteps[horse] += effectiveStep;
|
||||
//if (effectiveStep > 1) builder.AppendLine($"[ {horse}({horse.HP}) ] 移动了 {effectiveStep} 步!");
|
||||
if (turnEvents.Count != 0)
|
||||
{
|
||||
builder.AppendLine($"[ {horse}({horse.HP}) ] {string.Join(";", turnEvents)}");
|
||||
}
|
||||
|
||||
if (horse.CurrentPosition >= maxLength)
|
||||
{
|
||||
builder.AppendLine($"\r\n🎯 恭喜 [ {horse}({horse.HP}) ] 冲过终点线!它赢得了比赛!");
|
||||
raceFinished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine("\r\n--- 赛道状况 ---");
|
||||
for (int i = 0; i < horses.Count; i++)
|
||||
{
|
||||
builder.AppendLine(GenerateTrackString(horses[i], i + 1, maxLength, turnSteps));
|
||||
}
|
||||
|
||||
msgs.Add(builder.ToString().Trim());
|
||||
builder.Clear();
|
||||
|
||||
if (raceFinished)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
builder.Clear();
|
||||
builder.AppendLine("\r\n--- 比赛结果 ---");
|
||||
List<Horse> finalRanking = [.. horses.OrderByDescending(h => h.CurrentPosition)];
|
||||
int points = 10;
|
||||
for (int i = 0; i < finalRanking.Count; i++)
|
||||
{
|
||||
userPoints[finalRanking[i].Id] = points;
|
||||
builder.AppendLine($"第 {i + 1} 名:{finalRanking[i].Name}(获得 {points} 点赛马积分)");
|
||||
points = (int)(points * 0.8);
|
||||
if (points == 0) points = 1;
|
||||
}
|
||||
|
||||
builder.AppendLine("\r\n--- 比赛结束,奖励将在稍后发放! ---");
|
||||
msgs.Add(builder.ToString().Trim());
|
||||
|
||||
return userPoints;
|
||||
}
|
||||
|
||||
private static void AssignRandomSkills(Horse horse)
|
||||
{
|
||||
// 技能池
|
||||
List<HorseSkill> skillPool = [
|
||||
new() { Name = "冲刺", AddStep = 2, CastProbability = 0.3, Duration = 1 }, // 普通冲刺,1回合
|
||||
new() { Name = "耐力爆发", AddHP = 2, CastProbability = 0.3, Duration = 1 }, // 瞬间回血
|
||||
new() { Name = "神行百变", AddStep = 1, AddHR = 1, CastProbability = 0.3, Duration = 3 }, // 持续3回合的加速和恢复
|
||||
new() { Name = "稳健", AddStep = 0, AddHR = 1, CastProbability = 0.3, Duration = 2 }, // 持续2回合的额外恢复
|
||||
new() { Name = "疾风步", AddStep = 1, CastProbability = 0.15, Duration = 2 }, // 强大的2回合加速
|
||||
new() { Name = "疲惫", ToEnemy = true, ReduceStep = 1, CastProbability = 0.4, Duration = 2 }, // 持续2回合的减速
|
||||
new() { Name = "摔跤", ToEnemy = true, ReduceHP = 2, ReduceStep = 1, CastProbability = 0.4, Duration = 1 }, // 瞬间掉血减速
|
||||
new() { Name = "干扰", ToEnemy = true, ReduceStep = 2, CastProbability = 0.3, Duration = 1 }, // 瞬间减速
|
||||
new() { Name = "石头攻击", ToEnemy = true, ReduceHP = 3, CastProbability = 0.4, Duration = 1 }, // 瞬间掉血
|
||||
new() { Name = "台风", ToEnemy = true, ReduceHP = 2, CastProbability = 0.4, Duration = 2 }, // 强大的2回合掉血
|
||||
new() { Name = "死刑宣告", ToEnemy = true, ReduceHP = 2, ReduceHR = 1, CastProbability = 0.3, Duration = 2 }, // 瞬间掉血+重伤
|
||||
new() { Name = "后退吧!", ToEnemy = true, ChangePosition = -2, CastProbability = 0.3, Duration = 1 }, // 直接改变位置
|
||||
];
|
||||
|
||||
int skillsToAssign = _random.Next(1, 4);
|
||||
|
||||
for (int i = 0; i < skillsToAssign; i++)
|
||||
{
|
||||
HorseSkill chosenSkill = skillPool[_random.Next(skillPool.Count)];
|
||||
while (true)
|
||||
{
|
||||
if (!horse.Skills.Any(s => s.Name == chosenSkill.Name))
|
||||
{
|
||||
break;
|
||||
}
|
||||
// 如果技能已存在,重新选择
|
||||
chosenSkill = skillPool[_random.Next(skillPool.Count)];
|
||||
}
|
||||
horse.Skills.Add(new HorseSkill
|
||||
{
|
||||
Horse = horse,
|
||||
Name = chosenSkill.Name,
|
||||
ToEnemy = chosenSkill.ToEnemy,
|
||||
AddStep = chosenSkill.AddStep,
|
||||
ReduceStep = chosenSkill.ReduceStep,
|
||||
AddHP = chosenSkill.AddHP,
|
||||
ReduceHP = chosenSkill.ReduceHP,
|
||||
AddHR = chosenSkill.AddHR,
|
||||
ReduceHR = chosenSkill.ReduceHR,
|
||||
ChangePosition = chosenSkill.ChangePosition,
|
||||
CastProbability = chosenSkill.CastProbability,
|
||||
Duration = chosenSkill.Duration
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static HorseSkill GenerateRandomEventSkill()
|
||||
{
|
||||
// 随机事件
|
||||
List<HorseSkill> eventPool = [
|
||||
new() { Name = "加速带", AddStep = 3, Duration = 1 }, // 瞬间加速
|
||||
new() { Name = "泥泞区", ReduceStep = 2, Duration = 2 }, // 持续2回合减速
|
||||
new() { Name = "观众欢呼", AddHP = 2, Duration = 1 }, // 瞬间回血
|
||||
new() { Name = "小石子", ReduceHP = 1, Duration = 1 }, // 瞬间掉血
|
||||
new() { Name = "顺风", AddStep = 1, Duration = 3 }, // 持续3回合微加速
|
||||
new() { Name = "逆风", ReduceStep = 1, Duration = 2 }, // 持续2回合微减速
|
||||
new() { Name = "兴奋剂", AddStep = 2, Duration = 4, ReduceHP = 2 } // 兴奋剂,有副作用
|
||||
];
|
||||
|
||||
return eventPool[_random.Next(eventPool.Count)];
|
||||
}
|
||||
|
||||
private static string GenerateTrackString(Horse horse, int trackNumber, int maxLength, Dictionary<Horse, int> turnSteps)
|
||||
{
|
||||
StringBuilder builder = new();
|
||||
|
||||
builder.Append($"[{trackNumber}]|");
|
||||
|
||||
if (horse.CurrentPosition < 0) horse.CurrentPosition = 0;
|
||||
int dashesBeforeHorse = Math.Min(horse.CurrentPosition, maxLength);
|
||||
int dashesAfterHorse = Math.Max(0, maxLength - horse.CurrentPosition);
|
||||
builder.Append(new string('=', dashesAfterHorse));
|
||||
|
||||
string horseMarker = $"<{horse}>";
|
||||
if (horse.ActiveEffects.Count > 0 || horse.HP == 0)
|
||||
{
|
||||
if (horse.HP == 0)
|
||||
{
|
||||
horseMarker = $"[💀死亡]<{horse}>";
|
||||
}
|
||||
if (horse.ActiveEffects.Count > 0)
|
||||
{
|
||||
horseMarker += $"[{string.Join("][", horse.ActiveEffects.Select(e => e.Skill.Name))}]";
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append(horseMarker);
|
||||
builder.Append(new string('=', dashesBeforeHorse));
|
||||
|
||||
int turnStep = 1;
|
||||
if (turnSteps.TryGetValue(horse, out int step))
|
||||
{
|
||||
turnStep = step;
|
||||
}
|
||||
builder.Append($"|({horse.CurrentPosition})({(turnStep >= 0 ? "+" : "")}{turnStep})");
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,6 +98,15 @@
|
||||
{"取消锻造", "取消已经创建的锻造配方" },
|
||||
{"模拟锻造", "模拟锻造结果" },
|
||||
{"确认开始锻造", "确认已经创建的锻造配方并开始锻造" },
|
||||
{"创建房间 <类型>", "类型:mix/team/cooperative/horseracing对应混战/团队/共斗/赛马" },
|
||||
{"加入房间 <房间号>", "加入多人游戏房间" },
|
||||
{"退出房间", "退出多人游戏房间" },
|
||||
{"开始游戏", "开始多人游戏" },
|
||||
{"创建混战", "快速创建混战房间" },
|
||||
{"创建团战", "快速创建团队死斗房间" },
|
||||
{"创建共斗", "快速创建共斗房间" },
|
||||
{"创建赛马", "快速创建赛马房间" },
|
||||
{"加入赛马", "快速加入赛马房间" },
|
||||
};
|
||||
|
||||
public static Dictionary<string, string> ClubHelp { get; } = new() {
|
||||
@ -146,7 +155,8 @@
|
||||
{"商店2", "查看武器商会商品"},
|
||||
{"商店3", "查看杂货铺商品"},
|
||||
{"商店4", "查看慈善基金会商品"},
|
||||
{"锻造商店", "查看锻造积分商店商品"},
|
||||
{"锻造商店/商店5", "查看锻造积分商店商品"},
|
||||
{"赛马商店/商店6", "查看锻造积分商店商品"},
|
||||
{"商店查看 <商品序号>", "查看指定商品详情,访问任意商店后2分钟内可用"},
|
||||
{"商店购买 <商品序号>", "购买指定商品,访问任意商店后2分钟内可用"},
|
||||
{"商店出售 <物品序号>", "向商店出售具有回收价的指定物品"},
|
||||
|
||||
@ -624,6 +624,12 @@ namespace Oshima.FunGame.OshimaServers.Service
|
||||
}
|
||||
}
|
||||
|
||||
// 检查在线状态
|
||||
if (FunGameConstant.UsersInRoom.ContainsKey(user.Id))
|
||||
{
|
||||
user.OnlineState = OnlineState.InRoom;
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@ -2161,6 +2167,19 @@ namespace Oshima.FunGame.OshimaServers.Service
|
||||
return $"你的{needy}不足 {reduce} 呢,无法购买【{goods.Name}】!";
|
||||
}
|
||||
}
|
||||
else if (needy == "赛马积分")
|
||||
{
|
||||
double reduce = Calculation.Round2Digits(goods.Prices[needy] * count);
|
||||
if (pc.TryGetValue("horseRacingPoints", out object? value) && double.TryParse(value.ToString(), out double points) && points >= reduce)
|
||||
{
|
||||
points -= reduce;
|
||||
pc.Add("horseRacingPoints", points);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"你的{needy}不足 {reduce} 呢,无法购买【{goods.Name}】!";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"不支持的货币类型:{needy},无法购买【{goods.Name}】!";
|
||||
@ -2169,7 +2188,11 @@ namespace Oshima.FunGame.OshimaServers.Service
|
||||
|
||||
foreach (Item item in goods.Items)
|
||||
{
|
||||
if (item.Id == (long)SpecialItemID.探索许可)
|
||||
if (item.Id == (long)SpecialItemID.钻石)
|
||||
{
|
||||
user.Inventory.Materials += count;
|
||||
}
|
||||
else if (item.Id == (long)SpecialItemID.探索许可)
|
||||
{
|
||||
int exploreTimes = FunGameConstant.MaxExploreTimes + count;
|
||||
if (pc.TryGetValue("exploreTimes", out object? value) && int.TryParse(value.ToString(), out exploreTimes))
|
||||
@ -4456,7 +4479,45 @@ namespace Oshima.FunGame.OshimaServers.Service
|
||||
|
||||
public static void RefreshSavedCache()
|
||||
{
|
||||
string directoryPath = $@"{AppDomain.CurrentDomain.BaseDirectory}configs/saved";
|
||||
string directoryPath;
|
||||
Dictionary<long, int> hrPoints = [];
|
||||
try
|
||||
{
|
||||
OnlineService.GetHorseRacingSettleSemaphoreSlim();
|
||||
directoryPath = $@"{AppDomain.CurrentDomain.BaseDirectory}configs/horseracing";
|
||||
if (Directory.Exists(directoryPath))
|
||||
{
|
||||
string[] filePaths = Directory.GetFiles(directoryPath);
|
||||
foreach (string filePath in filePaths)
|
||||
{
|
||||
string fileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
PluginConfig pc = new("horseracing", fileName);
|
||||
pc.LoadConfig();
|
||||
if (pc.Get<Dictionary<long, int>>("points") is Dictionary<long, int> points)
|
||||
{
|
||||
foreach (long userId in points.Keys)
|
||||
{
|
||||
if (hrPoints.ContainsKey(userId))
|
||||
{
|
||||
hrPoints[userId] += points[userId];
|
||||
}
|
||||
else
|
||||
{
|
||||
hrPoints[userId] = points[userId];
|
||||
}
|
||||
}
|
||||
}
|
||||
pc.Remove("points");
|
||||
pc.SaveConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
OnlineService.ReleaseHorseRacingSettleSemaphoreSlim();
|
||||
}
|
||||
directoryPath = $@"{AppDomain.CurrentDomain.BaseDirectory}configs/saved";
|
||||
if (Directory.Exists(directoryPath))
|
||||
{
|
||||
string[] filePaths = Directory.GetFiles(directoryPath);
|
||||
@ -4471,6 +4532,7 @@ namespace Oshima.FunGame.OshimaServers.Service
|
||||
FunGameConstant.UserIdAndUsername[user.Id] = user;
|
||||
bool updateQuest = false;
|
||||
bool updateExplore = false;
|
||||
bool updateHorseRacing = false;
|
||||
// 任务结算
|
||||
EntityModuleConfig<Quest> quests = new("quests", user.Id.ToString());
|
||||
quests.LoadConfig();
|
||||
@ -4487,7 +4549,20 @@ namespace Oshima.FunGame.OshimaServers.Service
|
||||
pc2.SaveConfig();
|
||||
updateExplore = true;
|
||||
}
|
||||
if (updateQuest || updateExplore)
|
||||
// 赛马结算
|
||||
if (hrPoints.TryGetValue(user.Id, out int points))
|
||||
{
|
||||
if (pc.TryGetValue("horseRacingPoints", out object? value2) && int.TryParse(value2.ToString(), out int userPoints))
|
||||
{
|
||||
pc.Add("horseRacingPoints", userPoints + points);
|
||||
}
|
||||
else
|
||||
{
|
||||
pc.Add("horseRacingPoints", points);
|
||||
}
|
||||
updateHorseRacing = true;
|
||||
}
|
||||
if (updateQuest || updateExplore || updateHorseRacing)
|
||||
{
|
||||
SetUserConfigButNotRelease(user.Id, pc, user);
|
||||
}
|
||||
|
||||
381
OshimaServers/Service/OnlineService.cs
Normal file
381
OshimaServers/Service/OnlineService.cs
Normal file
@ -0,0 +1,381 @@
|
||||
using Milimoe.FunGame.Core.Api.Utility;
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
using Milimoe.FunGame.Core.Library.Constant;
|
||||
using Oshima.FunGame.OshimaModules.Models;
|
||||
using Oshima.FunGame.OshimaServers.Model;
|
||||
|
||||
namespace Oshima.FunGame.OshimaServers.Service
|
||||
{
|
||||
public class OnlineService
|
||||
{
|
||||
public static SemaphoreSlim RoomSemaphoreSlim { get; } = new(1, 1);
|
||||
public static SemaphoreSlim HorseRacingSettleSemaphoreSlim { get; } = new(1, 1);
|
||||
public static Dictionary<string, bool> GroupsHasHorseRacing { get; } = [];
|
||||
|
||||
public static void GetRoomSemaphoreSlim()
|
||||
{
|
||||
RoomSemaphoreSlim.Wait(FunGameConstant.SemaphoreSlimTimeout);
|
||||
}
|
||||
|
||||
public static void ReleaseRoomSemaphoreSlim()
|
||||
{
|
||||
if (RoomSemaphoreSlim.CurrentCount == 0)
|
||||
{
|
||||
RoomSemaphoreSlim.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetHorseRacingSettleSemaphoreSlim()
|
||||
{
|
||||
HorseRacingSettleSemaphoreSlim.Wait(FunGameConstant.SemaphoreSlimTimeout);
|
||||
}
|
||||
|
||||
public static void ReleaseHorseRacingSettleSemaphoreSlim()
|
||||
{
|
||||
if (HorseRacingSettleSemaphoreSlim.CurrentCount == 0)
|
||||
{
|
||||
HorseRacingSettleSemaphoreSlim.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public static Room CreateRoom(User user, string roomType, string password, string groupId, out string msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetRoomSemaphoreSlim();
|
||||
long id = FunGameConstant.Rooms.Count > 0 ? FunGameConstant.Rooms.Values.Max(r => r.Id) + 1 : 1;
|
||||
Room room = Factory.GetRoom(id, password: password);
|
||||
msg = "";
|
||||
if (FunGameConstant.UsersInRoom.TryGetValue(user.Id, out Room? room2) && room2 != null)
|
||||
{
|
||||
msg = $"你已经在{room2.Name} [ {room2.Roomid} ] 中了,请先离开房间后再创建房间。";
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (roomType)
|
||||
{
|
||||
case "horseracing":
|
||||
if (GroupsHasHorseRacing.TryGetValue(groupId, out bool has) && has)
|
||||
{
|
||||
msg = "本群已经存在一个赛马房间!空闲房间会在 6 分钟后自动解散,请先等待该房间完成比赛或自动解散。";
|
||||
}
|
||||
else
|
||||
{
|
||||
room.RoomType = RoomType.Custom;
|
||||
room.Name = "赛马房间";
|
||||
room.GameMap = groupId;
|
||||
room.MaxUsers = 8;
|
||||
}
|
||||
break;
|
||||
case "mix":
|
||||
room.RoomType = RoomType.Mix;
|
||||
room.Name = "混战房间";
|
||||
room.MaxUsers = 10;
|
||||
break;
|
||||
case "team":
|
||||
room.RoomType = RoomType.Team;
|
||||
room.Name = "团队死斗房间";
|
||||
room.MaxUsers = 8;
|
||||
break;
|
||||
case "cooperative":
|
||||
room.RoomType = RoomType.Custom;
|
||||
room.Name = "共斗房间";
|
||||
room.MaxUsers = 4;
|
||||
break;
|
||||
default:
|
||||
msg = "不支持的房间类型。";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (msg == "")
|
||||
{
|
||||
room.Roomid = Verification.CreateVerifyCode(VerifyCodeType.MixVerifyCode, 7);
|
||||
while (true)
|
||||
{
|
||||
if (!FunGameConstant.Rooms.ContainsKey(room.Roomid))
|
||||
{
|
||||
break;
|
||||
}
|
||||
room.Roomid = Verification.CreateVerifyCode(VerifyCodeType.MixVerifyCode, 7);
|
||||
}
|
||||
msg = $"房间创建成功,房间号为:{room.Roomid}\r\n注意:房间若在 6 分钟后仍处于空闲状态,将自动解散。";
|
||||
room.RoomMaster = user;
|
||||
room.CreateTime = DateTime.Now;
|
||||
}
|
||||
if (room.Roomid != "-1")
|
||||
{
|
||||
FunGameConstant.Rooms[room.Roomid] = room;
|
||||
if (room.Name == "赛马房间")
|
||||
{
|
||||
GroupsHasHorseRacing[room.GameMap] = true;
|
||||
}
|
||||
}
|
||||
return room;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
msg = $"创建房间失败,错误信息:{e.Message}";
|
||||
return Factory.GetRoom();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseRoomSemaphoreSlim();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IntoRoom(User user, string roomid, string password, out string msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetRoomSemaphoreSlim();
|
||||
msg = "";
|
||||
if (FunGameConstant.Rooms.TryGetValue(roomid, out Room? room) && room != null)
|
||||
{
|
||||
if (password == room.Password)
|
||||
{
|
||||
if (FunGameConstant.UsersInRoom.TryGetValue(user.Id, out Room? room2) && room2 != null)
|
||||
{
|
||||
msg = $"你已经在{room2.Name} [ {room2.Roomid} ] 中了,请先退出房间后再加入房间。";
|
||||
return false;
|
||||
}
|
||||
if (room.UserAndIsReady.Count >= room.MaxUsers)
|
||||
{
|
||||
msg = "房间人数已满,无法加入。";
|
||||
return false;
|
||||
}
|
||||
if (room.RoomState != RoomState.Created)
|
||||
{
|
||||
msg = "房间状态异常,无法加入。";
|
||||
return false;
|
||||
}
|
||||
FunGameConstant.UsersInRoom[user.Id] = room;
|
||||
room.UserAndIsReady[user] = true;
|
||||
user.OnlineState = OnlineState.InRoom;
|
||||
msg = $"成功加入{room.Name}:{room.Roomid}\r\n房间人数:{room.UserAndIsReady.Count} / {room.MaxUsers}";
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = "密码错误,无法加入房间。";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = "房间不存在,无法加入。";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
msg = $"加入房间失败,错误信息:{e.Message}";
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseRoomSemaphoreSlim();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool QuitRoom(User user, out string msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetRoomSemaphoreSlim();
|
||||
msg = "";
|
||||
if (FunGameConstant.UsersInRoom.TryGetValue(user.Id, out Room? room) && room != null)
|
||||
{
|
||||
if (room.RoomState != RoomState.Created)
|
||||
{
|
||||
msg = "房间状态异常,无法退出。";
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
FunGameConstant.UsersInRoom.Remove(user.Id);
|
||||
msg = $"成功退出{room.Name}:{room.Roomid}";
|
||||
User[] users = [.. room.UserAndIsReady.Keys.Where(u => u.Id == user.Id)];
|
||||
foreach (User userTemp in users)
|
||||
{
|
||||
room.UserAndIsReady.Remove(userTemp);
|
||||
}
|
||||
if (room.UserAndIsReady.Count == 0)
|
||||
{
|
||||
FunGameConstant.Rooms.Remove(room.Roomid);
|
||||
msg += ",该房间人数为零,已解散该房间。";
|
||||
if (room.Name == "赛马房间")
|
||||
{
|
||||
GroupsHasHorseRacing[room.GameMap] = false;
|
||||
}
|
||||
}
|
||||
else if (room.RoomMaster.Id == user.Id)
|
||||
{
|
||||
User newRoomMaster = room.UserAndIsReady.Keys.First();
|
||||
room.RoomMaster = newRoomMaster;
|
||||
string newRoomMasterName = newRoomMaster.Username;
|
||||
if (FunGameConstant.UserIdAndUsername.TryGetValue(newRoomMaster.Id, out User? temp) && temp != null)
|
||||
{
|
||||
newRoomMasterName = temp.Username;
|
||||
}
|
||||
msg += $",新房主为:{newRoomMasterName}。";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = "你当前不在任何房间中。";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
msg = $"退出房间失败,错误信息:{e.Message}";
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseRoomSemaphoreSlim();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RoomsAutoDisband()
|
||||
{
|
||||
try
|
||||
{
|
||||
GetRoomSemaphoreSlim();
|
||||
Room[] rooms = [.. FunGameConstant.Rooms.Values];
|
||||
foreach (Room room in rooms)
|
||||
{
|
||||
if (room.RoomState == RoomState.Created && room.CreateTime.AddMinutes(6) < DateTime.Now)
|
||||
{
|
||||
foreach (User user in room.UserAndIsReady.Keys)
|
||||
{
|
||||
FunGameConstant.UsersInRoom.Remove(user.Id);
|
||||
}
|
||||
FunGameConstant.Rooms.Remove(room.Roomid);
|
||||
if (room.Name == "赛马房间")
|
||||
{
|
||||
GroupsHasHorseRacing[room.GameMap] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
ReleaseRoomSemaphoreSlim();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReSetRoomState(string roomid)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetRoomSemaphoreSlim();
|
||||
if (FunGameConstant.Rooms.TryGetValue(roomid, out Room? room) && room != null)
|
||||
{
|
||||
room.CreateTime = DateTime.Now;
|
||||
room.RoomState = RoomState.Created;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
ReleaseRoomSemaphoreSlim();
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<(Room, List<string>)> RunGameAsync(User user)
|
||||
{
|
||||
Room room = General.HallInstance;
|
||||
try
|
||||
{
|
||||
GetRoomSemaphoreSlim();
|
||||
List<string> msgs = [];
|
||||
if (FunGameConstant.UsersInRoom.TryGetValue(user.Id, out Room? value) && value != null)
|
||||
{
|
||||
room = value;
|
||||
if (room.RoomMaster.Id != user.Id)
|
||||
{
|
||||
msgs.Add("你不是房主,无法开始游戏。");
|
||||
}
|
||||
else if (room.RoomState != RoomState.Created)
|
||||
{
|
||||
msgs.Add("房间状态异常,无法开始游戏,已自动解散该房间。");
|
||||
foreach (User userTemp in room.UserAndIsReady.Keys)
|
||||
{
|
||||
FunGameConstant.UsersInRoom.Remove(userTemp.Id);
|
||||
}
|
||||
FunGameConstant.Rooms.Remove(room.Roomid);
|
||||
if (room.Name == "赛马房间")
|
||||
{
|
||||
GroupsHasHorseRacing[room.GameMap] = false;
|
||||
}
|
||||
}
|
||||
else if (room.UserAndIsReady.Count < 2)
|
||||
{
|
||||
msgs.Add("房间人数不足,无法开始游戏。");
|
||||
}
|
||||
else
|
||||
{
|
||||
room.RoomState = RoomState.Gaming;
|
||||
switch (room.Name)
|
||||
{
|
||||
case "赛马房间":
|
||||
try
|
||||
{
|
||||
GetHorseRacingSettleSemaphoreSlim();
|
||||
Dictionary<long, int> userPoints = HorseRacing.RunHorseRacing(msgs, room);
|
||||
PluginConfig pc = new("horseracing", room.GameMap);
|
||||
pc.LoadConfig();
|
||||
Dictionary<long, int> waitforsettle = pc.Get<Dictionary<long, int>>("points") ?? [];
|
||||
foreach (long uid in waitforsettle.Keys)
|
||||
{
|
||||
int points = waitforsettle[uid];
|
||||
if (userPoints.ContainsKey(uid))
|
||||
{
|
||||
userPoints[uid] += points;
|
||||
}
|
||||
else
|
||||
{
|
||||
userPoints[uid] = points;
|
||||
}
|
||||
}
|
||||
pc.Add("points", userPoints);
|
||||
pc.SaveConfig();
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
msgs.Add("Error: " + e2.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseHorseRacingSettleSemaphoreSlim();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
msgs.Add("游戏已开始!");
|
||||
await Task.Delay(5000);
|
||||
msgs.Add("游戏已结束!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msgs.Add("你当前不在任何房间中。");
|
||||
}
|
||||
return (room, msgs);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return (room, [$"游戏遇到错误,错误信息:{e.Message}"]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseRoomSemaphoreSlim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2813,6 +2813,32 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
||||
pc2.Add("exploreTimes", exploreTimes);
|
||||
msg = $"已为 [ {user2} ] 生成 {itemCount} 个探索许可";
|
||||
}
|
||||
else if (itemName == "锻造积分")
|
||||
{
|
||||
if (pc.TryGetValue("forgepoints", out object? value) && int.TryParse(value.ToString(), out int forgepoints))
|
||||
{
|
||||
forgepoints += itemCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
forgepoints = itemCount;
|
||||
}
|
||||
pc2.Add("forgepoints", forgepoints);
|
||||
msg = $"已为 [ {user2} ] 生成 {itemCount} 个锻造积分";
|
||||
}
|
||||
else if (itemName == "赛马积分")
|
||||
{
|
||||
if (pc.TryGetValue("horseRacingPoints", out object? value) && int.TryParse(value.ToString(), out int horseRacingPoints))
|
||||
{
|
||||
horseRacingPoints += itemCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
horseRacingPoints = itemCount;
|
||||
}
|
||||
pc2.Add("horseRacingPoints", horseRacingPoints);
|
||||
msg = $"已为 [ {user2} ] 生成 {itemCount} 个锻造积分";
|
||||
}
|
||||
else if (itemName.Contains("魔法卡礼包"))
|
||||
{
|
||||
foreach (string type in ItemSet.QualityTypeNameArray)
|
||||
@ -2926,7 +2952,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
||||
FunGameService.SetUserConfigAndReleaseSemaphoreSlim(userid, pc, user);
|
||||
|
||||
string msg = "";
|
||||
if (user.IsAdmin || userid > 0)
|
||||
if (user.IsAdmin)
|
||||
{
|
||||
PluginConfig pc2 = FunGameService.GetUserConfig(targetid, out _);
|
||||
if (pc2.Count > 0)
|
||||
@ -6709,7 +6735,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
||||
{
|
||||
User user = FunGameService.GetUser(pc);
|
||||
|
||||
if (user.IsAdmin || user.IsOperator)
|
||||
if (user.IsAdmin)
|
||||
{
|
||||
PluginConfig renameExamine = new("examines", "rename");
|
||||
renameExamine.LoadConfig();
|
||||
@ -6793,7 +6819,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
||||
FunGameService.ReleaseUserSemaphoreSlim(userid);
|
||||
}
|
||||
|
||||
if (user.IsAdmin || user.IsOperator)
|
||||
if (user.IsAdmin)
|
||||
{
|
||||
PluginConfig renameExamine = new("examines", "rename");
|
||||
renameExamine.LoadConfig();
|
||||
@ -7959,6 +7985,162 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("createroom")]
|
||||
public string CreateRoom([FromQuery] long uid = -1, [FromQuery] string roomType = "", [FromQuery] string password = "", [FromQuery] string groupId = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
PluginConfig pc = FunGameService.GetUserConfig(uid, out bool isTimeout);
|
||||
if (isTimeout)
|
||||
{
|
||||
return busy;
|
||||
}
|
||||
|
||||
string msg = "";
|
||||
if (pc.Count > 0)
|
||||
{
|
||||
User user = FunGameService.GetUser(pc);
|
||||
|
||||
Room room = OnlineService.CreateRoom(user, roomType, password, groupId, out msg);
|
||||
if (room.Roomid != "-1")
|
||||
{
|
||||
if (OnlineService.IntoRoom(user, room.Roomid, password, out string msg2))
|
||||
{
|
||||
msg += $"\r\n{msg2}";
|
||||
}
|
||||
}
|
||||
|
||||
FunGameService.SetUserConfigButNotRelease(uid, pc, user);
|
||||
return msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
return noSaved;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(e, "Error: {e}", e);
|
||||
return busy;
|
||||
}
|
||||
finally
|
||||
{
|
||||
FunGameService.ReleaseUserSemaphoreSlim(uid);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("intoroom")]
|
||||
public string IntoRoom([FromQuery] long uid = -1, [FromQuery] string roomid = "", [FromQuery] string password = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
PluginConfig pc = FunGameService.GetUserConfig(uid, out bool isTimeout);
|
||||
if (isTimeout)
|
||||
{
|
||||
return busy;
|
||||
}
|
||||
|
||||
string msg = "";
|
||||
if (pc.Count > 0)
|
||||
{
|
||||
User user = FunGameService.GetUser(pc);
|
||||
|
||||
OnlineService.IntoRoom(user, roomid, password, out msg);
|
||||
|
||||
FunGameService.SetUserConfigButNotRelease(uid, pc, user);
|
||||
return msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
return noSaved;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(e, "Error: {e}", e);
|
||||
return busy;
|
||||
}
|
||||
finally
|
||||
{
|
||||
FunGameService.ReleaseUserSemaphoreSlim(uid);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("quitroom")]
|
||||
public string QuitRoom([FromQuery] long uid = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
PluginConfig pc = FunGameService.GetUserConfig(uid, out bool isTimeout);
|
||||
if (isTimeout)
|
||||
{
|
||||
return busy;
|
||||
}
|
||||
|
||||
string msg = "";
|
||||
if (pc.Count > 0)
|
||||
{
|
||||
User user = FunGameService.GetUser(pc);
|
||||
|
||||
OnlineService.QuitRoom(user, out msg);
|
||||
|
||||
FunGameService.SetUserConfigButNotRelease(uid, pc, user);
|
||||
return msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
return noSaved;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(e, "Error: {e}", e);
|
||||
return busy;
|
||||
}
|
||||
finally
|
||||
{
|
||||
FunGameService.ReleaseUserSemaphoreSlim(uid);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("rungame")]
|
||||
public async Task<(Room, List<string>)> RunGame([FromQuery] long uid = -1)
|
||||
{
|
||||
Room room = General.HallInstance;
|
||||
try
|
||||
{
|
||||
PluginConfig pc = FunGameService.GetUserConfig(uid, out bool isTimeout);
|
||||
if (isTimeout)
|
||||
{
|
||||
return (room, [busy]);
|
||||
}
|
||||
|
||||
List<string> msgs = [];
|
||||
if (pc.Count > 0)
|
||||
{
|
||||
User user = FunGameService.GetUser(pc);
|
||||
|
||||
(room, msgs) = await OnlineService.RunGameAsync(user);
|
||||
|
||||
FunGameService.SetUserConfigButNotRelease(uid, pc, user);
|
||||
return (room, msgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (room, [noSaved]);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(e, "Error: {e}", e);
|
||||
return (room, [busy]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
FunGameService.ReleaseUserSemaphoreSlim(uid);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("template")]
|
||||
public string Template([FromQuery] long uid = -1)
|
||||
{
|
||||
|
||||
@ -94,6 +94,9 @@ namespace Oshima.FunGame.WebAPI.Models
|
||||
[JsonPropertyName("isgroup")]
|
||||
public bool IsGroup { get; set; } = false;
|
||||
|
||||
[JsonPropertyName("group_openid")]
|
||||
public string GroupOpenId { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("detail")]
|
||||
public string Detail { get; set; } = "";
|
||||
|
||||
|
||||
@ -47,10 +47,10 @@ namespace Oshima.FunGame.WebAPI
|
||||
{
|
||||
// 获取 RainBOTService 实例
|
||||
RainBOTService bot = serviceProvider.GetRequiredService<RainBOTService>();
|
||||
Controller.WriteLine("成功获取 RainBOTService 实例!");
|
||||
ThirdPartyMessage message = new()
|
||||
{
|
||||
IsGroup = false,
|
||||
IsGroup = true,
|
||||
GroupOpenId = "1",
|
||||
AuthorOpenId = "1",
|
||||
OpenId = "1",
|
||||
Detail = input,
|
||||
|
||||
@ -320,7 +320,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
FunGameSimulation = true;
|
||||
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: 0);
|
||||
List<string> real = [];
|
||||
int remain = 7;
|
||||
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||
string merge = "";
|
||||
for (int i = 0; i < msgs.Count - 2; i++)
|
||||
{
|
||||
@ -350,7 +350,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
foreach (string msg in real)
|
||||
{
|
||||
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
|
||||
await Task.Delay(5500);
|
||||
if (count != real.Count) await Task.Delay(5500);
|
||||
}
|
||||
FunGameSimulation = false;
|
||||
}
|
||||
@ -375,7 +375,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
FunGameSimulation = true;
|
||||
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: maxRespawnTimesMix);
|
||||
List<string> real = [];
|
||||
int remain = 7;
|
||||
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||
string merge = "";
|
||||
for (int i = 0; i < msgs.Count - 2; i++)
|
||||
{
|
||||
@ -405,7 +405,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
foreach (string msg in real)
|
||||
{
|
||||
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
|
||||
await Task.Delay(5500);
|
||||
if (count != real.Count) await Task.Delay(5500);
|
||||
}
|
||||
FunGameSimulation = false;
|
||||
}
|
||||
@ -435,7 +435,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
{
|
||||
real.Add(msgs[0]);
|
||||
}
|
||||
int remain = 7;
|
||||
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||
string merge = "";
|
||||
for (int i = 1; i < msgs.Count - 2; i++)
|
||||
{
|
||||
@ -465,7 +465,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
foreach (string msg in real)
|
||||
{
|
||||
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
|
||||
await Task.Delay(5500);
|
||||
if (count != real.Count) await Task.Delay(5500);
|
||||
}
|
||||
FunGameSimulation = false;
|
||||
}
|
||||
@ -1693,7 +1693,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
{
|
||||
if (msgs.Count < 20)
|
||||
{
|
||||
int remain = 7;
|
||||
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||
string merge = "";
|
||||
for (int i = 0; i < msgs.Count - 1; i++)
|
||||
{
|
||||
@ -1730,7 +1730,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
foreach (string msg in real)
|
||||
{
|
||||
await SendAsync(e, "完整决斗", msg.Trim(), msgSeq: count++);
|
||||
await Task.Delay(1500);
|
||||
if (count != real.Count) await Task.Delay(1500);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1750,7 +1750,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
List<string> real = [];
|
||||
if (msgs.Count > 2)
|
||||
{
|
||||
int remain = 7;
|
||||
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||
string merge = "";
|
||||
for (int i = 0; i < msgs.Count - 1; i++)
|
||||
{
|
||||
@ -1781,7 +1781,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
foreach (string msg in real)
|
||||
{
|
||||
await SendAsync(e, "决斗", msg.Trim(), msgSeq: count++);
|
||||
await Task.Delay(1500);
|
||||
if (count != real.Count) await Task.Delay(1500);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1803,7 +1803,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
{
|
||||
if (msgs.Count < 20)
|
||||
{
|
||||
int remain = 7;
|
||||
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||
string merge = "";
|
||||
for (int i = 0; i < msgs.Count - 1; i++)
|
||||
{
|
||||
@ -1840,7 +1840,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
foreach (string msg in real)
|
||||
{
|
||||
await SendAsync(e, "完整决斗", msg.Trim(), msgSeq: count++);
|
||||
await Task.Delay(1500);
|
||||
if (count != real.Count) await Task.Delay(1500);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1876,7 +1876,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
{
|
||||
if (msgs.Count < 20)
|
||||
{
|
||||
int remain = 7;
|
||||
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||
string merge = "";
|
||||
for (int i = 0; i < msgs.Count - 1; i++)
|
||||
{
|
||||
@ -1913,7 +1913,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
foreach (string msg in real)
|
||||
{
|
||||
await SendAsync(e, "BOSS", msg.Trim(), msgSeq: count++);
|
||||
await Task.Delay(1500);
|
||||
if (count != real.Count) await Task.Delay(1500);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1935,7 +1935,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
{
|
||||
if (msgs.Count < 20)
|
||||
{
|
||||
int remain = 7;
|
||||
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||
string merge = "";
|
||||
for (int i = 0; i < msgs.Count - 1; i++)
|
||||
{
|
||||
@ -1972,7 +1972,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
foreach (string msg in real)
|
||||
{
|
||||
await SendAsync(e, "BOSS", msg.Trim(), msgSeq: count++);
|
||||
await Task.Delay(1500);
|
||||
if (count != real.Count) await Task.Delay(1500);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2903,8 +2903,67 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail == "后勤部")
|
||||
{
|
||||
string msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_logistics");
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "商店", msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail == "武器商会")
|
||||
{
|
||||
string msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_weapons");
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "商店", msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail == "杂货铺")
|
||||
{
|
||||
string msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_yuki");
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "商店", msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail == "基金会")
|
||||
{
|
||||
string msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_welfare");
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "商店", msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail == "锻造商店")
|
||||
{
|
||||
string msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_forge");
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "商店", msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail == "赛马商店")
|
||||
{
|
||||
string msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_horseracing");
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "商店", msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail.StartsWith("商店"))
|
||||
{
|
||||
string detail = e.Detail.Replace("商店", "").Trim();
|
||||
@ -2928,6 +2987,9 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
case 5:
|
||||
msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_forge");
|
||||
break;
|
||||
case 6:
|
||||
msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_horseracing");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -3218,6 +3280,230 @@ namespace Oshima.FunGame.WebAPI.Services
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail == "创建赛马")
|
||||
{
|
||||
string groupId = "";
|
||||
if (e.IsGroup && e is GroupAtMessage groupAtMessage && groupAtMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = groupAtMessage.GroupOpenId;
|
||||
}
|
||||
else if (e.IsGroup && e is ThirdPartyMessage thirdPartyMessage && thirdPartyMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = thirdPartyMessage.GroupOpenId;
|
||||
}
|
||||
if (groupId != "")
|
||||
{
|
||||
string msg = Controller.CreateRoom(uid, "horseracing", "", groupId);
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "赛马", msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendAsync(e, "赛马", "请在群聊中进行多人游戏。");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail == "加入赛马")
|
||||
{
|
||||
string groupId = "";
|
||||
if (e.IsGroup && e is GroupAtMessage groupAtMessage && groupAtMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = groupAtMessage.GroupOpenId;
|
||||
}
|
||||
else if (e.IsGroup && e is ThirdPartyMessage thirdPartyMessage && thirdPartyMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = thirdPartyMessage.GroupOpenId;
|
||||
}
|
||||
if (groupId != "")
|
||||
{
|
||||
if (FunGameConstant.Rooms.Values.FirstOrDefault(r => r.GameMap == groupId) is Room room)
|
||||
{
|
||||
string msg = Controller.IntoRoom(uid, room.Roomid, "");
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "赛马", msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendAsync(e, "赛马", "本群还没有创建赛马房间,请使用【创建赛马】指令来创建一个房间。");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendAsync(e, "赛马", "请在群聊中进行多人游戏。");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail.StartsWith("创建房间"))
|
||||
{
|
||||
string groupId = "";
|
||||
if (e.IsGroup && e is GroupAtMessage groupAtMessage && groupAtMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = groupAtMessage.GroupOpenId;
|
||||
}
|
||||
else if (e.IsGroup && e is ThirdPartyMessage thirdPartyMessage && thirdPartyMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = thirdPartyMessage.GroupOpenId;
|
||||
}
|
||||
if (groupId != "")
|
||||
{
|
||||
string detail = e.Detail.Replace("创建房间", "").Trim();
|
||||
string[] strings = detail.Split(" ", StringSplitOptions.RemoveEmptyEntries);
|
||||
string roomType = "", password = "";
|
||||
if (strings.Length > 0) roomType = strings[0];
|
||||
if (strings.Length > 1)
|
||||
{
|
||||
int firstSpaceIndex = detail.IndexOf(' ');
|
||||
if (firstSpaceIndex != -1 && firstSpaceIndex + 1 < detail.Length)
|
||||
{
|
||||
password = detail[(firstSpaceIndex + 1)..].Trim();
|
||||
}
|
||||
}
|
||||
string msg = Controller.CreateRoom(uid, roomType, password, groupId);
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "房间", msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendAsync(e, "房间", "请在群聊中进行多人游戏。");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail.StartsWith("加入房间"))
|
||||
{
|
||||
string groupId = "";
|
||||
if (e.IsGroup && e is GroupAtMessage groupAtMessage && groupAtMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = groupAtMessage.GroupOpenId;
|
||||
}
|
||||
else if (e.IsGroup && e is ThirdPartyMessage thirdPartyMessage && thirdPartyMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = thirdPartyMessage.GroupOpenId;
|
||||
}
|
||||
if (groupId != "")
|
||||
{
|
||||
string detail = e.Detail.Replace("加入房间", "").Trim();
|
||||
string[] strings = detail.Split(" ", StringSplitOptions.RemoveEmptyEntries);
|
||||
string roomid = "", password = "";
|
||||
if (strings.Length > 0) roomid = strings[0];
|
||||
if (strings.Length > 1)
|
||||
{
|
||||
int firstSpaceIndex = detail.IndexOf(' ');
|
||||
if (firstSpaceIndex != -1 && firstSpaceIndex + 1 < detail.Length)
|
||||
{
|
||||
password = detail[(firstSpaceIndex + 1)..].Trim();
|
||||
}
|
||||
}
|
||||
string msg = Controller.IntoRoom(uid, roomid, password);
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "房间", msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendAsync(e, "房间", "请在群聊中进行多人游戏。");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail == "开始游戏")
|
||||
{
|
||||
string groupId = "";
|
||||
if (e.IsGroup && e is GroupAtMessage groupAtMessage && groupAtMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = groupAtMessage.GroupOpenId;
|
||||
}
|
||||
else if (e.IsGroup && e is ThirdPartyMessage thirdPartyMessage && thirdPartyMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = thirdPartyMessage.GroupOpenId;
|
||||
}
|
||||
if (groupId != "")
|
||||
{
|
||||
(Room room, List<string> msgs) = await Controller.RunGame(uid);
|
||||
List<string> real = [];
|
||||
if (msgs.Count > 1)
|
||||
{
|
||||
if (msgs.Count > 20)
|
||||
{
|
||||
msgs = [msgs[0], .. msgs[^20..]];
|
||||
}
|
||||
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||
string merge = "";
|
||||
for (int i = 0; i < msgs.Count - 1; i++)
|
||||
{
|
||||
remain--;
|
||||
merge += msgs[i] + "\r\n";
|
||||
if (remain == 0)
|
||||
{
|
||||
real.Add(merge);
|
||||
merge = "";
|
||||
if ((msgs.Count - i - 1) < 7)
|
||||
{
|
||||
remain = msgs.Count - i - 1;
|
||||
}
|
||||
else remain = 7;
|
||||
}
|
||||
}
|
||||
real.Add(msgs[^1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
real = msgs;
|
||||
}
|
||||
if (real.Count >= 3)
|
||||
{
|
||||
real = [real[0], .. real[^2..]];
|
||||
}
|
||||
int count = 1;
|
||||
foreach (string msg in real)
|
||||
{
|
||||
await SendAsync(e, "房间", msg.Trim(), msgSeq: count++);
|
||||
if (count <= real.Count) await Task.Delay(1500);
|
||||
}
|
||||
OnlineService.ReSetRoomState(room.Roomid);
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendAsync(e, "房间", "请在群聊中进行多人游戏。");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (e.Detail == "退出房间")
|
||||
{
|
||||
string groupId = "";
|
||||
if (e.IsGroup && e is GroupAtMessage groupAtMessage && groupAtMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = groupAtMessage.GroupOpenId;
|
||||
}
|
||||
else if (e.IsGroup && e is ThirdPartyMessage thirdPartyMessage && thirdPartyMessage.GroupOpenId != "")
|
||||
{
|
||||
groupId = thirdPartyMessage.GroupOpenId;
|
||||
}
|
||||
if (groupId != "")
|
||||
{
|
||||
string msg = Controller.QuitRoom(uid);
|
||||
if (msg.Trim() != "")
|
||||
{
|
||||
await SendAsync(e, "房间", msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendAsync(e, "房间", "请在群聊中进行多人游戏。");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (uid == GeneralSettings.Master && e.Detail.StartsWith("重载FunGame", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
string msg = Controller.Relaod(uid);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user