稳定性改进

This commit is contained in:
milimoe 2025-06-30 22:46:30 +08:00
parent 2ed15a6419
commit 5447c6fe97
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
5 changed files with 328 additions and 160 deletions

View File

@ -13,7 +13,7 @@ namespace Oshima.FunGame.OshimaServers.Service
public const int ItemsPerPage1 = 6;
public const int ItemsPerPage2 = 10;
public const int ExploreTime = 2;
public const int MaxExploreTimes = 12;
public const int MaxExploreTimes = 60;
public static List<Character> Characters { get; } = [];
public static List<Skill> Skills { get; } = [];
public static List<Skill> PassiveSkills { get; } = [];
@ -300,38 +300,56 @@ namespace Oshima.FunGame.OshimaServers.Service
new ()
];
public static Dictionary<ExploreResult, double> ExploreResultProbabilities { get; } = new()
{
{ ExploreResult.General, 40 },
{ ExploreResult.Nothing, 20 },
{ ExploreResult.Fight, 20 },
{ ExploreResult.Earned, 20 },
{ ExploreResult.Event, 0 }
};
/// <summary>
/// 参数说明:{0} 奖励内容字符串,{1} 敌人名称,{2} NPC名称{3} 物品名称1{4} 地点名称1{5} 物品名称1{6} 地点名称2
/// </summary>
public static Dictionary<string, ExploreResult> ExploreString { get; } = new()
public static Dictionary<ExploreResult, List<string>> ExploreString { get; } = new()
{
// General - 带奖励的普通结果
{ "当{3}的光芒洒满{4}时,{6}显露出了被封印的{0},你快马加鞭冲了上去夺走!", ExploreResult.General },
{ "{2}的低语在风中消散,但留在你手中的是闪耀的{0}", ExploreResult.General },
{ "恭喜你!成功在荒野中迷路!奖励…等等,好像是:{0}?至少不是空手而归…", ExploreResult.General },
{ "你凝视着远方,远方也凝视着你…然后,你获得了:{0}!这大概就是命运吧。", ExploreResult.General },
{ "探索结果:空气,阳光,还有…奖励:{0}!看来今天运气还不错?", ExploreResult.General },
// Nothing - 无收获
{ "风沙抹去了所有痕迹,只有{3}见证过你的到来。(什么也没有获得)", ExploreResult.Nothing },
{ "{4}地牢里的封印纹丝未动,仿佛在嘲笑着你的徒劳……(什么也没有获得)", ExploreResult.Nothing },
{ "在你的注视下,{4}的宝藏已被{2}掠夺一空。(什么也没有获得)", ExploreResult.Nothing },
{ "你对着空地发呆了半天,只剩冰冷的{4}和你的失望。(什么也没有获得)", ExploreResult.Nothing },
{ "在空荡的回响中传来讥笑,原来{4}的秘宝不过是个传说。(什么也没有获得)", ExploreResult.Nothing },
// Fight - 遭遇敌人
{ "{4}的地面突然裂开,{1}扑向了你!迎接战斗吧!", ExploreResult.Fight },
{ "当你触碰{3}时,{1}的咆哮震撼着{4}", ExploreResult.Fight },
{ "原来这里真的有危险……是{1}守卫着{4},不得不战了!", ExploreResult.Fight },
{ "在探索{4}的某处时,身旁的墙突然破裂,{1}从阴影中降临!", ExploreResult.Fight },
{ "你惊动了{1}{4}瞬间化作战场!", ExploreResult.Fight },
// Earned - 珍贵收获
{ "当{3}发出诡异的光芒照亮{4}时,藏在其中的{0}突然落入你手中!", ExploreResult.Earned },
{ "祝福应验!{4}深处的{0}为你所有!", ExploreResult.Earned },
{ "解开{4}地牢中的谜题后,{0}终于显现!", ExploreResult.Earned },
{ "屏障消散,至宝{0}光芒万丈,自觉地飞进了你的口袋!", ExploreResult.Earned },
{ "在偶遇{1}和{2}的遭遇战时,你渔翁得利抢到了:{0}", ExploreResult.Earned }
{
ExploreResult.General, [
"当{3}的光芒洒满{4}时,{6}显露出了被封印的{0},你快马加鞭冲了上去夺走!",
"{2}的低语在风中消散,但留在你手中的是闪耀的{0}",
"恭喜你!成功在荒野中迷路!奖励…等等,好像是:{0}?至少不是空手而归…",
"你凝视着远方,远方也凝视着你…然后,你获得了:{0}!这大概就是命运吧。",
"探索结果:空气,阳光,还有…奖励:{0}!看来今天运气还不错?"
]
},
{
ExploreResult.Nothing, [
"风沙抹去了所有痕迹,只有{3}见证过你的到来。(什么也没有获得)",
"{4}地牢里的封印纹丝未动,仿佛在嘲笑着你的徒劳……(什么也没有获得)",
"在你的注视下,{4}的宝藏已被{2}掠夺一空。(什么也没有获得)",
"你对着空地发呆了半天,只剩冰冷的{4}和你的失望。(什么也没有获得)",
"在空荡的回响中传来讥笑,原来{4}的秘宝不过是个传说。(什么也没有获得)"
]
},
{
ExploreResult.Fight, [
"{4}的地面突然裂开,{1}扑向了你!迎接战斗吧!",
"当你触碰{3}时,{1}的咆哮震撼着{4}",
"原来这里真的有危险……是{1}守卫着{4},不得不战了!",
"在探索{4}的某处时,身旁的墙突然破裂,{1}从阴影中降临!",
"你惊动了{1}{4}瞬间化作战场!"
]
},
{
ExploreResult.Earned, [
"当{3}发出诡异的光芒照亮{4}时,藏在其中的{0}突然落入你手中!",
"祝福应验!{4}深处的{0}为你所有!",
"解开{4}地牢中的谜题后,{0}终于显现!",
"屏障消散,至宝{0}光芒万丈,自觉地飞进了你的口袋!",
"在偶遇{1}和{2}的遭遇战时,你渔翁得利抢到了:{0}"
]
}
};
public static Dictionary<QualityType, double> DrawCardProbabilities { get; } = new()

View File

@ -16,9 +16,13 @@ namespace Oshima.FunGame.OshimaServers.Service
{
public class FunGameService
{
public static Dictionary<long, List<string>> UserExploreCharacterCache { get; } = [];
public static Dictionary<long, List<string>> UserExploreItemCache { get; } = [];
public static Dictionary<long, List<string>> UserExploreEventCache { get; } = [];
public static HashSet<Activity> Activities { get; } = [];
public static List<string> ActivitiesCharacterCache { get; } = [];
public static List<string> ActivitiesItemCache { get; } = [];
public static List<string> ActivitiesEventCache { get; } = [];
public static Dictionary<long, HashSet<string>> UserNotice { get; } = [];
public static Dictionary<int, Character> Bosses { get; } = [];
public static ServerPluginLoader? ServerPluginLoader { get; set; } = null;
@ -1754,12 +1758,12 @@ namespace Oshima.FunGame.OshimaServers.Service
{
if (quest.NeedyExploreItemName == item)
{
result = true;
quest.Progress += items.Count();
if (quest.Progress >= quest.MaxProgress)
{
quest.Progress = quest.MaxProgress;
quest.Status = QuestState.Completed;
result = true;
}
}
}
@ -1986,43 +1990,94 @@ namespace Oshima.FunGame.OshimaServers.Service
{
return "当前没有任何活动,敬请期待。";
}
Activities.Clear();
foreach (Activity activity in activities.Values)
lock (Activities)
{
Activities.Add(activity);
}
bool update = false;
if (ActivitiesItemCache.Count > 0)
{
List<string> willRemove = [];
IEnumerable<Activity> activityList = Activities.Where(a => a.Status == ActivityState.InProgress);
foreach (string item in ActivitiesItemCache.Distinct())
Activities.Clear();
foreach (Activity activity in activities.Values)
{
IEnumerable<string> items = ActivitiesItemCache.Where(str => str == item);
foreach (Quest quest in activityList.SelectMany(a => a.Quests))
Activities.Add(activity);
}
bool update = false;
if (ActivitiesCharacterCache.Count > 0)
{
List<string> willRemove = [];
IEnumerable<Activity> activityList = Activities.Where(a => a.Status == ActivityState.InProgress);
foreach (string item in ActivitiesCharacterCache.Distinct())
{
if (quest.NeedyExploreItemName == item)
IEnumerable<string> items = ActivitiesCharacterCache.Where(str => str == item);
foreach (Quest quest in activityList.SelectMany(a => a.Quests).Where(q => q.Status == QuestState.InProgress))
{
update = true;
quest.Progress += items.Count();
if (quest.Progress >= quest.MaxProgress)
if (quest.NeedyExploreCharacterName == item)
{
quest.Progress = quest.MaxProgress;
quest.Status = QuestState.Completed;
update = true;
quest.Progress += items.Count();
if (quest.Progress >= quest.MaxProgress)
{
quest.Progress = quest.MaxProgress;
quest.Status = QuestState.Completed;
}
}
}
willRemove.Add(item);
}
willRemove.Add(item);
ActivitiesCharacterCache.RemoveAll(willRemove.Contains);
}
ActivitiesItemCache.RemoveAll(willRemove.Contains);
}
if (update)
{
foreach (Activity activity in Activities)
if (ActivitiesItemCache.Count > 0)
{
activities.Add(activity.Id.ToString(), activity);
List<string> willRemove = [];
IEnumerable<Activity> activityList = Activities.Where(a => a.Status == ActivityState.InProgress);
foreach (string item in ActivitiesItemCache.Distinct())
{
IEnumerable<string> items = ActivitiesItemCache.Where(str => str == item);
foreach (Quest quest in activityList.SelectMany(a => a.Quests).Where(q => q.Status == QuestState.InProgress))
{
if (quest.NeedyExploreItemName == item)
{
update = true;
quest.Progress += items.Count();
if (quest.Progress >= quest.MaxProgress)
{
quest.Progress = quest.MaxProgress;
quest.Status = QuestState.Completed;
}
}
}
willRemove.Add(item);
}
ActivitiesItemCache.RemoveAll(willRemove.Contains);
}
if (ActivitiesEventCache.Count > 0)
{
List<string> willRemove = [];
IEnumerable<Activity> activityList = Activities.Where(a => a.Status == ActivityState.InProgress);
foreach (string item in ActivitiesEventCache.Distinct())
{
IEnumerable<string> items = ActivitiesEventCache.Where(str => str == item);
foreach (Quest quest in activityList.SelectMany(a => a.Quests).Where(q => q.Status == QuestState.InProgress))
{
if (quest.NeedyExploreEventName == item)
{
update = true;
quest.Progress += items.Count();
if (quest.Progress >= quest.MaxProgress)
{
quest.Progress = quest.MaxProgress;
quest.Status = QuestState.Completed;
}
}
}
willRemove.Add(item);
}
ActivitiesEventCache.RemoveAll(willRemove.Contains);
}
if (update)
{
foreach (Activity activity in Activities)
{
activities.Add(activity.Id.ToString(), activity);
}
activities.SaveConfig();
}
activities.SaveConfig();
}
StringBuilder builder = new();
builder.AppendLine("★☆★ 活动中心 ★☆★");
@ -2042,7 +2097,7 @@ namespace Oshima.FunGame.OshimaServers.Service
return builder.ToString().Trim();
}
public static string GetEvents(ActivityState status = ActivityState.InProgress)
{
EntityModuleConfig<Activity> activities = new("activities", "activities");
@ -2093,9 +2148,9 @@ namespace Oshima.FunGame.OshimaServers.Service
Dictionary<Character, int> characters = inventory
.Select((character, index) => new { character, index })
.ToDictionary(x => x.character, x => x.index + 1);
return $"{(squad.Length > 0 ? string.Join(separator, squad.Select(c => $"#{characters[c]}. {c}")) : "")}";
return $"{(squad.Length > 0 ? string.Join(separator, squad.Select(c => $"#{characters[c]}. {c.ToStringWithLevelWithOutUser()}")) : "")}";
}
public static string GetCharacterGroupInfoByInventorySequence(IEnumerable<Character> inventory, IEnumerable<long> characterIds, string separator = "\r\n")
{
Dictionary<Character, int> characters = [];
@ -2107,7 +2162,7 @@ namespace Oshima.FunGame.OshimaServers.Service
characters[loop[i - 1]] = i;
}
}
return $"{(characters.Count > 0 ? string.Join(separator, characters.Keys.Select(c => $"#{characters[c]}. {c}")) : "")}";
return $"{(characters.Count > 0 ? string.Join(separator, characters.Keys.Select(c => $"#{characters[c]}. {c.ToStringWithLevelWithOutUser()}")) : "")}";
}
public static async Task<ExploreModel> GenerateExploreModel(OshimaRegion region, long[] characterIds, User user)
@ -2119,13 +2174,61 @@ namespace Oshima.FunGame.OshimaServers.Service
CharacterIds = characterIds,
StartTime = DateTime.Now
};
int diff = region.Difficulty switch
{
RarityType.OneStar => 1,
RarityType.TwoStar => 2,
RarityType.ThreeStar => 3,
RarityType.FourStar => 4,
_ => 5
};
// 直接保存探索奖励,但是要等到探索结束后发放
int random = Random.Shared.Next(FunGameConstant.ExploreString.Count);
string exploreString = FunGameConstant.ExploreString.Keys.ToArray()[random];
double randomDouble = Random.Shared.NextDouble();
Dictionary<ExploreResult, double> probabilities = new(FunGameConstant.ExploreResultProbabilities);
switch (diff)
{
case 2:
probabilities[ExploreResult.General] -= 0.05;
probabilities[ExploreResult.Earned] -= 0.05;
probabilities[ExploreResult.Fight] += 0.1;
break;
case 3:
probabilities[ExploreResult.General] -= 0.1;
probabilities[ExploreResult.Earned] -= 0.05;
probabilities[ExploreResult.Nothing] -= 0.05;
probabilities[ExploreResult.Fight] += 0.2;
break;
case 4:
probabilities[ExploreResult.General] -= 0.2;
probabilities[ExploreResult.Earned] -= 0.1;
probabilities[ExploreResult.Nothing] -= 0.05;
probabilities[ExploreResult.Fight] += 0.35;
break;
case 5:
probabilities[ExploreResult.General] -= 0.3;
probabilities[ExploreResult.Earned] -= 0.15;
probabilities[ExploreResult.Nothing] -= 0.05;
probabilities[ExploreResult.Fight] += 0.5;
break;
default:
break;
}
double cumulative = 0;
model.Result = ExploreResult.Nothing;
foreach (ExploreResult key in probabilities.Keys)
{
cumulative += probabilities[key];
if (randomDouble <= cumulative)
{
model.Result = key;
break;
}
}
string exploreString = FunGameConstant.ExploreString[model.Result].OrderBy(o => Random.Shared.Next()).First();
// 出现的NPC
random = Random.Shared.Next(region.NPCs.Count + 1);
int random = Random.Shared.Next(region.NPCs.Count + 1);
string npc = random == region.NPCs.Count ? GenerateRandomChineseUserName() : region.NPCs[random];
// 探索的子区域
@ -2142,14 +2245,6 @@ namespace Oshima.FunGame.OshimaServers.Service
string item2 = items[random].Name;
// 筛选敌人
int diff = region.Difficulty switch
{
RarityType.OneStar => 1,
RarityType.TwoStar => 2,
RarityType.ThreeStar => 3,
RarityType.FourStar => 4,
_ => 5
};
List<Character> enemys = [];
Character enemy;
if (region.Characters.Count > 0 && region.Units.Count > 0)
@ -2197,7 +2292,6 @@ namespace Oshima.FunGame.OshimaServers.Service
// 生成奖励
string award = "";
model.Result = FunGameConstant.ExploreString[exploreString];
switch (model.Result)
{
case ExploreResult.General:
@ -2207,7 +2301,7 @@ namespace Oshima.FunGame.OshimaServers.Service
int credits = 0;
for (int i = 0; i < characterCount; i++)
{
credits += Random.Shared.Next(500, 1000) * diff;
credits += Random.Shared.Next(250, 400) * diff;
}
model.CreditsAward = credits;
award = $" {credits} {General.GameplayEquilibriumConstant.InGameCurrency}";
@ -2237,10 +2331,10 @@ namespace Oshima.FunGame.OshimaServers.Service
int exp = 0;
for (int i = 0; i < characterCount; i++)
{
exp += Random.Shared.Next(300, 700) * diff;
exp += Random.Shared.Next(100, 300) * diff;
}
model.Awards["exp"] = exp;
award += $",并额外获得了 {exp} 点经验值(探索队员们平分)";
exploreString += $"额外获得了:{exp} 点经验值(探索队员们平分)!";
break;
case ExploreResult.Fight:
// 小队信息
@ -2287,19 +2381,19 @@ namespace Oshima.FunGame.OshimaServers.Service
int credits = 0;
for (int i = 0; i < characterCount; i++)
{
credits += Random.Shared.Next(1000, 1500) * diff;
credits += Random.Shared.Next(400, 650) * diff;
}
model.CreditsAward = credits;
exp = 0;
for (int i = 0; i < characterCount; i++)
{
exp += Random.Shared.Next(600, 1000) * diff;
exp += Random.Shared.Next(250, 520) * diff;
}
model.Awards["exp"] = exp;
int materials = 0;
for (int i = 0; i < characterCount; i++)
{
materials += Random.Shared.Next(4, 7) * diff;
materials += Random.Shared.Next(3, 7) * diff;
}
model.MaterialsAward = materials;
Item item = FunGameConstant.ExploreItems[region][Random.Shared.Next(FunGameConstant.ExploreItems[region].Count)];
@ -2319,7 +2413,7 @@ namespace Oshima.FunGame.OshimaServers.Service
string itemquality = ItemSet.GetQualityTypeName(itemDrop.QualityType);
string itemtype = ItemSet.GetItemTypeName(itemDrop.ItemType) + (itemDrop.ItemType == ItemType.Weapon && itemDrop.WeaponType != WeaponType.None ? "-" + ItemSet.GetWeaponTypeName(itemDrop.WeaponType) : "");
if (itemtype != "") itemtype = $"|{itemtype}";
award += $"!额外获得了:[{itemquality + itemtype}] {itemDrop.Name}";
award += $"!额外获得了:[{itemquality + itemtype}]{itemDrop.Name}";
}
}
exploreString = $"{exploreString}\r\n{string.Join("\r\n", msgs)}\r\n探索小队战胜了{enemy.Name}!获得了:{award}";
@ -2347,7 +2441,7 @@ namespace Oshima.FunGame.OshimaServers.Service
string itemquality = ItemSet.GetQualityTypeName(itemEarned.QualityType);
string itemtype = ItemSet.GetItemTypeName(itemEarned.ItemType) + (itemEarned.ItemType == ItemType.Weapon && itemEarned.WeaponType != WeaponType.None ? "-" + ItemSet.GetWeaponTypeName(itemEarned.WeaponType) : "");
if (itemtype != "") itemtype = $"|{itemtype}";
award += $"[{itemquality + itemtype}] {itemEarned.Name}";
award += $"[{itemquality + itemtype}]{itemEarned.Name}";
}
break;
case ExploreResult.Event:
@ -2432,7 +2526,7 @@ namespace Oshima.FunGame.OshimaServers.Service
List<Guid> remove = [];
foreach (ExploreModel model in list)
{
if (model.StartTime.HasValue && (DateTime.Now - model.StartTime.Value).TotalMinutes > FunGameConstant.ExploreTime + 5)
if (model.StartTime.HasValue && (DateTime.Now - model.StartTime.Value).TotalMinutes > FunGameConstant.ExploreTime + 2)
{
if (SettleExplore(model.Guid, list, user, out string msg))
{

View File

@ -2525,6 +2525,19 @@ namespace Oshima.FunGame.WebAPI.Controllers
user2.Inventory.Materials += itemCount;
msg = $"已为 [ {user2} ] 生成 {itemCount} {General.GameplayEquilibriumConstant.InGameMaterial}";
}
else if (itemName == "探索许可")
{
if (pc.TryGetValue("exploreTimes", out object? value) && int.TryParse(value.ToString(), out int exploreTimes))
{
exploreTimes += itemCount;
}
else
{
exploreTimes = FunGameConstant.MaxExploreTimes + itemCount;
}
pc.Add("exploreTimes", exploreTimes);
msg = $"已为 [ {user2} ] 生成 {itemCount} 个探索许可";
}
else if (itemName.Contains("魔法卡礼包"))
{
foreach (string type in ItemSet.QualityTypeNameArray)
@ -5267,22 +5280,41 @@ namespace Oshima.FunGame.WebAPI.Controllers
msg = $"没有找到与输入序号相对应的角色:{string.Join("", invalid)}。";
}
// 检查探索次数
if (pc.TryGetValue("exploreTimes", out object? value) && int.TryParse(value.ToString(), out int exploreTimes))
// 检查探索许可
int exploreTimes = 0;
int reduce = 1;
if (regionid > 0 && regionid <= FunGameConstant.Regions.Count && FunGameConstant.Regions.FirstOrDefault(r => r.Id == regionid) is OshimaRegion region)
{
if (exploreTimes <= 0)
int diff = region.Difficulty switch
{
exploreTimes = 0;
msg = $"今日的探索次数已用完,无法再继续探索。";
RarityType.OneStar => 1,
RarityType.TwoStar => 2,
RarityType.ThreeStar => 3,
RarityType.FourStar => 4,
_ => 5
};
reduce = characterCount * diff;
if (pc.TryGetValue("exploreTimes", out object? value) && int.TryParse(value.ToString(), out exploreTimes))
{
if (exploreTimes <= 0)
{
exploreTimes = 0;
msg = $"今日的探索许可已用完,无法再继续探索。";
}
else if (reduce > exploreTimes)
{
msg = $"本次探索需要消耗 {reduce} 个探索许可,超过了你的剩余探索许可数量({exploreTimes} 个),请减少选择的角色数量或更换探索地区。" +
$"\r\n需要注意探索难度星级一比一兑换探索许可并且参与探索的角色都需要消耗相同数量的探索许可。";
}
}
else if (characterCount > exploreTimes)
else
{
msg = $"你选择的角色数量超过了剩余的探索次数({exploreTimes} 次),请减少选择的角色数量。需要注意:探索角色越多,奖励越多,但是会扣除相应的探索次数。";
exploreTimes = FunGameConstant.MaxExploreTimes;
}
}
else
{
exploreTimes = FunGameConstant.MaxExploreTimes;
return ($"没有找到与这个序号相对应的地区!", exploreId);
}
// 检查角色是否正在探索
@ -5294,14 +5326,14 @@ namespace Oshima.FunGame.WebAPI.Controllers
foreach (ExploreModel model in list)
{
// 可能要结算先前的超时探索
if (model.StartTime.HasValue && (DateTime.Now - model.StartTime.Value).TotalMinutes > FunGameConstant.ExploreTime + 5)
if (model.StartTime.HasValue && (DateTime.Now - model.StartTime.Value).TotalMinutes > FunGameConstant.ExploreTime + 2)
{
if (FunGameService.SettleExplore(model.Guid, list, user, out string notice))
{
if (notice != "")
{
if (msg2 != "") msg2 += "\r\n";
msg2 += $"你上次未完成的探索已被自动结算{notice}";
msg2 += $"你上次未完成的探索已被自动结算{notice}";
}
remove.Add(model.Guid);
}
@ -5328,26 +5360,16 @@ namespace Oshima.FunGame.WebAPI.Controllers
if (msg == "")
{
if (regionid > 0 && regionid <= FunGameConstant.Regions.Count && FunGameConstant.Regions.FirstOrDefault(r => r.Id == regionid) is OshimaRegion region)
{
exploreTimes -= characterCount;
exploreTimes -= reduce;
msg = $"开始探索【{region.Name}】,探索时间预计 {FunGameConstant.ExploreTime} 分钟(系统会自动结算,届时会有提示)。" +
$"探索成员:[ {FunGameService.GetCharacterGroupInfoByInventorySequence(user.Inventory.Characters, characterIds, " ] / [ ")} ]";
ExploreModel model = await FunGameService.GenerateExploreModel(region, characterIds, user);
exploreId = model.Guid;
list.Add(model);
msg = $"开始探索【{region.Name}】,探索时间预计 {FunGameConstant.ExploreTime} 分钟(系统会自动结算,届时会有提示)。" +
$"探索成员:[ {FunGameService.GetCharacterGroupInfoByInventorySequence(user.Inventory.Characters, characterIds, " ] / [ ")} ]";
ExploreModel model = await FunGameService.GenerateExploreModel(region, characterIds, user);
exploreId = model.Guid;
list.Add(model);
if (exploreTimes > 0)
{
if (msg != "") msg += "\r\n";
msg += $"本次扣除探索次数 {characterCount} 次,你的剩余探索次数:{exploreTimes} 次。需要注意:探索角色越多,奖励越多,但是会扣除相应的探索次数。";
}
}
else
{
return ($"没有找到与这个序号相对应的地区!", exploreId);
}
if (msg != "") msg += "\r\n";
msg += $"本次消耗探索许可 {reduce} 个,你的剩余探索许可:{exploreTimes} 个。需要注意:探索难度星级一比一兑换探索许可,并且参与探索的角色,都需要消耗相同数量的探索许可。";
}
user.LastTime = DateTime.Now;
@ -5377,13 +5399,13 @@ namespace Oshima.FunGame.WebAPI.Controllers
{
User user = FunGameService.GetUser(pc);
// 检查探索次数
// 检查探索许可
if (pc.TryGetValue("exploreTimes", out object? value) && int.TryParse(value.ToString(), out int exploreTimes))
{
if (exploreTimes <= 0)
{
exploreTimes = 0;
msg = $"今日的探索次数已用完,无法再继续探索。";
msg = $"今日的探索许可已用完,无法再继续探索。";
}
}
else
@ -5414,7 +5436,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
if (exploreTimes > 0)
{
if (msg != "") msg += "\r\n";
msg += $"你的剩余探索次数:{exploreTimes} 次。";
msg += $"你的剩余探索许可:{exploreTimes} 个。";
}
user.LastTime = DateTime.Now;

View File

@ -83,6 +83,7 @@ namespace Oshima.FunGame.WebAPI.Models
public string OpenId { get; }
public string AuthorOpenId { get; }
public long FunGameUID { get; set; }
public bool UseNotice { get; set; }
}
public class ThirdPartyMessage : IBotMessage
@ -113,6 +114,9 @@ namespace Oshima.FunGame.WebAPI.Models
[JsonIgnore]
public long FunGameUID { get; set; } = 0;
[JsonIgnore]
public bool UseNotice { get; set; } = true;
}
public class C2CMessage : IBotMessage
@ -135,6 +139,9 @@ namespace Oshima.FunGame.WebAPI.Models
[JsonIgnore]
public long FunGameUID { get; set; } = 0;
[JsonIgnore]
public bool UseNotice { get; set; } = true;
public string Detail
{
get => Content;
@ -168,6 +175,9 @@ namespace Oshima.FunGame.WebAPI.Models
[JsonIgnore]
public long FunGameUID { get; set; } = 0;
[JsonIgnore]
public bool UseNotice { get; set; } = true;
public string Detail
{
get => Content;

View File

@ -44,7 +44,7 @@ namespace Oshima.FunGame.WebAPI.Services
content = content.Trim();
await Service.SendC2CMessageAsync(msg.OpenId, content, msgType, media, msg.Id, msgSeq);
}
if (msg.FunGameUID > 0 && FunGameService.UserNotice.TryGetValue(msg.FunGameUID, out HashSet<string>? msgs) && msgs != null)
if (msg.UseNotice && msg.FunGameUID > 0 && FunGameService.UserNotice.TryGetValue(msg.FunGameUID, out HashSet<string>? msgs) && msgs != null)
{
FunGameService.UserNotice.Remove(msg.FunGameUID);
await SendAsync(msg, "每日登录提醒", string.Join("\r\n", msgs), msgType, media, 5);
@ -52,8 +52,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
private async Task SendHelp(IBotMessage e, Dictionary<string, string> helpDict, string helpName, int currentPage)
{
int pageSize = 15;
{
e.UseNotice = false;
int pageSize = 15;
int totalPages = (helpDict.Count + pageSize - 1) / pageSize;
StringBuilder result = new($"《筽祀牻》{helpName}指令(第 {currentPage}/{totalPages} 页)\n");
@ -133,28 +134,32 @@ namespace Oshima.FunGame.WebAPI.Services
if (!e.IsGroup && e.Detail == "获取接入码")
{
await SendAsync(e, "获取接入码", $"你的接入码为 {openid},请妥善保存!");
e.UseNotice = false;
await SendAsync(e, "获取接入码", $"你的接入码为 {openid},请妥善保存!");
return true;
}
if (e.Detail == "查询服务器启动时间")
{
string msg = TestController.GetLastLoginTime();
{
e.UseNotice = false;
string msg = TestController.GetLastLoginTime();
await SendAsync(e, "查询服务器启动时间", msg);
return true;
}
if (e.Detail.StartsWith("查询任务计划"))
{
string msg = TestController.GetTaskScheduler(e.Detail.Replace("查询任务计划", ""));
{
e.UseNotice = false;
string msg = TestController.GetTaskScheduler(e.Detail.Replace("查询任务计划", ""));
await SendAsync(e, "查询任务计划", msg);
return true;
}
// 指令处理
if (e.Detail == "帮助")
{
await SendAsync(e, "筽祀牻", @$"欢迎使用《筽祀牻》游戏指令帮助系统!
{
e.UseNotice = false;
await SendAsync(e, "筽祀牻", @$"欢迎使用《筽祀牻》游戏指令帮助系统!
{FunGameInfo.FunGame_Version}
@ -212,8 +217,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail.StartsWith("FunGame模拟", StringComparison.CurrentCultureIgnoreCase))
{
if (!FunGameSimulation)
{
e.UseNotice = false;
if (!FunGameSimulation)
{
FunGameSimulation = true;
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: 0);
@ -260,8 +266,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail.StartsWith("混战模拟"))
{
int maxRespawnTimesMix = 1;
{
e.UseNotice = false;
int maxRespawnTimesMix = 1;
string detail = e.Detail.Replace("混战模拟", "").Trim();
if (int.TryParse(detail, out int times))
{
@ -314,14 +321,16 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail == "上次的完整日志")
{
await SendAsync(e, "筽祀牻", string.Join("\r\n", Controller.GetLast()));
{
e.UseNotice = false;
await SendAsync(e, "筽祀牻", string.Join("\r\n", Controller.GetLast()));
return result;
}
if (e.Detail.StartsWith("FunGame团队模拟", StringComparison.CurrentCultureIgnoreCase))
{
if (!FunGameSimulation)
{
e.UseNotice = false;
if (!FunGameSimulation)
{
FunGameSimulation = true;
List<string> msgs = await Controller.GetTest(false, true);
@ -372,8 +381,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail.StartsWith("查数据", StringComparison.CurrentCultureIgnoreCase))
{
string detail = e.Detail.Replace("查数据", "").Trim();
{
e.UseNotice = false;
string detail = e.Detail.Replace("查数据", "").Trim();
if (int.TryParse(detail, out int id))
{
string msg = Controller.GetStats(id);
@ -386,8 +396,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail.StartsWith("查团队数据", StringComparison.CurrentCultureIgnoreCase))
{
string detail = e.Detail.Replace("查团队数据", "").Trim();
{
e.UseNotice = false;
string detail = e.Detail.Replace("查团队数据", "").Trim();
if (int.TryParse(detail, out int id))
{
string msg = Controller.GetTeamStats(id);
@ -400,8 +411,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail.StartsWith("查个人胜率", StringComparison.CurrentCultureIgnoreCase))
{
List<string> msgs = Controller.GetWinrateRank();
{
e.UseNotice = false;
List<string> msgs = Controller.GetWinrateRank();
if (msgs.Count > 0)
{
await SendAsync(e, "查个人胜率", string.Join("\r\n\r\n", msgs));
@ -410,8 +422,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail.StartsWith("查团队胜率", StringComparison.CurrentCultureIgnoreCase))
{
List<string> msgs = Controller.GetWinrateRank(true);
{
e.UseNotice = false;
List<string> msgs = Controller.GetWinrateRank(true);
if (msgs.Count > 0)
{
await SendAsync(e, "查团队胜率", string.Join("\r\n\r\n", msgs));
@ -420,8 +433,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail.StartsWith("查角色", StringComparison.CurrentCultureIgnoreCase))
{
string detail = e.Detail.Replace("查角色", "").Trim();
{
e.UseNotice = false;
string detail = e.Detail.Replace("查角色", "").Trim();
if (int.TryParse(detail, out int id))
{
string msg = Controller.GetCharacterInfo(id);
@ -434,8 +448,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail.StartsWith("查技能", StringComparison.CurrentCultureIgnoreCase))
{
string detail = e.Detail.Replace("查技能", "").Trim();
{
e.UseNotice = false;
string detail = e.Detail.Replace("查技能", "").Trim();
if (int.TryParse(detail, out int id))
{
string msg = Controller.GetSkillInfo(uid, id);
@ -456,8 +471,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail.StartsWith("查物品", StringComparison.CurrentCultureIgnoreCase))
{
string detail = e.Detail.Replace("查物品", "").Trim();
{
e.UseNotice = false;
string detail = e.Detail.Replace("查物品", "").Trim();
if (int.TryParse(detail, out int id))
{
string msg = Controller.GetItemInfo(uid, id);
@ -478,8 +494,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail.StartsWith("生成"))
{
string pattern = @"生成\s*(\d+)\s*个\s*([\s\S]+)(?:\s*给\s*(\d+))";
{
e.UseNotice = false;
string pattern = @"生成\s*(\d+)\s*个\s*([\s\S]+)(?:\s*给\s*(\d+))";
Regex regex = new(pattern, RegexOptions.IgnoreCase);
Match match = regex.Match(e.Detail);
@ -512,8 +529,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail == "生成魔法卡包")
{
string msg = Controller.GenerateMagicCardPack();
{
e.UseNotice = false;
string msg = Controller.GenerateMagicCardPack();
if (msg != "")
{
await SendAsync(e, "生成魔法卡包", msg);
@ -521,8 +539,9 @@ namespace Oshima.FunGame.WebAPI.Services
return result;
}
else if (e.Detail == "生成魔法卡")
{
string msg = Controller.GenerateMagicCard();
{
e.UseNotice = false;
string msg = Controller.GenerateMagicCard();
if (msg != "")
{
await SendAsync(e, "生成魔法卡", msg);
@ -531,8 +550,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail == "创建存档")
{
string msg = Controller.CreateSaved(name: openid);
{
e.UseNotice = false;
string msg = Controller.CreateSaved(name: openid);
if (msg != "")
{
await SendAsync(e, "创建存档", "\r\n" + msg);
@ -551,8 +571,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail == "我的主战")
{
string msg = Controller.GetCharacterInfoFromInventory(uid, 0);
{
e.UseNotice = false;
string msg = Controller.GetCharacterInfoFromInventory(uid, 0);
if (msg != "")
{
await SendAsync(e, "我的主战", "\r\n" + msg);
@ -561,8 +582,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail == "我的状态")
{
string msg = Controller.ShowMainCharacterOrSquadStatus(uid);
{
e.UseNotice = false;
string msg = Controller.ShowMainCharacterOrSquadStatus(uid);
if (msg != "")
{
await SendAsync(e, "我的状态", "\r\n" + msg);
@ -571,8 +593,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail == "小队状态" || e.Detail == "我的小队状态")
{
string msg = Controller.ShowMainCharacterOrSquadStatus(uid, true);
{
e.UseNotice = false;
string msg = Controller.ShowMainCharacterOrSquadStatus(uid, true);
if (msg != "")
{
await SendAsync(e, "我的小队状态", "\r\n" + msg);
@ -581,8 +604,9 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail == "我的小队")
{
string msg = Controller.ShowSquad(uid);
{
e.UseNotice = false;
string msg = Controller.ShowSquad(uid);
if (msg != "")
{
await SendAsync(e, "我的小队", "\r\n" + msg);