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,
|
创生之印 = 18012,
|
||||||
法则精粹 = 18013,
|
法则精粹 = 18013,
|
||||||
大师锻造券 = 18014,
|
大师锻造券 = 18014,
|
||||||
|
钻石 = 18998,
|
||||||
探索许可 = 18999
|
探索许可 = 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 Dictionary<long, LastStoreModel> UserLastVisitStore { get; } = [];
|
||||||
public static ConcurrentDictionary<string, SemaphoreSlim> UserSemaphoreSlims { get; } = [];
|
public static ConcurrentDictionary<string, SemaphoreSlim> UserSemaphoreSlims { get; } = [];
|
||||||
public static SemaphoreSlim MarketSemaphoreSlim { get; } = new(1, 1);
|
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[] 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 ItemType[] ItemCanNotDrawCard => [ItemType.Collectible, ItemType.QuestItem, ItemType.GiftBox, ItemType.Others];
|
||||||
public static char[] SplitChars => [',', ' ', ',', ';', ';'];
|
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)SpecialItemID.大师锻造券 => new 大师锻造券(),
|
||||||
|
(long)SpecialItemID.钻石 => new 钻石(),
|
||||||
(long)SpecialItemID.探索许可 => new 探索许可(),
|
(long)SpecialItemID.探索许可 => new 探索许可(),
|
||||||
(long)ConsumableID.小回复药 => new 小回复药(),
|
(long)ConsumableID.小回复药 => new 小回复药(),
|
||||||
(long)ConsumableID.中回复药 => new 中回复药(),
|
(long)ConsumableID.中回复药 => new 中回复药(),
|
||||||
|
|||||||
@ -36,6 +36,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
|||||||
{
|
{
|
||||||
template = CreateNewForgeStore();
|
template = CreateNewForgeStore();
|
||||||
}
|
}
|
||||||
|
else if (storeName == "dokyo_horseracing")
|
||||||
|
{
|
||||||
|
template = CreateNewHorseRacingStore();
|
||||||
|
}
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +113,15 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
|||||||
}
|
}
|
||||||
return $"现有锻造积分:{forgePoints:0.##}";
|
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 "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,6 +137,7 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
|||||||
{
|
{
|
||||||
EntityModuleConfig<Store> storeTemplate = new("stores", "dokyo");
|
EntityModuleConfig<Store> storeTemplate = new("stores", "dokyo");
|
||||||
storeTemplate.LoadConfig();
|
storeTemplate.LoadConfig();
|
||||||
|
|
||||||
Store? store = storeTemplate.Get("dokyo_forge");
|
Store? store = storeTemplate.Get("dokyo_forge");
|
||||||
if (store is null)
|
if (store is null)
|
||||||
{
|
{
|
||||||
@ -136,6 +150,20 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
|||||||
store.CopyGoodsToNextRefreshGoods(newStore.Goods);
|
store.CopyGoodsToNextRefreshGoods(newStore.Goods);
|
||||||
}
|
}
|
||||||
storeTemplate.Add("dokyo_forge", store);
|
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();
|
storeTemplate.SaveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +171,7 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
|||||||
{
|
{
|
||||||
Store store = new("锻造积分商店")
|
Store store = new("锻造积分商店")
|
||||||
{
|
{
|
||||||
|
GetNewerGoodsOnVisiting = true,
|
||||||
AutoRefresh = true,
|
AutoRefresh = true,
|
||||||
RefreshInterval = 3,
|
RefreshInterval = 3,
|
||||||
NextRefreshDate = DateTime.Today.AddHours(4),
|
NextRefreshDate = DateTime.Today.AddHours(4),
|
||||||
@ -161,5 +190,22 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
|||||||
}
|
}
|
||||||
return store;
|
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();
|
FunGameService.RefreshSavedCache();
|
||||||
Controller.WriteLine("读取 FunGame 存档缓存", LogLevel.Debug);
|
Controller.WriteLine("读取 FunGame 存档缓存", LogLevel.Debug);
|
||||||
|
OnlineService.RoomsAutoDisband();
|
||||||
|
Controller.WriteLine("清除空闲房间", LogLevel.Debug);
|
||||||
}, true);
|
}, true);
|
||||||
TaskScheduler.Shared.AddTask("刷新每日任务", new TimeSpan(4, 0, 0), () =>
|
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() {
|
public static Dictionary<string, string> ClubHelp { get; } = new() {
|
||||||
@ -146,7 +155,8 @@
|
|||||||
{"商店2", "查看武器商会商品"},
|
{"商店2", "查看武器商会商品"},
|
||||||
{"商店3", "查看杂货铺商品"},
|
{"商店3", "查看杂货铺商品"},
|
||||||
{"商店4", "查看慈善基金会商品"},
|
{"商店4", "查看慈善基金会商品"},
|
||||||
{"锻造商店", "查看锻造积分商店商品"},
|
{"锻造商店/商店5", "查看锻造积分商店商品"},
|
||||||
|
{"赛马商店/商店6", "查看锻造积分商店商品"},
|
||||||
{"商店查看 <商品序号>", "查看指定商品详情,访问任意商店后2分钟内可用"},
|
{"商店查看 <商品序号>", "查看指定商品详情,访问任意商店后2分钟内可用"},
|
||||||
{"商店购买 <商品序号>", "购买指定商品,访问任意商店后2分钟内可用"},
|
{"商店购买 <商品序号>", "购买指定商品,访问任意商店后2分钟内可用"},
|
||||||
{"商店出售 <物品序号>", "向商店出售具有回收价的指定物品"},
|
{"商店出售 <物品序号>", "向商店出售具有回收价的指定物品"},
|
||||||
|
|||||||
@ -624,6 +624,12 @@ namespace Oshima.FunGame.OshimaServers.Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查在线状态
|
||||||
|
if (FunGameConstant.UsersInRoom.ContainsKey(user.Id))
|
||||||
|
{
|
||||||
|
user.OnlineState = OnlineState.InRoom;
|
||||||
|
}
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2161,6 +2167,19 @@ namespace Oshima.FunGame.OshimaServers.Service
|
|||||||
return $"你的{needy}不足 {reduce} 呢,无法购买【{goods.Name}】!";
|
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
|
else
|
||||||
{
|
{
|
||||||
return $"不支持的货币类型:{needy},无法购买【{goods.Name}】!";
|
return $"不支持的货币类型:{needy},无法购买【{goods.Name}】!";
|
||||||
@ -2169,7 +2188,11 @@ namespace Oshima.FunGame.OshimaServers.Service
|
|||||||
|
|
||||||
foreach (Item item in goods.Items)
|
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;
|
int exploreTimes = FunGameConstant.MaxExploreTimes + count;
|
||||||
if (pc.TryGetValue("exploreTimes", out object? value) && int.TryParse(value.ToString(), out exploreTimes))
|
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()
|
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))
|
if (Directory.Exists(directoryPath))
|
||||||
{
|
{
|
||||||
string[] filePaths = Directory.GetFiles(directoryPath);
|
string[] filePaths = Directory.GetFiles(directoryPath);
|
||||||
@ -4471,6 +4532,7 @@ namespace Oshima.FunGame.OshimaServers.Service
|
|||||||
FunGameConstant.UserIdAndUsername[user.Id] = user;
|
FunGameConstant.UserIdAndUsername[user.Id] = user;
|
||||||
bool updateQuest = false;
|
bool updateQuest = false;
|
||||||
bool updateExplore = false;
|
bool updateExplore = false;
|
||||||
|
bool updateHorseRacing = false;
|
||||||
// 任务结算
|
// 任务结算
|
||||||
EntityModuleConfig<Quest> quests = new("quests", user.Id.ToString());
|
EntityModuleConfig<Quest> quests = new("quests", user.Id.ToString());
|
||||||
quests.LoadConfig();
|
quests.LoadConfig();
|
||||||
@ -4487,7 +4549,20 @@ namespace Oshima.FunGame.OshimaServers.Service
|
|||||||
pc2.SaveConfig();
|
pc2.SaveConfig();
|
||||||
updateExplore = true;
|
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);
|
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);
|
pc2.Add("exploreTimes", exploreTimes);
|
||||||
msg = $"已为 [ {user2} ] 生成 {itemCount} 个探索许可";
|
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("魔法卡礼包"))
|
else if (itemName.Contains("魔法卡礼包"))
|
||||||
{
|
{
|
||||||
foreach (string type in ItemSet.QualityTypeNameArray)
|
foreach (string type in ItemSet.QualityTypeNameArray)
|
||||||
@ -2926,7 +2952,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
|||||||
FunGameService.SetUserConfigAndReleaseSemaphoreSlim(userid, pc, user);
|
FunGameService.SetUserConfigAndReleaseSemaphoreSlim(userid, pc, user);
|
||||||
|
|
||||||
string msg = "";
|
string msg = "";
|
||||||
if (user.IsAdmin || userid > 0)
|
if (user.IsAdmin)
|
||||||
{
|
{
|
||||||
PluginConfig pc2 = FunGameService.GetUserConfig(targetid, out _);
|
PluginConfig pc2 = FunGameService.GetUserConfig(targetid, out _);
|
||||||
if (pc2.Count > 0)
|
if (pc2.Count > 0)
|
||||||
@ -6709,7 +6735,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
|||||||
{
|
{
|
||||||
User user = FunGameService.GetUser(pc);
|
User user = FunGameService.GetUser(pc);
|
||||||
|
|
||||||
if (user.IsAdmin || user.IsOperator)
|
if (user.IsAdmin)
|
||||||
{
|
{
|
||||||
PluginConfig renameExamine = new("examines", "rename");
|
PluginConfig renameExamine = new("examines", "rename");
|
||||||
renameExamine.LoadConfig();
|
renameExamine.LoadConfig();
|
||||||
@ -6793,7 +6819,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
|||||||
FunGameService.ReleaseUserSemaphoreSlim(userid);
|
FunGameService.ReleaseUserSemaphoreSlim(userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.IsAdmin || user.IsOperator)
|
if (user.IsAdmin)
|
||||||
{
|
{
|
||||||
PluginConfig renameExamine = new("examines", "rename");
|
PluginConfig renameExamine = new("examines", "rename");
|
||||||
renameExamine.LoadConfig();
|
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")]
|
[HttpPost("template")]
|
||||||
public string Template([FromQuery] long uid = -1)
|
public string Template([FromQuery] long uid = -1)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -94,6 +94,9 @@ namespace Oshima.FunGame.WebAPI.Models
|
|||||||
[JsonPropertyName("isgroup")]
|
[JsonPropertyName("isgroup")]
|
||||||
public bool IsGroup { get; set; } = false;
|
public bool IsGroup { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonPropertyName("group_openid")]
|
||||||
|
public string GroupOpenId { get; set; } = "";
|
||||||
|
|
||||||
[JsonPropertyName("detail")]
|
[JsonPropertyName("detail")]
|
||||||
public string Detail { get; set; } = "";
|
public string Detail { get; set; } = "";
|
||||||
|
|
||||||
|
|||||||
@ -47,10 +47,10 @@ namespace Oshima.FunGame.WebAPI
|
|||||||
{
|
{
|
||||||
// 获取 RainBOTService 实例
|
// 获取 RainBOTService 实例
|
||||||
RainBOTService bot = serviceProvider.GetRequiredService<RainBOTService>();
|
RainBOTService bot = serviceProvider.GetRequiredService<RainBOTService>();
|
||||||
Controller.WriteLine("成功获取 RainBOTService 实例!");
|
|
||||||
ThirdPartyMessage message = new()
|
ThirdPartyMessage message = new()
|
||||||
{
|
{
|
||||||
IsGroup = false,
|
IsGroup = true,
|
||||||
|
GroupOpenId = "1",
|
||||||
AuthorOpenId = "1",
|
AuthorOpenId = "1",
|
||||||
OpenId = "1",
|
OpenId = "1",
|
||||||
Detail = input,
|
Detail = input,
|
||||||
|
|||||||
@ -320,7 +320,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
FunGameSimulation = true;
|
FunGameSimulation = true;
|
||||||
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: 0);
|
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: 0);
|
||||||
List<string> real = [];
|
List<string> real = [];
|
||||||
int remain = 7;
|
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||||
string merge = "";
|
string merge = "";
|
||||||
for (int i = 0; i < msgs.Count - 2; i++)
|
for (int i = 0; i < msgs.Count - 2; i++)
|
||||||
{
|
{
|
||||||
@ -350,7 +350,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
foreach (string msg in real)
|
foreach (string msg in real)
|
||||||
{
|
{
|
||||||
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
|
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
|
||||||
await Task.Delay(5500);
|
if (count != real.Count) await Task.Delay(5500);
|
||||||
}
|
}
|
||||||
FunGameSimulation = false;
|
FunGameSimulation = false;
|
||||||
}
|
}
|
||||||
@ -375,7 +375,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
FunGameSimulation = true;
|
FunGameSimulation = true;
|
||||||
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: maxRespawnTimesMix);
|
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: maxRespawnTimesMix);
|
||||||
List<string> real = [];
|
List<string> real = [];
|
||||||
int remain = 7;
|
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||||
string merge = "";
|
string merge = "";
|
||||||
for (int i = 0; i < msgs.Count - 2; i++)
|
for (int i = 0; i < msgs.Count - 2; i++)
|
||||||
{
|
{
|
||||||
@ -405,7 +405,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
foreach (string msg in real)
|
foreach (string msg in real)
|
||||||
{
|
{
|
||||||
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
|
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
|
||||||
await Task.Delay(5500);
|
if (count != real.Count) await Task.Delay(5500);
|
||||||
}
|
}
|
||||||
FunGameSimulation = false;
|
FunGameSimulation = false;
|
||||||
}
|
}
|
||||||
@ -435,7 +435,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
{
|
{
|
||||||
real.Add(msgs[0]);
|
real.Add(msgs[0]);
|
||||||
}
|
}
|
||||||
int remain = 7;
|
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||||
string merge = "";
|
string merge = "";
|
||||||
for (int i = 1; i < msgs.Count - 2; i++)
|
for (int i = 1; i < msgs.Count - 2; i++)
|
||||||
{
|
{
|
||||||
@ -465,7 +465,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
foreach (string msg in real)
|
foreach (string msg in real)
|
||||||
{
|
{
|
||||||
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
|
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
|
||||||
await Task.Delay(5500);
|
if (count != real.Count) await Task.Delay(5500);
|
||||||
}
|
}
|
||||||
FunGameSimulation = false;
|
FunGameSimulation = false;
|
||||||
}
|
}
|
||||||
@ -1693,7 +1693,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
{
|
{
|
||||||
if (msgs.Count < 20)
|
if (msgs.Count < 20)
|
||||||
{
|
{
|
||||||
int remain = 7;
|
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||||
string merge = "";
|
string merge = "";
|
||||||
for (int i = 0; i < msgs.Count - 1; i++)
|
for (int i = 0; i < msgs.Count - 1; i++)
|
||||||
{
|
{
|
||||||
@ -1730,7 +1730,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
foreach (string msg in real)
|
foreach (string msg in real)
|
||||||
{
|
{
|
||||||
await SendAsync(e, "完整决斗", msg.Trim(), msgSeq: count++);
|
await SendAsync(e, "完整决斗", msg.Trim(), msgSeq: count++);
|
||||||
await Task.Delay(1500);
|
if (count != real.Count) await Task.Delay(1500);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1750,7 +1750,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
List<string> real = [];
|
List<string> real = [];
|
||||||
if (msgs.Count > 2)
|
if (msgs.Count > 2)
|
||||||
{
|
{
|
||||||
int remain = 7;
|
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||||
string merge = "";
|
string merge = "";
|
||||||
for (int i = 0; i < msgs.Count - 1; i++)
|
for (int i = 0; i < msgs.Count - 1; i++)
|
||||||
{
|
{
|
||||||
@ -1781,7 +1781,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
foreach (string msg in real)
|
foreach (string msg in real)
|
||||||
{
|
{
|
||||||
await SendAsync(e, "决斗", msg.Trim(), msgSeq: count++);
|
await SendAsync(e, "决斗", msg.Trim(), msgSeq: count++);
|
||||||
await Task.Delay(1500);
|
if (count != real.Count) await Task.Delay(1500);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1803,7 +1803,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
{
|
{
|
||||||
if (msgs.Count < 20)
|
if (msgs.Count < 20)
|
||||||
{
|
{
|
||||||
int remain = 7;
|
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||||
string merge = "";
|
string merge = "";
|
||||||
for (int i = 0; i < msgs.Count - 1; i++)
|
for (int i = 0; i < msgs.Count - 1; i++)
|
||||||
{
|
{
|
||||||
@ -1840,7 +1840,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
foreach (string msg in real)
|
foreach (string msg in real)
|
||||||
{
|
{
|
||||||
await SendAsync(e, "完整决斗", msg.Trim(), msgSeq: count++);
|
await SendAsync(e, "完整决斗", msg.Trim(), msgSeq: count++);
|
||||||
await Task.Delay(1500);
|
if (count != real.Count) await Task.Delay(1500);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1876,7 +1876,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
{
|
{
|
||||||
if (msgs.Count < 20)
|
if (msgs.Count < 20)
|
||||||
{
|
{
|
||||||
int remain = 7;
|
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||||
string merge = "";
|
string merge = "";
|
||||||
for (int i = 0; i < msgs.Count - 1; i++)
|
for (int i = 0; i < msgs.Count - 1; i++)
|
||||||
{
|
{
|
||||||
@ -1913,7 +1913,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
foreach (string msg in real)
|
foreach (string msg in real)
|
||||||
{
|
{
|
||||||
await SendAsync(e, "BOSS", msg.Trim(), msgSeq: count++);
|
await SendAsync(e, "BOSS", msg.Trim(), msgSeq: count++);
|
||||||
await Task.Delay(1500);
|
if (count != real.Count) await Task.Delay(1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1935,7 +1935,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
{
|
{
|
||||||
if (msgs.Count < 20)
|
if (msgs.Count < 20)
|
||||||
{
|
{
|
||||||
int remain = 7;
|
int remain = msgs.Count > 7 ? 7 : msgs.Count - 1;
|
||||||
string merge = "";
|
string merge = "";
|
||||||
for (int i = 0; i < msgs.Count - 1; i++)
|
for (int i = 0; i < msgs.Count - 1; i++)
|
||||||
{
|
{
|
||||||
@ -1972,7 +1972,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
foreach (string msg in real)
|
foreach (string msg in real)
|
||||||
{
|
{
|
||||||
await SendAsync(e, "BOSS", msg.Trim(), msgSeq: count++);
|
await SendAsync(e, "BOSS", msg.Trim(), msgSeq: count++);
|
||||||
await Task.Delay(1500);
|
if (count != real.Count) await Task.Delay(1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2903,8 +2903,67 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
}
|
}
|
||||||
return result;
|
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("商店"))
|
if (e.Detail.StartsWith("商店"))
|
||||||
{
|
{
|
||||||
string detail = e.Detail.Replace("商店", "").Trim();
|
string detail = e.Detail.Replace("商店", "").Trim();
|
||||||
@ -2928,6 +2987,9 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
case 5:
|
case 5:
|
||||||
msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_forge");
|
msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_forge");
|
||||||
break;
|
break;
|
||||||
|
case 6:
|
||||||
|
msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_horseracing");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3218,6 +3280,230 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
return result;
|
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))
|
if (uid == GeneralSettings.Master && e.Detail.StartsWith("重载FunGame", StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
string msg = Controller.Relaod(uid);
|
string msg = Controller.Relaod(uid);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user