mirror of
https://github.com/oshima-studios/OshimaGameModule.git
synced 2025-08-02 12:02:56 +00:00
添加小队、查看存档、查看角色技能、物品方法;添加 Token 验证,保护 API 方法;分开 Simulation 和 ActionQueue
This commit is contained in:
parent
9f2084b443
commit
538da000e7
@ -16,6 +16,8 @@ namespace Oshima.Core.Configs
|
|||||||
|
|
||||||
public static int BlackFrozenTime { get; set; } = 150;
|
public static int BlackFrozenTime { get; set; } = 150;
|
||||||
|
|
||||||
|
public static List<string> TokenList { get; set; } = [];
|
||||||
|
|
||||||
public static PluginConfig Configs { get; set; } = new("rainbot", "config");
|
public static PluginConfig Configs { get; set; } = new("rainbot", "config");
|
||||||
|
|
||||||
public static void LoadSetting()
|
public static void LoadSetting()
|
||||||
@ -38,6 +40,10 @@ namespace Oshima.Core.Configs
|
|||||||
{
|
{
|
||||||
BlackFrozenTime = Convert.ToInt32((long)value);
|
BlackFrozenTime = Convert.ToInt32((long)value);
|
||||||
}
|
}
|
||||||
|
if (configs.TryGetValue("TokenList", out value) && value != null)
|
||||||
|
{
|
||||||
|
TokenList = (List<string>)value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveConfig()
|
public static void SaveConfig()
|
||||||
@ -46,6 +52,7 @@ namespace Oshima.Core.Configs
|
|||||||
Configs.Add("Master", Master);
|
Configs.Add("Master", Master);
|
||||||
Configs.Add("BlackTimes", BlackTimes);
|
Configs.Add("BlackTimes", BlackTimes);
|
||||||
Configs.Add("BlackFrozenTime", BlackFrozenTime);
|
Configs.Add("BlackFrozenTime", BlackFrozenTime);
|
||||||
|
Configs.Add("TokenList", TokenList);
|
||||||
Configs.SaveConfig();
|
Configs.SaveConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Milimoe.FunGame.Core.Api.Utility;
|
using Milimoe.FunGame.Core.Api.Utility;
|
||||||
@ -12,6 +13,7 @@ using Oshima.FunGame.OshimaModules.Items;
|
|||||||
|
|
||||||
namespace Oshima.Core.Controllers
|
namespace Oshima.Core.Controllers
|
||||||
{
|
{
|
||||||
|
[Authorize(AuthenticationSchemes = "CustomBearer")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
public class FunGameController(ILogger<FunGameController> logger) : ControllerBase
|
public class FunGameController(ILogger<FunGameController> logger) : ControllerBase
|
||||||
@ -28,7 +30,7 @@ namespace Oshima.Core.Controllers
|
|||||||
bool web = isweb ?? true;
|
bool web = isweb ?? true;
|
||||||
bool team = isteam ?? false;
|
bool team = isteam ?? false;
|
||||||
bool all = showall ?? false;
|
bool all = showall ?? false;
|
||||||
return FunGameActionQueue.StartSimulationGame(false, web, team, all);
|
return FunGameSimulation.StartSimulationGame(false, web, team, all);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("stats")]
|
[HttpGet("stats")]
|
||||||
@ -37,7 +39,7 @@ namespace Oshima.Core.Controllers
|
|||||||
if (id != null && id > 0 && id <= FunGameService.Characters.Count)
|
if (id != null && id > 0 && id <= FunGameService.Characters.Count)
|
||||||
{
|
{
|
||||||
Character character = FunGameService.Characters[Convert.ToInt32(id) - 1];
|
Character character = FunGameService.Characters[Convert.ToInt32(id) - 1];
|
||||||
if (FunGameActionQueue.CharacterStatistics.TryGetValue(character, out CharacterStatistics? stats) && stats != null)
|
if (FunGameSimulation.CharacterStatistics.TryGetValue(character, out CharacterStatistics? stats) && stats != null)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new();
|
StringBuilder builder = new();
|
||||||
|
|
||||||
@ -67,14 +69,14 @@ namespace Oshima.Core.Controllers
|
|||||||
builder.AppendLine($"总计前三数:{stats.Top3s}");
|
builder.AppendLine($"总计前三数:{stats.Top3s}");
|
||||||
builder.AppendLine($"总计败场数:{stats.Loses}");
|
builder.AppendLine($"总计败场数:{stats.Loses}");
|
||||||
|
|
||||||
List<string> names = [.. FunGameActionQueue.CharacterStatistics.OrderByDescending(kv => kv.Value.MVPs).Select(kv => kv.Key.GetName())];
|
List<string> names = [.. FunGameSimulation.CharacterStatistics.OrderByDescending(kv => kv.Value.MVPs).Select(kv => kv.Key.GetName())];
|
||||||
builder.AppendLine($"MVP次数:{stats.MVPs}(#{names.IndexOf(character.GetName()) + 1})");
|
builder.AppendLine($"MVP次数:{stats.MVPs}(#{names.IndexOf(character.GetName()) + 1})");
|
||||||
|
|
||||||
names = [.. FunGameActionQueue.CharacterStatistics.OrderByDescending(kv => kv.Value.Winrates).Select(kv => kv.Key.GetName())];
|
names = [.. FunGameSimulation.CharacterStatistics.OrderByDescending(kv => kv.Value.Winrates).Select(kv => kv.Key.GetName())];
|
||||||
builder.AppendLine($"胜率:{stats.Winrates * 100:0.##}%(#{names.IndexOf(character.GetName()) + 1})");
|
builder.AppendLine($"胜率:{stats.Winrates * 100:0.##}%(#{names.IndexOf(character.GetName()) + 1})");
|
||||||
builder.AppendLine($"前三率:{stats.Top3rates * 100:0.##}%");
|
builder.AppendLine($"前三率:{stats.Top3rates * 100:0.##}%");
|
||||||
|
|
||||||
names = [.. FunGameActionQueue.CharacterStatistics.OrderByDescending(kv => kv.Value.Rating).Select(kv => kv.Key.GetName())];
|
names = [.. FunGameSimulation.CharacterStatistics.OrderByDescending(kv => kv.Value.Rating).Select(kv => kv.Key.GetName())];
|
||||||
builder.AppendLine($"技术得分:{stats.Rating:0.0#}(#{names.IndexOf(character.GetName()) + 1})");
|
builder.AppendLine($"技术得分:{stats.Rating:0.0#}(#{names.IndexOf(character.GetName()) + 1})");
|
||||||
|
|
||||||
builder.AppendLine($"上次排名:{stats.LastRank} / 场均名次:{stats.AvgRank:0.##}");
|
builder.AppendLine($"上次排名:{stats.LastRank} / 场均名次:{stats.AvgRank:0.##}");
|
||||||
@ -91,7 +93,7 @@ namespace Oshima.Core.Controllers
|
|||||||
if (id != null && id > 0 && id <= FunGameService.Characters.Count)
|
if (id != null && id > 0 && id <= FunGameService.Characters.Count)
|
||||||
{
|
{
|
||||||
Character character = FunGameService.Characters[Convert.ToInt32(id) - 1];
|
Character character = FunGameService.Characters[Convert.ToInt32(id) - 1];
|
||||||
if (FunGameActionQueue.TeamCharacterStatistics.TryGetValue(character, out CharacterStatistics? stats) && stats != null)
|
if (FunGameSimulation.TeamCharacterStatistics.TryGetValue(character, out CharacterStatistics? stats) && stats != null)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new();
|
StringBuilder builder = new();
|
||||||
|
|
||||||
@ -121,11 +123,11 @@ namespace Oshima.Core.Controllers
|
|||||||
builder.AppendLine($"总计胜场数:{stats.Wins}");
|
builder.AppendLine($"总计胜场数:{stats.Wins}");
|
||||||
builder.AppendLine($"总计败场数:{stats.Loses}");
|
builder.AppendLine($"总计败场数:{stats.Loses}");
|
||||||
|
|
||||||
List<string> names = [.. FunGameActionQueue.TeamCharacterStatistics.OrderByDescending(kv => kv.Value.MVPs).Select(kv => kv.Key.GetName())];
|
List<string> names = [.. FunGameSimulation.TeamCharacterStatistics.OrderByDescending(kv => kv.Value.MVPs).Select(kv => kv.Key.GetName())];
|
||||||
builder.AppendLine($"MVP次数:{stats.MVPs}(#{names.IndexOf(character.GetName()) + 1})");
|
builder.AppendLine($"MVP次数:{stats.MVPs}(#{names.IndexOf(character.GetName()) + 1})");
|
||||||
names = [.. FunGameActionQueue.TeamCharacterStatistics.OrderByDescending(kv => kv.Value.Winrates).Select(kv => kv.Key.GetName())];
|
names = [.. FunGameSimulation.TeamCharacterStatistics.OrderByDescending(kv => kv.Value.Winrates).Select(kv => kv.Key.GetName())];
|
||||||
builder.AppendLine($"胜率:{stats.Winrates * 100:0.##}%(#{names.IndexOf(character.GetName()) + 1})");
|
builder.AppendLine($"胜率:{stats.Winrates * 100:0.##}%(#{names.IndexOf(character.GetName()) + 1})");
|
||||||
names = [.. FunGameActionQueue.TeamCharacterStatistics.OrderByDescending(kv => kv.Value.Rating).Select(kv => kv.Key.GetName())];
|
names = [.. FunGameSimulation.TeamCharacterStatistics.OrderByDescending(kv => kv.Value.Rating).Select(kv => kv.Key.GetName())];
|
||||||
builder.AppendLine($"技术得分:{stats.Rating:0.0#}(#{names.IndexOf(character.GetName()) + 1})");
|
builder.AppendLine($"技术得分:{stats.Rating:0.0#}(#{names.IndexOf(character.GetName()) + 1})");
|
||||||
|
|
||||||
return NetworkUtility.JsonSerialize(builder.ToString());
|
return NetworkUtility.JsonSerialize(builder.ToString());
|
||||||
@ -141,11 +143,11 @@ namespace Oshima.Core.Controllers
|
|||||||
if (team)
|
if (team)
|
||||||
{
|
{
|
||||||
List<string> strings = [];
|
List<string> strings = [];
|
||||||
IEnumerable<Character> ratings = FunGameActionQueue.TeamCharacterStatistics.OrderByDescending(kv => kv.Value.Winrates).Select(kv => kv.Key);
|
IEnumerable<Character> ratings = FunGameSimulation.TeamCharacterStatistics.OrderByDescending(kv => kv.Value.Winrates).Select(kv => kv.Key);
|
||||||
foreach (Character character in ratings)
|
foreach (Character character in ratings)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new();
|
StringBuilder builder = new();
|
||||||
CharacterStatistics stats = FunGameActionQueue.TeamCharacterStatistics[character];
|
CharacterStatistics stats = FunGameSimulation.TeamCharacterStatistics[character];
|
||||||
builder.AppendLine(character.ToString());
|
builder.AppendLine(character.ToString());
|
||||||
builder.AppendLine($"总计参赛数:{stats.Plays}");
|
builder.AppendLine($"总计参赛数:{stats.Plays}");
|
||||||
builder.AppendLine($"总计冠军数:{stats.Wins}");
|
builder.AppendLine($"总计冠军数:{stats.Wins}");
|
||||||
@ -159,11 +161,11 @@ namespace Oshima.Core.Controllers
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<string> strings = [];
|
List<string> strings = [];
|
||||||
IEnumerable<Character> ratings = FunGameActionQueue.CharacterStatistics.OrderByDescending(kv => kv.Value.Winrates).Select(kv => kv.Key);
|
IEnumerable<Character> ratings = FunGameSimulation.CharacterStatistics.OrderByDescending(kv => kv.Value.Winrates).Select(kv => kv.Key);
|
||||||
foreach (Character character in ratings)
|
foreach (Character character in ratings)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new();
|
StringBuilder builder = new();
|
||||||
CharacterStatistics stats = FunGameActionQueue.CharacterStatistics[character];
|
CharacterStatistics stats = FunGameSimulation.CharacterStatistics[character];
|
||||||
builder.AppendLine(character.ToString());
|
builder.AppendLine(character.ToString());
|
||||||
builder.AppendLine($"总计参赛数:{stats.Plays}");
|
builder.AppendLine($"总计参赛数:{stats.Plays}");
|
||||||
builder.AppendLine($"总计冠军数:{stats.Wins}");
|
builder.AppendLine($"总计冠军数:{stats.Wins}");
|
||||||
@ -185,11 +187,11 @@ namespace Oshima.Core.Controllers
|
|||||||
if (team)
|
if (team)
|
||||||
{
|
{
|
||||||
List<string> strings = [];
|
List<string> strings = [];
|
||||||
IEnumerable<Character> ratings = FunGameActionQueue.TeamCharacterStatistics.OrderByDescending(kv => kv.Value.Rating).Select(kv => kv.Key);
|
IEnumerable<Character> ratings = FunGameSimulation.TeamCharacterStatistics.OrderByDescending(kv => kv.Value.Rating).Select(kv => kv.Key);
|
||||||
foreach (Character character in ratings)
|
foreach (Character character in ratings)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new();
|
StringBuilder builder = new();
|
||||||
CharacterStatistics stats = FunGameActionQueue.TeamCharacterStatistics[character];
|
CharacterStatistics stats = FunGameSimulation.TeamCharacterStatistics[character];
|
||||||
builder.AppendLine(character.ToString());
|
builder.AppendLine(character.ToString());
|
||||||
builder.AppendLine($"总计参赛数:{stats.Plays}");
|
builder.AppendLine($"总计参赛数:{stats.Plays}");
|
||||||
builder.AppendLine($"总计冠军数:{stats.Wins}");
|
builder.AppendLine($"总计冠军数:{stats.Wins}");
|
||||||
@ -203,11 +205,11 @@ namespace Oshima.Core.Controllers
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<string> strings = [];
|
List<string> strings = [];
|
||||||
IEnumerable<Character> ratings = FunGameActionQueue.CharacterStatistics.OrderByDescending(kv => kv.Value.Rating).Select(kv => kv.Key);
|
IEnumerable<Character> ratings = FunGameSimulation.CharacterStatistics.OrderByDescending(kv => kv.Value.Rating).Select(kv => kv.Key);
|
||||||
foreach (Character character in ratings)
|
foreach (Character character in ratings)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new();
|
StringBuilder builder = new();
|
||||||
CharacterStatistics stats = FunGameActionQueue.CharacterStatistics[character];
|
CharacterStatistics stats = FunGameSimulation.CharacterStatistics[character];
|
||||||
builder.AppendLine(character.ToString());
|
builder.AppendLine(character.ToString());
|
||||||
builder.AppendLine($"总计参赛数:{stats.Plays}");
|
builder.AppendLine($"总计参赛数:{stats.Plays}");
|
||||||
builder.AppendLine($"总计冠军数:{stats.Wins}");
|
builder.AppendLine($"总计冠军数:{stats.Wins}");
|
||||||
@ -352,6 +354,49 @@ namespace Oshima.Core.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("showsaved")]
|
||||||
|
public string ShowSaved([FromQuery] long? qq = null)
|
||||||
|
{
|
||||||
|
long userid = qq ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
|
||||||
|
|
||||||
|
PluginConfig pc = new("saved", userid.ToString());
|
||||||
|
pc.LoadConfig();
|
||||||
|
|
||||||
|
if (pc.Count > 0)
|
||||||
|
{
|
||||||
|
User user = FunGameService.GetUser(pc);
|
||||||
|
|
||||||
|
StringBuilder builder = new();
|
||||||
|
builder.AppendLine($"☆★☆ {user.Username}的存档信息 ☆★☆");
|
||||||
|
builder.AppendLine($"{General.GameplayEquilibriumConstant.InGameCurrency}:{user.Inventory.Credits:0.00}");
|
||||||
|
builder.AppendLine($"{General.GameplayEquilibriumConstant.InGameMaterial}:{user.Inventory.Materials:0.00}");
|
||||||
|
builder.AppendLine($"角色数量:{user.Inventory.Characters.Count}");
|
||||||
|
builder.AppendLine($"主战角色:{user.Inventory.MainCharacter.ToStringWithLevelWithOutUser()}");
|
||||||
|
Character[] squad = [.. user.Inventory.Characters.Where(c => user.Inventory.Squad.Contains(c.Id))];
|
||||||
|
Dictionary<Character, int> characters = user.Inventory.Characters
|
||||||
|
.Select((character, index) => new { character, index })
|
||||||
|
.ToDictionary(x => x.character, x => x.index + 1);
|
||||||
|
builder.AppendLine($"小队成员:{(squad.Length > 0 ? string.Join(" / ", squad.Select(c => $"[#{characters[c]}]{c.Name}({c.Level})")) : "空")}");
|
||||||
|
if (user.Inventory.Training.Count > 0)
|
||||||
|
{
|
||||||
|
builder.AppendLine($"正在练级:{string.Join(" / ", user.Inventory.Characters.Where(c => user.Inventory.Training.ContainsKey(c.Id)).Select(c => c.ToStringWithLevelWithOutUser()))}");
|
||||||
|
}
|
||||||
|
builder.AppendLine($"物品数量:{user.Inventory.Items.Count}");
|
||||||
|
builder.AppendLine($"所属社团:无");
|
||||||
|
builder.AppendLine($"注册时间:{user.RegTime.ToString(General.GeneralDateTimeFormatChinese)}");
|
||||||
|
builder.AppendLine($"最后访问:{user.LastTime.ToString(General.GeneralDateTimeFormatChinese)}");
|
||||||
|
|
||||||
|
user.LastTime = DateTime.Now;
|
||||||
|
pc.Add("user", user);
|
||||||
|
pc.SaveConfig();
|
||||||
|
return NetworkUtility.JsonSerialize(builder.ToString().Trim());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(noSaved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("rename")]
|
[HttpPost("rename")]
|
||||||
public string ReName([FromQuery] long? qq = null)
|
public string ReName([FromQuery] long? qq = null)
|
||||||
{
|
{
|
||||||
@ -1166,6 +1211,92 @@ namespace Oshima.Core.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("showcharacterskills")]
|
||||||
|
public string GetCharacterSkills([FromQuery] long? qq = null, [FromQuery] int? seq = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long userid = qq ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
|
||||||
|
int cIndex = seq ?? 0;
|
||||||
|
|
||||||
|
PluginConfig pc = new("saved", userid.ToString());
|
||||||
|
pc.LoadConfig();
|
||||||
|
|
||||||
|
if (pc.Count > 0)
|
||||||
|
{
|
||||||
|
User user = FunGameService.GetUser(pc);
|
||||||
|
|
||||||
|
if (cIndex == 0)
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize($"这是你的主战角色技能信息:\r\n{user.Inventory.MainCharacter.GetSkillInfo().Trim()}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cIndex > 0 && cIndex <= user.Inventory.Characters.Count)
|
||||||
|
{
|
||||||
|
Character character = user.Inventory.Characters.ToList()[cIndex - 1];
|
||||||
|
return NetworkUtility.JsonSerialize($"这是你库存中序号为 {cIndex} 的角色技能信息:\r\n{character.GetSkillInfo().Trim()}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize($"没有找到与这个序号相对应的角色!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(noSaved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("showcharacteritems")]
|
||||||
|
public string GetCharacterItems([FromQuery] long? qq = null, [FromQuery] int? seq = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long userid = qq ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
|
||||||
|
int cIndex = seq ?? 0;
|
||||||
|
|
||||||
|
PluginConfig pc = new("saved", userid.ToString());
|
||||||
|
pc.LoadConfig();
|
||||||
|
|
||||||
|
if (pc.Count > 0)
|
||||||
|
{
|
||||||
|
User user = FunGameService.GetUser(pc);
|
||||||
|
|
||||||
|
if (cIndex == 0)
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize($"这是你的主战角色装备物品信息:\r\n{user.Inventory.MainCharacter.GetItemInfo(showEXP: true).Trim()}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cIndex > 0 && cIndex <= user.Inventory.Characters.Count)
|
||||||
|
{
|
||||||
|
Character character = user.Inventory.Characters.ToList()[cIndex - 1];
|
||||||
|
return NetworkUtility.JsonSerialize($"这是你库存中序号为 {cIndex} 的角色装备物品信息:\r\n{character.GetItemInfo(showEXP: true).Trim()}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize($"没有找到与这个序号相对应的角色!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(noSaved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("showiteminfo")]
|
[HttpPost("showiteminfo")]
|
||||||
public string GetItemInfoFromInventory([FromQuery] long? qq = null, [FromQuery] int? seq = null)
|
public string GetItemInfoFromInventory([FromQuery] long? qq = null, [FromQuery] int? seq = null)
|
||||||
{
|
{
|
||||||
@ -1358,7 +1489,7 @@ namespace Oshima.Core.Controllers
|
|||||||
|
|
||||||
if (user1 != null && user2 != null)
|
if (user1 != null && user2 != null)
|
||||||
{
|
{
|
||||||
return FunGameActionQueue.StartGame([user1.Inventory.MainCharacter, user2.Inventory.MainCharacter], false, false, false, false, showAllRound);
|
return FunGameActionQueue.NewAndStartGame([user1.Inventory.MainCharacter, user2.Inventory.MainCharacter], false, false, false, false, showAllRound);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2316,7 +2447,7 @@ namespace Oshima.Core.Controllers
|
|||||||
user.LastTime = DateTime.Now;
|
user.LastTime = DateTime.Now;
|
||||||
pc.Add("user", user);
|
pc.Add("user", user);
|
||||||
pc.SaveConfig();
|
pc.SaveConfig();
|
||||||
return NetworkUtility.JsonSerialize($"角色 [{character}] 开始练级,请过一段时间后进行【练级结算】,时间越长奖励越丰盛!练级时间最长 1440 分钟(24小时),超时将无任何收益,请及时领取奖励。");
|
return NetworkUtility.JsonSerialize($"角色 [{character}] 开始练级,请过一段时间后进行【练级结算】,时间越长奖励越丰盛!练级时间上限 1440 分钟(24小时),超时将不会再产生收益,请按时领取奖励!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2856,7 +2987,7 @@ namespace Oshima.Core.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
Character boss2 = CharacterBuilder.Build(boss, false, true, null, FunGameService.AllItems, FunGameService.AllSkills, false);
|
Character boss2 = CharacterBuilder.Build(boss, false, true, null, FunGameService.AllItems, FunGameService.AllSkills, false);
|
||||||
List<string> msgs = FunGameActionQueue.StartGame([user.Inventory.MainCharacter, boss2], false, false, false, false, showAllRound);
|
List<string> msgs = FunGameActionQueue.NewAndStartGame([user.Inventory.MainCharacter, boss2], false, false, false, false, showAllRound);
|
||||||
|
|
||||||
if (boss2.HP <= 0)
|
if (boss2.HP <= 0)
|
||||||
{
|
{
|
||||||
@ -2991,11 +3122,115 @@ namespace Oshima.Core.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("setsquad")]
|
||||||
|
public string SetSquad([FromQuery] long? qq = null, [FromBody] int[]? c = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long userid = qq ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
|
||||||
|
int[] characterIndexs = c ?? [];
|
||||||
|
|
||||||
|
PluginConfig pc = new("saved", userid.ToString());
|
||||||
|
pc.LoadConfig();
|
||||||
|
|
||||||
|
if (pc.Count > 0)
|
||||||
|
{
|
||||||
|
User user = FunGameService.GetUser(pc);
|
||||||
|
|
||||||
|
user.Inventory.Squad.Clear();
|
||||||
|
foreach (int characterIndex in characterIndexs)
|
||||||
|
{
|
||||||
|
Character? character = null;
|
||||||
|
if (characterIndex > 0 && characterIndex <= user.Inventory.Characters.Count)
|
||||||
|
{
|
||||||
|
character = user.Inventory.Characters.ToList()[characterIndex - 1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize($"设置失败:没有找到与序号 {characterIndex} 相对应的角色!");
|
||||||
|
}
|
||||||
|
user.Inventory.Squad.Add(character.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
user.LastTime = DateTime.Now;
|
||||||
|
pc.Add("user", user);
|
||||||
|
pc.SaveConfig();
|
||||||
|
return NetworkUtility.JsonSerialize($"设置小队成员成功!当前小队角色如下:\r\n" +
|
||||||
|
string.Join("\r\n", user.Inventory.Characters.Where(c => user.Inventory.Squad.Contains(c.Id))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(noSaved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("clearsquad")]
|
||||||
|
public string ClearSquad([FromQuery] long? qq = null, [FromBody] int[]? c = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long userid = qq ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
|
||||||
|
int[] characterIndexs = c ?? [];
|
||||||
|
|
||||||
|
PluginConfig pc = new("saved", userid.ToString());
|
||||||
|
pc.LoadConfig();
|
||||||
|
|
||||||
|
if (pc.Count > 0)
|
||||||
|
{
|
||||||
|
User user = FunGameService.GetUser(pc);
|
||||||
|
|
||||||
|
user.Inventory.Squad.Clear();
|
||||||
|
user.LastTime = DateTime.Now;
|
||||||
|
pc.Add("user", user);
|
||||||
|
pc.SaveConfig();
|
||||||
|
return NetworkUtility.JsonSerialize($"清空小队成员成功!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(noSaved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("showsquad")]
|
||||||
|
public string ShowSquad([FromQuery] long? qq = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long userid = qq ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
|
||||||
|
|
||||||
|
PluginConfig pc = new("saved", userid.ToString());
|
||||||
|
pc.LoadConfig();
|
||||||
|
|
||||||
|
if (pc.Count > 0)
|
||||||
|
{
|
||||||
|
User user = FunGameService.GetUser(pc);
|
||||||
|
return NetworkUtility.JsonSerialize($"你的当前小队角色如下:\r\n" +
|
||||||
|
string.Join("\r\n", user.Inventory.Characters.Where(c => user.Inventory.Squad.Contains(c.Id))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(noSaved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("fightbossteam")]
|
[HttpPost("fightbossteam")]
|
||||||
public List<string> FightBossTeam([FromQuery] long? qq = null, [FromQuery] int? index = null, [FromQuery] bool? all = null)
|
public List<string> FightBossTeam([FromQuery] long? qq = null, [FromQuery] int? index = null, [FromQuery] bool? all = null)
|
||||||
{
|
{
|
||||||
return [];
|
|
||||||
|
|
||||||
long userid = qq ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
|
long userid = qq ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
|
||||||
int bossIndex = index ?? 0;
|
int bossIndex = index ?? 0;
|
||||||
bool showAllRound = all ?? false;
|
bool showAllRound = all ?? false;
|
||||||
@ -3013,14 +3248,15 @@ namespace Oshima.Core.Controllers
|
|||||||
|
|
||||||
if (squad.All(c => c.HP < c.MaxHP * 0.1))
|
if (squad.All(c => c.HP < c.MaxHP * 0.1))
|
||||||
{
|
{
|
||||||
return [$"小队角色均重伤未愈,当前生命值低于 10%,请先等待生命值自动回复或重组小队!",
|
return [$"小队角色均重伤未愈,当前生命值低于 10%,请先等待生命值自动回复或重组小队!\r\n" +
|
||||||
"当前小队角色如下:",
|
"当前小队角色如下:\r\n" +
|
||||||
string.Join("\r\n", user.Inventory.Characters.Where(c => user.Inventory.Squad.Contains(c.Id)))];
|
string.Join("\r\n", user.Inventory.Characters.Where(c => user.Inventory.Squad.Contains(c.Id)))];
|
||||||
}
|
}
|
||||||
|
|
||||||
Character boss2 = CharacterBuilder.Build(boss, false, true, null, FunGameService.AllItems, FunGameService.AllSkills, false);
|
Character boss2 = CharacterBuilder.Build(boss, false, true, null, FunGameService.AllItems, FunGameService.AllSkills, false);
|
||||||
//List<string> msgs = FunGameActionQueue.StartGameTeam;
|
Team team1 = new($"{user.Username}的小队", squad);
|
||||||
List<string> msgs = [];
|
Team team2 = new($"Boss", [boss2]);
|
||||||
|
List<string> msgs = FunGameActionQueue.NewAndStartTeamGame([team1, team2], showAllRound: showAllRound);
|
||||||
|
|
||||||
if (boss2.HP <= 0)
|
if (boss2.HP <= 0)
|
||||||
{
|
{
|
||||||
@ -3059,7 +3295,7 @@ namespace Oshima.Core.Controllers
|
|||||||
if (master != null && master == GeneralSettings.Master)
|
if (master != null && master == GeneralSettings.Master)
|
||||||
{
|
{
|
||||||
FunGameService.Reload();
|
FunGameService.Reload();
|
||||||
FunGameActionQueue.InitFunGameActionQueue();
|
FunGameSimulation.InitFunGameSimulation();
|
||||||
return NetworkUtility.JsonSerialize("FunGame已重新加载。");
|
return NetworkUtility.JsonSerialize("FunGame已重新加载。");
|
||||||
}
|
}
|
||||||
return NetworkUtility.JsonSerialize("提供的参数不正确。");
|
return NetworkUtility.JsonSerialize("提供的参数不正确。");
|
||||||
|
@ -3,9 +3,9 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Milimoe.FunGame.Core.Api.Transmittal;
|
using Milimoe.FunGame.Core.Api.Transmittal;
|
||||||
using Milimoe.FunGame.Core.Api.Utility;
|
using Milimoe.FunGame.Core.Api.Utility;
|
||||||
using Milimoe.FunGame.Core.Library.Constant;
|
|
||||||
using Milimoe.FunGame.Core.Library.Exception;
|
using Milimoe.FunGame.Core.Library.Exception;
|
||||||
using Milimoe.FunGame.Core.Library.SQLScript.Common;
|
using Milimoe.FunGame.Core.Library.SQLScript.Common;
|
||||||
|
using Oshima.Core.Configs;
|
||||||
using Oshima.Core.Constant;
|
using Oshima.Core.Constant;
|
||||||
using TaskScheduler = Milimoe.FunGame.Core.Api.Utility.TaskScheduler;
|
using TaskScheduler = Milimoe.FunGame.Core.Api.Utility.TaskScheduler;
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ namespace Oshima.Core.Controllers
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Statics.RunningPlugin.Controller?.Error(e);
|
Statics.RunningPlugin.Controller.Error(e);
|
||||||
return NetworkUtility.JsonSerialize("无法调用此接口。原因:\r\n" + e.GetErrorInfo());
|
return NetworkUtility.JsonSerialize("无法调用此接口。原因:\r\n" + e.GetErrorInfo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,5 +59,28 @@ namespace Oshima.Core.Controllers
|
|||||||
{
|
{
|
||||||
return NetworkUtility.JsonSerialize(TaskScheduler.Shared.GetRunTimeInfo(name));
|
return NetworkUtility.JsonSerialize(TaskScheduler.Shared.GetRunTimeInfo(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("sendtest")]
|
||||||
|
public string SendTest(long key, string to)
|
||||||
|
{
|
||||||
|
if (Statics.RunningPlugin != null && key == GeneralSettings.Master)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MailSender? sender = Statics.RunningPlugin.Controller.MailSender;
|
||||||
|
if (sender != null && sender.Send(new(sender, "Test Mail", "Hello!", to)) == Milimoe.FunGame.Core.Library.Constant.MailSendResult.Success)
|
||||||
|
{
|
||||||
|
return NetworkUtility.JsonSerialize("发送成功。");
|
||||||
|
}
|
||||||
|
return NetworkUtility.JsonSerialize("发送失败。");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Statics.RunningPlugin.Controller.Error(e);
|
||||||
|
return NetworkUtility.JsonSerialize("无法调用此接口。原因:\r\n" + e.GetErrorInfo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NetworkUtility.JsonSerialize("无法调用此接口。");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ namespace Oshima.Core.WebAPI
|
|||||||
{
|
{
|
||||||
if (input.StartsWith("fungametest"))
|
if (input.StartsWith("fungametest"))
|
||||||
{
|
{
|
||||||
FunGameActionQueue.StartSimulationGame(true, true);
|
FunGameSimulation.StartSimulationGame(true, true);
|
||||||
}
|
}
|
||||||
// OSM指令
|
// OSM指令
|
||||||
if (input.Length >= 4 && input[..4].Equals(".osm", StringComparison.CurrentCultureIgnoreCase))
|
if (input.Length >= 4 && input[..4].Equals(".osm", StringComparison.CurrentCultureIgnoreCase))
|
||||||
@ -46,7 +46,8 @@ namespace Oshima.Core.WebAPI
|
|||||||
SayNo.InitSayNo();
|
SayNo.InitSayNo();
|
||||||
Ignore.InitIgnore();
|
Ignore.InitIgnore();
|
||||||
FunGameService.InitFunGame();
|
FunGameService.InitFunGame();
|
||||||
FunGameActionQueue.InitFunGameActionQueue();
|
FunGameSimulation.InitFunGameSimulation();
|
||||||
|
WebAPIAuthenticator.WebAPICustomBearerTokenAuthenticator += CustomBearerTokenAuthenticator;
|
||||||
TaskScheduler.Shared.AddTask("重置每日运势", new TimeSpan(0, 0, 0), () =>
|
TaskScheduler.Shared.AddTask("重置每日运势", new TimeSpan(0, 0, 0), () =>
|
||||||
{
|
{
|
||||||
Controller.WriteLine("已重置所有人的今日运势");
|
Controller.WriteLine("已重置所有人的今日运势");
|
||||||
@ -88,5 +89,14 @@ namespace Oshima.Core.WebAPI
|
|||||||
Controller.WriteLine("刷新boss");
|
Controller.WriteLine("刷新boss");
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string CustomBearerTokenAuthenticator(string token)
|
||||||
|
{
|
||||||
|
if (GeneralSettings.TokenList.Contains(token))
|
||||||
|
{
|
||||||
|
return "APIUser";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,6 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Milimoe.FunGame.Core.Api.Utility;
|
using Milimoe.FunGame.Core.Api.Utility;
|
||||||
using Milimoe.FunGame.Core.Entity;
|
using Milimoe.FunGame.Core.Entity;
|
||||||
using Milimoe.FunGame.Core.Interface.Entity;
|
|
||||||
using Milimoe.FunGame.Core.Library.Constant;
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
using Oshima.FunGame.OshimaModules;
|
using Oshima.FunGame.OshimaModules;
|
||||||
using Oshima.FunGame.OshimaModules.Characters;
|
using Oshima.FunGame.OshimaModules.Characters;
|
||||||
@ -1111,6 +1110,7 @@ namespace Oshima.Core.Utils
|
|||||||
Item? magicCardPack = GenerateMagicCardPack(5, (QualityType)4);
|
Item? magicCardPack = GenerateMagicCardPack(5, (QualityType)4);
|
||||||
if (magicCardPack != null)
|
if (magicCardPack != null)
|
||||||
{
|
{
|
||||||
|
magicCardPack.QualityType = QualityType.Red;
|
||||||
foreach (Skill magic in magicCardPack.Skills.Magics)
|
foreach (Skill magic in magicCardPack.Skills.Magics)
|
||||||
{
|
{
|
||||||
magic.Level = mLevel;
|
magic.Level = mLevel;
|
||||||
@ -1389,5 +1389,169 @@ namespace Oshima.Core.Utils
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Dictionary<EffectID, Dictionary<string, object>> RoundRewards
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
EffectID.ExATK,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
{ "exatk", Random.Shared.Next(40, 80) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
EffectID.ExCritRate,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
{ "excr", Math.Clamp(Random.Shared.NextDouble(), 0.25, 0.5) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
EffectID.ExCritDMG,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
{ "excrd", Math.Clamp(Random.Shared.NextDouble(), 0.5, 1) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
EffectID.ExATK2,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
{ "exatk", Math.Clamp(Random.Shared.NextDouble(), 0.15, 0.3) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
EffectID.RecoverHP,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
{ "hp", Random.Shared.Next(160, 640) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
EffectID.RecoverMP,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
{ "mp", Random.Shared.Next(140, 490) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
EffectID.RecoverHP2,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
{ "hp", Math.Clamp(Random.Shared.NextDouble(), 0.04, 0.08) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
EffectID.RecoverMP2,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
{ "mp", Math.Clamp(Random.Shared.NextDouble(), 0.09, 0.18) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
EffectID.GetEP,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
{ "ep", Random.Shared.Next(20, 40) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<int, List<Skill>> GenerateRoundRewards(int maxRound)
|
||||||
|
{
|
||||||
|
Dictionary<int, List<Skill>> roundRewards = [];
|
||||||
|
|
||||||
|
int currentRound = 1;
|
||||||
|
while (currentRound <= maxRound)
|
||||||
|
{
|
||||||
|
currentRound += Random.Shared.Next(1, 9);
|
||||||
|
|
||||||
|
if (currentRound <= maxRound)
|
||||||
|
{
|
||||||
|
List<Skill> skills = [];
|
||||||
|
|
||||||
|
// 添加回合奖励特效
|
||||||
|
long effectID = (long)RoundRewards.Keys.ToArray()[Random.Shared.Next(RoundRewards.Count)];
|
||||||
|
Dictionary<string, object> args = [];
|
||||||
|
if (effectID > (long)EffectID.Active_Start)
|
||||||
|
{
|
||||||
|
args.Add("active", true);
|
||||||
|
args.Add("self", true);
|
||||||
|
args.Add("enemy", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
skills.Add(Factory.OpenFactory.GetInstance<Skill>(effectID, "回合奖励", args));
|
||||||
|
|
||||||
|
roundRewards[currentRound] = skills;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return roundRewards;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double CalculateRating(CharacterStatistics stats, Team? team = null)
|
||||||
|
{
|
||||||
|
// 基础得分
|
||||||
|
double baseScore = (stats.Kills + stats.Assists) / (stats.Kills + stats.Assists + stats.Deaths + 0.01);
|
||||||
|
if (team is null)
|
||||||
|
{
|
||||||
|
baseScore += stats.Kills * 0.1;
|
||||||
|
if (stats.Deaths == 0)
|
||||||
|
{
|
||||||
|
baseScore += 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
baseScore = baseScore * 0.6 + 0.4 * (stats.Kills / (stats.Kills + stats.Deaths + 0.01));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 伤害贡献
|
||||||
|
double logDamageContribution = Math.Log(1 + (stats.TotalDamage / (stats.TotalTakenDamage + 1e-6)));
|
||||||
|
|
||||||
|
// 存活时间贡献
|
||||||
|
double liveTimeContribution = Math.Log(1 + (stats.LiveTime / (stats.TotalTakenDamage + 0.01) * 100));
|
||||||
|
|
||||||
|
// 团队模式参团率加成
|
||||||
|
double teamContribution = 0;
|
||||||
|
if (team != null)
|
||||||
|
{
|
||||||
|
teamContribution = (stats.Kills + stats.Assists) / (team.Score + 0.01);
|
||||||
|
if (team.IsWinner)
|
||||||
|
{
|
||||||
|
teamContribution += 0.15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 权重设置
|
||||||
|
double k = stats.Deaths > 0 ? 0.2 : 0.075; // 伤害贡献权重
|
||||||
|
double l = stats.Deaths > 0 ? 0.2 : 0.05; // 存活时间权重
|
||||||
|
double t = stats.Deaths > 0 ? 0.2 : 0.075; // 参团率权重
|
||||||
|
|
||||||
|
// 计算最终评分
|
||||||
|
double rating = baseScore + k * logDamageContribution + l * liveTimeContribution + t * teamContribution;
|
||||||
|
|
||||||
|
// 确保评分在合理范围内
|
||||||
|
return Math.Max(0.01, rating);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GetCharacterRating(Dictionary<Character, CharacterStatistics> statistics, bool isTeam, List<Team> teams)
|
||||||
|
{
|
||||||
|
foreach (Character character in statistics.Keys)
|
||||||
|
{
|
||||||
|
Team? team = null;
|
||||||
|
if (isTeam)
|
||||||
|
{
|
||||||
|
team = teams.Where(t => t.IsOnThisTeam(character)).FirstOrDefault();
|
||||||
|
}
|
||||||
|
statistics[character].Rating = CalculateRating(statistics[character], team);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
691
OshimaCore/Utils/FunGameSimulation.cs
Normal file
691
OshimaCore/Utils/FunGameSimulation.cs
Normal file
@ -0,0 +1,691 @@
|
|||||||
|
using System.Text;
|
||||||
|
using Milimoe.FunGame.Core.Api.Utility;
|
||||||
|
using Milimoe.FunGame.Core.Entity;
|
||||||
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
|
using Milimoe.FunGame.Core.Model;
|
||||||
|
using Oshima.FunGame.OshimaModules.Effects.OpenEffects;
|
||||||
|
|
||||||
|
namespace Oshima.Core.Utils
|
||||||
|
{
|
||||||
|
public class FunGameSimulation
|
||||||
|
{
|
||||||
|
public static Dictionary<Character, CharacterStatistics> CharacterStatistics { get; } = [];
|
||||||
|
public static Dictionary<Character, CharacterStatistics> TeamCharacterStatistics { get; } = [];
|
||||||
|
public static PluginConfig StatsConfig { get; } = new("FunGameSimulation", nameof(CharacterStatistics));
|
||||||
|
public static PluginConfig TeamStatsConfig { get; } = new("FunGameSimulation", nameof(TeamCharacterStatistics));
|
||||||
|
public static bool IsRuning { get; set; } = false;
|
||||||
|
public static bool IsWeb { get; set; } = false;
|
||||||
|
public static bool PrintOut { get; set; } = false;
|
||||||
|
public static bool DeathMatchRoundDetail { get; set; } = false;
|
||||||
|
public static string Msg { get; set; } = "";
|
||||||
|
|
||||||
|
public static void InitFunGameSimulation()
|
||||||
|
{
|
||||||
|
CharacterStatistics.Clear();
|
||||||
|
TeamCharacterStatistics.Clear();
|
||||||
|
|
||||||
|
foreach (Character c in FunGameService.Characters)
|
||||||
|
{
|
||||||
|
CharacterStatistics.Add(c, new());
|
||||||
|
}
|
||||||
|
|
||||||
|
StatsConfig.LoadConfig();
|
||||||
|
foreach (Character character in CharacterStatistics.Keys)
|
||||||
|
{
|
||||||
|
if (StatsConfig.ContainsKey(character.ToStringWithOutUser()))
|
||||||
|
{
|
||||||
|
CharacterStatistics[character] = StatsConfig.Get<CharacterStatistics>(character.ToStringWithOutUser()) ?? CharacterStatistics[character];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Character c in FunGameService.Characters)
|
||||||
|
{
|
||||||
|
TeamCharacterStatistics.Add(c, new());
|
||||||
|
}
|
||||||
|
|
||||||
|
TeamStatsConfig.LoadConfig();
|
||||||
|
foreach (Character character in TeamCharacterStatistics.Keys)
|
||||||
|
{
|
||||||
|
if (TeamStatsConfig.ContainsKey(character.ToStringWithOutUser()))
|
||||||
|
{
|
||||||
|
TeamCharacterStatistics[character] = TeamStatsConfig.Get<CharacterStatistics>(character.ToStringWithOutUser()) ?? TeamCharacterStatistics[character];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<string> StartSimulationGame(bool printout, bool isWeb = false, bool isTeam = false, bool deathMatchRoundDetail = false)
|
||||||
|
{
|
||||||
|
PrintOut = printout;
|
||||||
|
IsWeb = isWeb;
|
||||||
|
DeathMatchRoundDetail = deathMatchRoundDetail;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (IsRuning) return ["游戏正在模拟中,请勿重复请求!"];
|
||||||
|
|
||||||
|
List<string> result = [];
|
||||||
|
Msg = "";
|
||||||
|
|
||||||
|
IsRuning = true;
|
||||||
|
|
||||||
|
// M = 0, W = 7, P1 = 1, P3 = 1
|
||||||
|
// M = 1, W = 6, P1 = 2, P3 = 0
|
||||||
|
// M = 2, W = 4, P1 = 0, P3 = 2
|
||||||
|
// M = 2, W = 5, P1 = 0, P3 = 0
|
||||||
|
// M = 3, W = 3, P1 = 1, P3 = 1
|
||||||
|
// M = 4, W = 2, P1 = 2, P3 = 0
|
||||||
|
// M = 5, W = 0, P1 = 0, P3 = 2
|
||||||
|
// M = 5, W = 1, P1 = 0, P3 = 0
|
||||||
|
|
||||||
|
List<Character> list = new(FunGameService.Characters);
|
||||||
|
|
||||||
|
if (list.Count > 11)
|
||||||
|
{
|
||||||
|
if (PrintOut) Console.WriteLine();
|
||||||
|
if (PrintOut) Console.WriteLine("Start!!!");
|
||||||
|
if (PrintOut) Console.WriteLine();
|
||||||
|
|
||||||
|
Character character1 = list[0].Copy();
|
||||||
|
Character character2 = list[1].Copy();
|
||||||
|
Character character3 = list[2].Copy();
|
||||||
|
Character character4 = list[3].Copy();
|
||||||
|
Character character5 = list[4].Copy();
|
||||||
|
Character character6 = list[5].Copy();
|
||||||
|
Character character7 = list[6].Copy();
|
||||||
|
Character character8 = list[7].Copy();
|
||||||
|
Character character9 = list[8].Copy();
|
||||||
|
Character character10 = list[9].Copy();
|
||||||
|
Character character11 = list[10].Copy();
|
||||||
|
Character character12 = list[11].Copy();
|
||||||
|
|
||||||
|
List<Character> characters = [
|
||||||
|
character1, character2, character3, character4,
|
||||||
|
character5, character6, character7, character8,
|
||||||
|
character9, character10, character11, character12
|
||||||
|
];
|
||||||
|
|
||||||
|
int clevel = 60;
|
||||||
|
int slevel = 6;
|
||||||
|
int mlevel = 8;
|
||||||
|
|
||||||
|
// 升级和赋能
|
||||||
|
for (int index = 0; index < characters.Count; index++)
|
||||||
|
{
|
||||||
|
Character c = characters[index];
|
||||||
|
c.Level = clevel;
|
||||||
|
c.NormalAttack.Level = mlevel;
|
||||||
|
FunGameService.AddCharacterSkills(c, 1, slevel, slevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建顺序表并排序
|
||||||
|
ActionQueue actionQueue = new(characters, isTeam, WriteLine);
|
||||||
|
if (isTeam)
|
||||||
|
{
|
||||||
|
actionQueue.MaxRespawnTimes = -1;
|
||||||
|
actionQueue.MaxScoreToWin = 30;
|
||||||
|
}
|
||||||
|
if (PrintOut) Console.WriteLine();
|
||||||
|
|
||||||
|
// 总游戏时长
|
||||||
|
double totalTime = 0;
|
||||||
|
|
||||||
|
// 开始空投
|
||||||
|
Msg = "";
|
||||||
|
int 发放的卡包品质 = 0;
|
||||||
|
int 发放的武器品质 = 0;
|
||||||
|
int 发放的防具品质 = 0;
|
||||||
|
int 发放的鞋子品质 = 0;
|
||||||
|
int 发放的饰品品质 = 0;
|
||||||
|
WriteLine($"社区送温暖了,现在随机发放空投!!");
|
||||||
|
空投(actionQueue, 发放的卡包品质, 发放的武器品质, 发放的防具品质, 发放的鞋子品质, 发放的饰品品质);
|
||||||
|
WriteLine("");
|
||||||
|
if (isWeb) result.Add("=== 空投 ===\r\n" + Msg);
|
||||||
|
double 下一次空投 = isTeam ? 80 : 40;
|
||||||
|
if (发放的卡包品质 < 4)
|
||||||
|
{
|
||||||
|
发放的卡包品质++;
|
||||||
|
}
|
||||||
|
if (发放的武器品质 < 4)
|
||||||
|
{
|
||||||
|
发放的武器品质++;
|
||||||
|
}
|
||||||
|
if (发放的防具品质 < 1)
|
||||||
|
{
|
||||||
|
发放的防具品质++;
|
||||||
|
}
|
||||||
|
if (发放的鞋子品质 < 1)
|
||||||
|
{
|
||||||
|
发放的鞋子品质++;
|
||||||
|
}
|
||||||
|
if (发放的饰品品质 < 3)
|
||||||
|
{
|
||||||
|
发放的饰品品质++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示角色信息
|
||||||
|
if (PrintOut) characters.ForEach(c => Console.WriteLine(c.GetInfo()));
|
||||||
|
|
||||||
|
// 因赋予了装备,所以清除排序重新排
|
||||||
|
actionQueue.ClearQueue();
|
||||||
|
actionQueue.InitCharacterQueue(characters);
|
||||||
|
if (PrintOut) Console.WriteLine();
|
||||||
|
|
||||||
|
// 团队模式
|
||||||
|
if (isTeam)
|
||||||
|
{
|
||||||
|
Msg = "=== 团队模式随机分组 ===\r\n\r\n";
|
||||||
|
// 打乱角色列表
|
||||||
|
List<Character> shuffledCharacters = [.. characters.OrderBy(c => Random.Shared.Next())];
|
||||||
|
|
||||||
|
// 创建两个团队
|
||||||
|
List<Character> group1 = [];
|
||||||
|
List<Character> group2 = [];
|
||||||
|
|
||||||
|
// 将角色交替分配到两个团队中
|
||||||
|
for (int cid = 0; cid < shuffledCharacters.Count; cid++)
|
||||||
|
{
|
||||||
|
if (cid % 2 == 0)
|
||||||
|
{
|
||||||
|
group1.Add(shuffledCharacters[cid]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
group2.Add(shuffledCharacters[cid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加到团队字典
|
||||||
|
actionQueue.AddTeam("队伍一", group1);
|
||||||
|
actionQueue.AddTeam("队伍二", group2);
|
||||||
|
|
||||||
|
foreach (string team in actionQueue.Teams.Keys)
|
||||||
|
{
|
||||||
|
WriteLine($"团队【{team}】的成员:\r\n{string.Join("\r\n", actionQueue.Teams[team].Members)}\r\n");
|
||||||
|
}
|
||||||
|
result.Add(Msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示初始顺序表
|
||||||
|
actionQueue.DisplayQueue();
|
||||||
|
if (PrintOut) Console.WriteLine();
|
||||||
|
|
||||||
|
// 总回合数
|
||||||
|
int maxRound = isTeam ? 9999 : 999;
|
||||||
|
|
||||||
|
// 随机回合奖励
|
||||||
|
Dictionary<int, List<Skill>> roundRewards = FunGameService.GenerateRoundRewards(maxRound);
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
while (i < maxRound)
|
||||||
|
{
|
||||||
|
Msg = "";
|
||||||
|
if (i == maxRound - 1)
|
||||||
|
{
|
||||||
|
if (isTeam)
|
||||||
|
{
|
||||||
|
WriteLine("两队打到天昏地暗,流局了!!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteLine($"=== 终局审判 ===");
|
||||||
|
Dictionary<Character, double> 他们的血量百分比 = [];
|
||||||
|
foreach (Character c in characters)
|
||||||
|
{
|
||||||
|
他们的血量百分比.TryAdd(c, c.HP / c.MaxHP);
|
||||||
|
}
|
||||||
|
double max = 他们的血量百分比.Values.Max();
|
||||||
|
Character winner = 他们的血量百分比.Keys.Where(c => 他们的血量百分比[c] == max).First();
|
||||||
|
WriteLine("[ " + winner + " ] 成为了天选之人!!");
|
||||||
|
foreach (Character c in characters.Where(c => c != winner && c.HP > 0))
|
||||||
|
{
|
||||||
|
WriteLine("[ " + winner + " ] 对 [ " + c + " ] 造成了 99999999999 点真实伤害。");
|
||||||
|
actionQueue.DeathCalculation(winner, c);
|
||||||
|
}
|
||||||
|
actionQueue.EndGameInfo(winner);
|
||||||
|
result.Add(Msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有角色可以行动
|
||||||
|
Character? characterToAct = actionQueue.NextCharacter();
|
||||||
|
|
||||||
|
// 处理回合
|
||||||
|
if (characterToAct != null)
|
||||||
|
{
|
||||||
|
// 获取回合奖励
|
||||||
|
List<Skill> skillRewards = [];
|
||||||
|
if (roundRewards.TryGetValue(i, out List<Skill>? effectList) && effectList != null)
|
||||||
|
{
|
||||||
|
skillRewards = new(effectList);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteLine($"=== Round {i++} ===");
|
||||||
|
WriteLine("现在是 [ " + characterToAct + (isTeam ? "(" + (actionQueue.GetTeam(characterToAct)?.Name ?? "") + ")" : "") + " ] 的回合!");
|
||||||
|
|
||||||
|
// 实际的回合奖励
|
||||||
|
List<Skill> realSkillRewards = [];
|
||||||
|
if (skillRewards.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (Skill skill in skillRewards)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> effectArgs = [];
|
||||||
|
if (FunGameService.RoundRewards.TryGetValue((EffectID)skill.Id, out Dictionary<string, object>? dict) && dict != null)
|
||||||
|
{
|
||||||
|
effectArgs = new(dict);
|
||||||
|
}
|
||||||
|
Dictionary<string, object> args = new()
|
||||||
|
{
|
||||||
|
{ "skill", skill },
|
||||||
|
{ "values", effectArgs }
|
||||||
|
};
|
||||||
|
skill.GamingQueue = actionQueue;
|
||||||
|
skill.Effects.Add(Factory.OpenFactory.GetInstance<Effect>(skill.Id, "", args));
|
||||||
|
skill.Character = characterToAct;
|
||||||
|
skill.Level = 1;
|
||||||
|
actionQueue.LastRound.RoundRewards.Add(skill);
|
||||||
|
WriteLine($"[ {characterToAct} ] 获得了回合奖励!{skill.Description}".Trim());
|
||||||
|
if (skill.IsActive)
|
||||||
|
{
|
||||||
|
actionQueue.LastRound.Targets.Add(characterToAct);
|
||||||
|
skill.OnSkillCasted(actionQueue, characterToAct, [characterToAct]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
characterToAct.Skills.Add(skill);
|
||||||
|
realSkillRewards.Add(skill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isGameEnd = actionQueue.ProcessTurn(characterToAct);
|
||||||
|
|
||||||
|
if (realSkillRewards.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (Skill skill in realSkillRewards)
|
||||||
|
{
|
||||||
|
foreach (Effect e in skill.Effects)
|
||||||
|
{
|
||||||
|
e.OnEffectLost(characterToAct);
|
||||||
|
characterToAct.Effects.Remove(e);
|
||||||
|
}
|
||||||
|
characterToAct.Skills.Remove(skill);
|
||||||
|
skill.Character = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGameEnd)
|
||||||
|
{
|
||||||
|
result.Add(Msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
actionQueue.DisplayQueue();
|
||||||
|
WriteLine("");
|
||||||
|
}
|
||||||
|
|
||||||
|
string roundMsg = "";
|
||||||
|
if (actionQueue.LastRound.HasKill)
|
||||||
|
{
|
||||||
|
roundMsg = Msg;
|
||||||
|
if (!deathMatchRoundDetail)
|
||||||
|
{
|
||||||
|
roundMsg = actionQueue.LastRound.ToString().Trim() + $"\r\n{(isTeam ? $"比分:{string.Join(" / ", actionQueue.Teams.Values.Select(t => $"{t.Name}({t.Score})"))},击杀来自{actionQueue.GetTeam(actionQueue.LastRound.Actor)}" : "")}\r\n";
|
||||||
|
}
|
||||||
|
Msg = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟时间流逝
|
||||||
|
double timeLapse = actionQueue.TimeLapse();
|
||||||
|
totalTime += timeLapse;
|
||||||
|
下一次空投 -= timeLapse;
|
||||||
|
|
||||||
|
if (roundMsg != "")
|
||||||
|
{
|
||||||
|
if ((isTeam && deathMatchRoundDetail || !isTeam) && isWeb)
|
||||||
|
{
|
||||||
|
roundMsg += "\r\n" + Msg;
|
||||||
|
}
|
||||||
|
result.Add(roundMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (下一次空投 <= 0)
|
||||||
|
{
|
||||||
|
// 空投
|
||||||
|
Msg = "";
|
||||||
|
WriteLine($"社区送温暖了,现在随机发放空投!!");
|
||||||
|
空投(actionQueue, 发放的卡包品质, 发放的武器品质, 发放的防具品质, 发放的鞋子品质, 发放的饰品品质);
|
||||||
|
WriteLine("");
|
||||||
|
if (isWeb) result.Add("=== 空投 ===\r\n" + Msg);
|
||||||
|
下一次空投 = isTeam ? 100 : 40;
|
||||||
|
if (发放的卡包品质 < 4)
|
||||||
|
{
|
||||||
|
发放的卡包品质++;
|
||||||
|
}
|
||||||
|
if (发放的武器品质 < 4)
|
||||||
|
{
|
||||||
|
发放的武器品质++;
|
||||||
|
}
|
||||||
|
if (发放的防具品质 < 1)
|
||||||
|
{
|
||||||
|
发放的防具品质++;
|
||||||
|
}
|
||||||
|
if (发放的鞋子品质 < 1)
|
||||||
|
{
|
||||||
|
发放的鞋子品质++;
|
||||||
|
}
|
||||||
|
if (发放的饰品品质 < 3)
|
||||||
|
{
|
||||||
|
发放的饰品品质++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PrintOut)
|
||||||
|
{
|
||||||
|
Console.WriteLine("--- End ---");
|
||||||
|
Console.WriteLine($"总游戏时长:{totalTime:0.##}");
|
||||||
|
Console.WriteLine("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 赛后统计
|
||||||
|
FunGameService.GetCharacterRating(actionQueue.CharacterStatistics, isTeam, actionQueue.EliminatedTeams);
|
||||||
|
|
||||||
|
// 统计技术得分,评选 MVP
|
||||||
|
Character? mvp = actionQueue.CharacterStatistics.OrderByDescending(d => d.Value.Rating).Select(d => d.Key).FirstOrDefault();
|
||||||
|
StringBuilder mvpBuilder = new();
|
||||||
|
if (mvp != null)
|
||||||
|
{
|
||||||
|
CharacterStatistics stats = actionQueue.CharacterStatistics[mvp];
|
||||||
|
stats.MVPs++;
|
||||||
|
mvpBuilder.AppendLine($"{(isTeam ? "[ " + actionQueue.GetTeamFromEliminated(mvp)?.Name + " ] " : "")}[ {mvp.ToStringWithLevel()} ]");
|
||||||
|
mvpBuilder.AppendLine($"技术得分:{stats.Rating:0.0#} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(actionQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}");
|
||||||
|
mvpBuilder.AppendLine($"存活时长:{stats.LiveTime} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}");
|
||||||
|
mvpBuilder.AppendLine($"总计伤害:{stats.TotalDamage} / 总计物理伤害:{stats.TotalPhysicalDamage} / 总计魔法伤害:{stats.TotalMagicDamage}");
|
||||||
|
mvpBuilder.AppendLine($"总承受伤害:{stats.TotalTakenDamage} / 总承受物理伤害:{stats.TotalTakenPhysicalDamage} / 总承受魔法伤害:{stats.TotalTakenMagicDamage}");
|
||||||
|
mvpBuilder.Append($"每秒伤害:{stats.DamagePerSecond} / 每回合伤害:{stats.DamagePerTurn}");
|
||||||
|
}
|
||||||
|
|
||||||
|
int top = isWeb ? actionQueue.CharacterStatistics.Count : 0; // 回执多少个角色的统计信息
|
||||||
|
int count = 1;
|
||||||
|
if (isWeb)
|
||||||
|
{
|
||||||
|
WriteLine("=== 技术得分排行榜 ==="); // 这是输出在界面上的
|
||||||
|
Msg = $"=== 技术得分排行榜 TOP{top} ===\r\n"; // 这个是下一条给Result回执的标题,覆盖掉上面方法里的赋值了
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StringBuilder ratingBuilder = new();
|
||||||
|
if (isTeam)
|
||||||
|
{
|
||||||
|
ratingBuilder.AppendLine($"=== 赛后数据 ===");
|
||||||
|
foreach (Team team in actionQueue.EliminatedTeams)
|
||||||
|
{
|
||||||
|
ratingBuilder.AppendLine($"☆--- [ {team} ] ---☆");
|
||||||
|
foreach (Character character in actionQueue.CharacterStatistics.Where(d => team.Members.Contains(d.Key))
|
||||||
|
.OrderByDescending(d => d.Value.Rating).Select(d => d.Key))
|
||||||
|
{
|
||||||
|
CharacterStatistics stats = actionQueue.CharacterStatistics[character];
|
||||||
|
ratingBuilder.AppendLine($"[ {stats.Rating:0.0#} ] {character}({stats.Kills} / {stats.Assists} / {stats.Deaths})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteLine("=== 本场比赛最佳角色 ===");
|
||||||
|
Msg = $"=== 本场比赛最佳角色 ===\r\n";
|
||||||
|
WriteLine(mvpBuilder.ToString() + "\r\n\r\n" + ratingBuilder.ToString());
|
||||||
|
|
||||||
|
if (PrintOut)
|
||||||
|
{
|
||||||
|
Console.WriteLine();
|
||||||
|
Console.WriteLine("=== 技术得分排行榜 ===");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTeam)
|
||||||
|
{
|
||||||
|
foreach (Character character in actionQueue.CharacterStatistics.OrderByDescending(d => d.Value.Rating).Select(d => d.Key))
|
||||||
|
{
|
||||||
|
StringBuilder builder = new();
|
||||||
|
CharacterStatistics stats = actionQueue.CharacterStatistics[character];
|
||||||
|
builder.AppendLine($"{(isWeb ? count + "." : ("[ " + actionQueue.GetTeamFromEliminated(character)?.Name + " ]" ?? ""))} [ {character.ToStringWithLevel()} ]");
|
||||||
|
builder.AppendLine($"技术得分:{stats.Rating:0.0#} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(actionQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}");
|
||||||
|
builder.AppendLine($"存活时长:{stats.LiveTime} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}");
|
||||||
|
builder.AppendLine($"总计伤害:{stats.TotalDamage} / 总计物理伤害:{stats.TotalPhysicalDamage} / 总计魔法伤害:{stats.TotalMagicDamage}");
|
||||||
|
builder.AppendLine($"总承受伤害:{stats.TotalTakenDamage} / 总承受物理伤害:{stats.TotalTakenPhysicalDamage} / 总承受魔法伤害:{stats.TotalTakenMagicDamage}");
|
||||||
|
builder.Append($"每秒伤害:{stats.DamagePerSecond} / 每回合伤害:{stats.DamagePerTurn}");
|
||||||
|
if (count++ <= top)
|
||||||
|
{
|
||||||
|
WriteLine(builder.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (PrintOut) Console.WriteLine(builder.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
CharacterStatistics? totalStats = TeamCharacterStatistics.Where(kv => kv.Key.GetName() == character.GetName()).Select(kv => kv.Value).FirstOrDefault();
|
||||||
|
if (totalStats != null)
|
||||||
|
{
|
||||||
|
UpdateStatistics(totalStats, stats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (Character character in actionQueue.CharacterStatistics.OrderByDescending(d => d.Value.Rating).Select(d => d.Key))
|
||||||
|
{
|
||||||
|
StringBuilder builder = new();
|
||||||
|
CharacterStatistics stats = actionQueue.CharacterStatistics[character];
|
||||||
|
builder.AppendLine($"{(isWeb ? count + ". " : "")}[ {character.ToStringWithLevel()} ]");
|
||||||
|
builder.AppendLine($"技术得分:{stats.Rating:0.0#} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(actionQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}");
|
||||||
|
builder.AppendLine($"存活时长:{stats.LiveTime} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}");
|
||||||
|
builder.AppendLine($"总计伤害:{stats.TotalDamage} / 总计物理伤害:{stats.TotalPhysicalDamage} / 总计魔法伤害:{stats.TotalMagicDamage}");
|
||||||
|
builder.AppendLine($"总承受伤害:{stats.TotalTakenDamage} / 总承受物理伤害:{stats.TotalTakenPhysicalDamage} / 总承受魔法伤害:{stats.TotalTakenMagicDamage}");
|
||||||
|
builder.Append($"每秒伤害:{stats.DamagePerSecond} / 每回合伤害:{stats.DamagePerTurn}");
|
||||||
|
if (count++ <= top)
|
||||||
|
{
|
||||||
|
WriteLine(builder.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (PrintOut) Console.WriteLine(builder.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
CharacterStatistics? totalStats = CharacterStatistics.Where(kv => kv.Key.GetName() == character.GetName()).Select(kv => kv.Value).FirstOrDefault();
|
||||||
|
if (totalStats != null)
|
||||||
|
{
|
||||||
|
UpdateStatistics(totalStats, stats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Add(Msg);
|
||||||
|
|
||||||
|
// 显示每个角色的信息
|
||||||
|
if (isWeb)
|
||||||
|
{
|
||||||
|
if (isTeam)
|
||||||
|
{
|
||||||
|
top = 1;
|
||||||
|
for (i = actionQueue.EliminatedTeams.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
Team team = actionQueue.EliminatedTeams[i];
|
||||||
|
string topTeam = "";
|
||||||
|
if (top == 1)
|
||||||
|
{
|
||||||
|
topTeam = "冠军";
|
||||||
|
}
|
||||||
|
if (top == 2)
|
||||||
|
{
|
||||||
|
topTeam = "亚军";
|
||||||
|
}
|
||||||
|
if (top == 3)
|
||||||
|
{
|
||||||
|
topTeam = "季军";
|
||||||
|
}
|
||||||
|
if (top > 3)
|
||||||
|
{
|
||||||
|
topTeam = $"第 {top} 名";
|
||||||
|
}
|
||||||
|
foreach (Character character in team.Members)
|
||||||
|
{
|
||||||
|
result.Add($"== {topTeam}团队 [ {team.Name} ] ==\r\n== 角色:[ {character} ] ==\r\n{character.GetInfo()}");
|
||||||
|
}
|
||||||
|
top++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = actionQueue.Eliminated.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
Character character = actionQueue.Eliminated[i];
|
||||||
|
result.Add($"=== 角色 [ {character} ] ===\r\n{character.GetInfo()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTeam)
|
||||||
|
{
|
||||||
|
lock (TeamStatsConfig)
|
||||||
|
{
|
||||||
|
foreach (Character c in TeamCharacterStatistics.Keys)
|
||||||
|
{
|
||||||
|
TeamStatsConfig.Add(c.ToStringWithOutUser(), TeamCharacterStatistics[c]);
|
||||||
|
}
|
||||||
|
TeamStatsConfig.SaveConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (StatsConfig)
|
||||||
|
{
|
||||||
|
foreach (Character c in CharacterStatistics.Keys)
|
||||||
|
{
|
||||||
|
StatsConfig.Add(c.ToStringWithOutUser(), CharacterStatistics[c]);
|
||||||
|
}
|
||||||
|
StatsConfig.SaveConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IsRuning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
IsRuning = false;
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
return [ex.ToString()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WriteLine(string str)
|
||||||
|
{
|
||||||
|
Msg += str + "\r\n";
|
||||||
|
if (PrintOut) Console.WriteLine(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void 空投(ActionQueue queue, int mQuality, int wQuality, int aQuality, int sQuality, int acQuality)
|
||||||
|
{
|
||||||
|
foreach (Character character in queue.Queue)
|
||||||
|
{
|
||||||
|
Item[] 武器 = FunGameService.Equipment.Where(i => i.Id.ToString().StartsWith("11") && (int)i.QualityType == wQuality).ToArray();
|
||||||
|
Item[] 防具 = FunGameService.Equipment.Where(i => i.Id.ToString().StartsWith("12") && (int)i.QualityType == aQuality).ToArray();
|
||||||
|
Item[] 鞋子 = FunGameService.Equipment.Where(i => i.Id.ToString().StartsWith("13") && (int)i.QualityType == sQuality).ToArray();
|
||||||
|
Item[] 饰品 = FunGameService.Equipment.Where(i => i.Id.ToString().StartsWith("14") && (int)i.QualityType == acQuality).ToArray();
|
||||||
|
Item? a = null, b = null, c = null, d = null;
|
||||||
|
if (武器.Length > 0)
|
||||||
|
{
|
||||||
|
a = 武器[Random.Shared.Next(武器.Length)];
|
||||||
|
}
|
||||||
|
if (防具.Length > 0)
|
||||||
|
{
|
||||||
|
b = 防具[Random.Shared.Next(防具.Length)];
|
||||||
|
}
|
||||||
|
if (鞋子.Length > 0)
|
||||||
|
{
|
||||||
|
c = 鞋子[Random.Shared.Next(鞋子.Length)];
|
||||||
|
}
|
||||||
|
if (饰品.Length > 0)
|
||||||
|
{
|
||||||
|
d = 饰品[Random.Shared.Next(饰品.Length)];
|
||||||
|
}
|
||||||
|
List<Item> 这次发放的空投 = [];
|
||||||
|
if (a != null) 这次发放的空投.Add(a);
|
||||||
|
if (b != null) 这次发放的空投.Add(b);
|
||||||
|
if (c != null) 这次发放的空投.Add(c);
|
||||||
|
if (d != null) 这次发放的空投.Add(d);
|
||||||
|
Item? 魔法卡包 = FunGameService.GenerateMagicCardPack(3, (QualityType)mQuality);
|
||||||
|
if (魔法卡包 != null)
|
||||||
|
{
|
||||||
|
foreach (Skill magic in 魔法卡包.Skills.Magics)
|
||||||
|
{
|
||||||
|
magic.Level = 8;
|
||||||
|
}
|
||||||
|
魔法卡包.SetGamingQueue(queue);
|
||||||
|
queue.Equip(character, 魔法卡包);
|
||||||
|
}
|
||||||
|
foreach (Item item in 这次发放的空投)
|
||||||
|
{
|
||||||
|
Item realItem = item.Copy();
|
||||||
|
realItem.SetGamingQueue(queue);
|
||||||
|
queue.Equip(character, realItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateStatistics(CharacterStatistics totalStats, CharacterStatistics stats)
|
||||||
|
{
|
||||||
|
// 统计此角色的所有数据
|
||||||
|
totalStats.TotalDamage = Calculation.Round2Digits(totalStats.TotalDamage + stats.TotalDamage);
|
||||||
|
totalStats.TotalPhysicalDamage = Calculation.Round2Digits(totalStats.TotalPhysicalDamage + stats.TotalPhysicalDamage);
|
||||||
|
totalStats.TotalMagicDamage = Calculation.Round2Digits(totalStats.TotalMagicDamage + stats.TotalMagicDamage);
|
||||||
|
totalStats.TotalRealDamage = Calculation.Round2Digits(totalStats.TotalRealDamage + stats.TotalRealDamage);
|
||||||
|
totalStats.TotalTakenDamage = Calculation.Round2Digits(totalStats.TotalTakenDamage + stats.TotalTakenDamage);
|
||||||
|
totalStats.TotalTakenPhysicalDamage = Calculation.Round2Digits(totalStats.TotalTakenPhysicalDamage + stats.TotalTakenPhysicalDamage);
|
||||||
|
totalStats.TotalTakenMagicDamage = Calculation.Round2Digits(totalStats.TotalTakenMagicDamage + stats.TotalTakenMagicDamage);
|
||||||
|
totalStats.TotalTakenRealDamage = Calculation.Round2Digits(totalStats.TotalTakenRealDamage + stats.TotalTakenRealDamage);
|
||||||
|
totalStats.LiveRound += stats.LiveRound;
|
||||||
|
totalStats.ActionTurn += stats.ActionTurn;
|
||||||
|
totalStats.LiveTime = Calculation.Round2Digits(totalStats.LiveTime + stats.LiveTime);
|
||||||
|
totalStats.TotalEarnedMoney += stats.TotalEarnedMoney;
|
||||||
|
totalStats.Kills += stats.Kills;
|
||||||
|
totalStats.Deaths += stats.Deaths;
|
||||||
|
totalStats.Assists += stats.Assists;
|
||||||
|
totalStats.FirstKills += stats.FirstKills;
|
||||||
|
totalStats.FirstDeaths += stats.FirstDeaths;
|
||||||
|
totalStats.LastRank = stats.LastRank;
|
||||||
|
double totalRank = totalStats.AvgRank * totalStats.Plays + totalStats.LastRank;
|
||||||
|
double totalRating = totalStats.Rating * totalStats.Plays + stats.Rating;
|
||||||
|
totalStats.Plays += stats.Plays;
|
||||||
|
if (totalStats.Plays != 0) totalStats.AvgRank = Calculation.Round2Digits(totalRank / totalStats.Plays);
|
||||||
|
else totalStats.AvgRank = stats.LastRank;
|
||||||
|
if (totalStats.Plays != 0) totalStats.Rating = Calculation.Round4Digits(totalRating / totalStats.Plays);
|
||||||
|
else totalStats.Rating = stats.Rating;
|
||||||
|
totalStats.Wins += stats.Wins;
|
||||||
|
totalStats.Top3s += stats.Top3s;
|
||||||
|
totalStats.Loses += stats.Loses;
|
||||||
|
totalStats.MVPs += stats.MVPs;
|
||||||
|
if (totalStats.Plays != 0)
|
||||||
|
{
|
||||||
|
totalStats.AvgDamage = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.Plays);
|
||||||
|
totalStats.AvgPhysicalDamage = Calculation.Round2Digits(totalStats.TotalPhysicalDamage / totalStats.Plays);
|
||||||
|
totalStats.AvgMagicDamage = Calculation.Round2Digits(totalStats.TotalMagicDamage / totalStats.Plays);
|
||||||
|
totalStats.AvgRealDamage = Calculation.Round2Digits(totalStats.TotalRealDamage / totalStats.Plays);
|
||||||
|
totalStats.AvgTakenDamage = Calculation.Round2Digits(totalStats.TotalTakenDamage / totalStats.Plays);
|
||||||
|
totalStats.AvgTakenPhysicalDamage = Calculation.Round2Digits(totalStats.TotalTakenPhysicalDamage / totalStats.Plays);
|
||||||
|
totalStats.AvgTakenMagicDamage = Calculation.Round2Digits(totalStats.TotalTakenMagicDamage / totalStats.Plays);
|
||||||
|
totalStats.AvgTakenRealDamage = Calculation.Round2Digits(totalStats.TotalTakenRealDamage / totalStats.Plays);
|
||||||
|
totalStats.AvgLiveRound = totalStats.LiveRound / totalStats.Plays;
|
||||||
|
totalStats.AvgActionTurn = totalStats.ActionTurn / totalStats.Plays;
|
||||||
|
totalStats.AvgLiveTime = Calculation.Round2Digits(totalStats.LiveTime / totalStats.Plays);
|
||||||
|
totalStats.AvgEarnedMoney = totalStats.TotalEarnedMoney / totalStats.Plays;
|
||||||
|
totalStats.Winrates = Calculation.Round4Digits(Convert.ToDouble(totalStats.Wins) / Convert.ToDouble(totalStats.Plays));
|
||||||
|
totalStats.Top3rates = Calculation.Round4Digits(Convert.ToDouble(totalStats.Top3s) / Convert.ToDouble(totalStats.Plays));
|
||||||
|
}
|
||||||
|
if (totalStats.LiveRound != 0) totalStats.DamagePerRound = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.LiveRound);
|
||||||
|
if (totalStats.ActionTurn != 0) totalStats.DamagePerTurn = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.ActionTurn);
|
||||||
|
if (totalStats.LiveTime != 0) totalStats.DamagePerSecond = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.LiveTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -50,8 +50,11 @@ namespace Oshima.FunGame.OshimaModules.Skills
|
|||||||
|
|
||||||
public override void OnTimeElapsed(Character character, double eapsed)
|
public override void OnTimeElapsed(Character character, double eapsed)
|
||||||
{
|
{
|
||||||
累计伤害 += 伤害提升 * eapsed;
|
if (GamingQueue != null)
|
||||||
WriteLine($"[ {character} ] 的 [ {Name} ] 效果增加了,当前总提升:{累计伤害 * 100:0.##}%。");
|
{
|
||||||
|
累计伤害 += 伤害提升 * eapsed;
|
||||||
|
WriteLine($"[ {character} ] 的 [ {Name} ] 效果增加了,当前总提升:{累计伤害 * 100:0.##}%。");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user