Fix Chess Rogue Bug & Feature: MuipServer PlayerInformation

- Fix when enter the layer 3's last room, there wont be any select menu
- Add web Handler for getting information
This commit is contained in:
Somebody
2024-07-08 14:15:07 +08:00
parent 5b8c7e227d
commit c7c7a071be
12 changed files with 318 additions and 3 deletions

View File

@@ -8,6 +8,10 @@
<AssemblyName>DanhengCommand</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\GameServer\GameServer.csproj" />

View File

@@ -18,6 +18,7 @@
<PackageReference Include="SQLitePCLRaw.core" Version="2.1.8" />
<PackageReference Include="SQLitePCLRaw.provider.e_sqlite3" Version="2.1.8" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.143" />
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Enums
{
public enum PlayerStatusEnum
{
Offline = 0,
Explore = 1,
Rogue = 2,
Challenge = 3,
Mission = 4
}
}

View File

@@ -214,10 +214,10 @@ namespace EggLink.DanhengServer.Game.ChessRogue
};
RogueCells.Add(item.Key, cell);
if (cell.GetCellId() == CurBoardExcel.MapInfo!.EndGridItemID) // last cell
{
//if (cell.GetCellId() == CurBoardExcel.MapInfo!.EndGridItemID) // last cell
//{
cell.Init();
}
//}
}
}

View File

@@ -32,6 +32,7 @@
<PackageReference Include="SQLitePCLRaw.core" Version="2.1.8" />
<PackageReference Include="SQLitePCLRaw.provider.e_sqlite3" Version="2.1.8" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.143" />
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
</Project>

View File

@@ -14,6 +14,10 @@
<Content Include="Danheng.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Command\Command.csproj" />
<ProjectReference Include="..\Common\Common.csproj" />

View File

@@ -13,6 +13,7 @@ using EggLink.DanhengServer.Command;
using EggLink.DanhengServer.Server.Packet;
using EggLink.DanhengServer.GameServer.Command;
using EggLink.DanhengServer.WebServer.Server;
using EggLink.DanhengServer.Enums;
namespace EggLink.DanhengServer.Program
{
@@ -139,6 +140,40 @@ namespace EggLink.DanhengServer.Program
};
MuipManager.OnExecuteCommand += CommandManager.HandleCommand;
MuipManager.OnGetServerInformation += x =>
{
foreach (var con in Listener.Connections.Values)
{
if (con.Player != null)
{
x.Add(con.Player.Uid, con.Player.Data);
}
}
};
MuipManager.OnGetPlayerStatus += (int uid, out PlayerStatusEnum status) =>
{
foreach (var con in Listener.Connections.Values)
{
if (con.Player != null && con.Player.Uid == uid)
{
if (con.Player.RogueManager?.GetRogueInstance() != null)
{
status = PlayerStatusEnum.Rogue;
}
else if (con.Player.ChallengeManager?.ChallengeInstance != null)
{
status = PlayerStatusEnum.Challenge;
}
else
{
status = PlayerStatusEnum.Explore;
}
return;
}
}
status = PlayerStatusEnum.Offline;
};
// generate the handbook
HandbookGenerator.Generate();

View File

@@ -29,5 +29,19 @@ namespace EggLink.DanhengServer.WebServer.Controllers
var resp = MuipManager.ExecuteCommand(req.SessionId, req.Command, req.TargetUid);
return new JsonResult(resp);
}
[HttpGet("/muip/server_information")]
public IActionResult GetServerInformation([FromBody] ServerInformationRequest req)
{
var resp = MuipManager.GetInformation(req.SessionId);
return new JsonResult(resp);
}
[HttpGet("/muip/player_information")]
public IActionResult GetPlayerInformation([FromBody] PlayerInformationRequest req)
{
var resp = MuipManager.GetPlayerInformation(req.SessionId, req.Uid);
return new JsonResult(resp);
}
}
}

View File

@@ -0,0 +1,13 @@
namespace EggLink.DanhengServer.WebServer.Request
{
public class ServerInformationRequest
{
public string SessionId { get; set; } = "";
}
public class PlayerInformationRequest
{
public string SessionId { get; set; } = "";
public int Uid { get; set; }
}
}

View File

@@ -0,0 +1,59 @@
using EggLink.DanhengServer.Enums;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace EggLink.DanhengServer.WebServer.Response
{
public class ServerInformationResponse(int code, string message, ServerInformationData? data = null) : BaseResponse<ServerInformationData>(code, message, data)
{
}
public class ServerInformationData
{
public List<SimplePlayerInformationData> OnlinePlayers { get; set; } = [];
public long ServerTime { get; set; } = 0;
public float MaxMemory { get; set; } = 0;
public float UsedMemory { get; set; } = 0;
public float ProgramUsedMemory { get; set; } = 0;
}
public class SimplePlayerInformationData
{
public int Uid { get; set; }
public string Name { get; set; } = "";
public int HeadIconId { get; set; }
}
public class PlayerInformationResponse(int code, string message, PlayerInformationData? data = null) : BaseResponse<PlayerInformationData>(code, message, data)
{
}
public class PlayerInformationData
{
// Basic info
public int Uid { get; set; }
public string Name { get; set; } = "";
public string Signature { get; set; } = "";
public int HeadIconId { get; set; }
// Scene info
public int CurPlaneId { get; set; }
public int CurFloorId { get; set; }
// Player info
[JsonConverter(typeof(StringEnumConverter))]
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
public PlayerStatusEnum PlayerStatus { get; set; } = PlayerStatusEnum.Explore;
public int Stamina { get; set; } = 0;
public int RecoveryStamina { get; set; } = 0;
public List<int> AssistAvatarList { get; set; } = [];
public List<int> DisplayAvatarList { get; set; } = [];
// Mission info
public List<int> FinishedMainMissionIdList { get; set; } = [];
public List<int> FinishedSubMissionIdList { get; set; } = [];
public List<int> AcceptedMainMissionIdList { get; set; } = [];
public List<int> AcceptedSubMissionIdList { get; set; } = [];
}
}

View File

@@ -7,6 +7,14 @@ using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.X509;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using EggLink.DanhengServer.Database.Player;
using EggLink.DanhengServer.Database;
using EggLink.DanhengServer.Database.Avatar;
using EggLink.DanhengServer.Database.Mission;
using EggLink.DanhengServer.Enums;
using Spectre.Console;
namespace EggLink.DanhengServer.WebServer.Server
{
@@ -14,6 +22,10 @@ namespace EggLink.DanhengServer.WebServer.Server
{
public delegate void ExecuteCommandDelegate(string message, MuipCommandSender sender);
public static event ExecuteCommandDelegate? OnExecuteCommand;
public delegate void ServerInformationDelegate(Dictionary<int, PlayerData> resultData);
public static event ServerInformationDelegate? OnGetServerInformation;
public delegate void GetPlayerStatusDelegate(int uid, out PlayerStatusEnum status);
public static event GetPlayerStatusDelegate? OnGetPlayerStatus;
public static string RsaPublicKey { get; private set; } = "";
public static string RsaPrivateKey { get; private set; } = "";
@@ -113,6 +125,108 @@ namespace EggLink.DanhengServer.WebServer.Server
return new(2, "Session not found!");
}
public static ServerInformationResponse GetInformation(string sessionId)
{
if (Sessions.TryGetValue(sessionId, out MuipSession? value))
{
var session = value;
if (session.ExpireTimeStamp < DateTime.Now.ToUnixSec())
{
Sessions.Remove(sessionId);
return new(1, "Session has expired!", null);
}
Process currentProcess = Process.GetCurrentProcess();
long currentProcessMemory = currentProcess.WorkingSet64;
// get system info
var totalMemory = -1f;
var availableMemory = -1f;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
totalMemory = GetTotalMemoryWindows();
availableMemory = GetAvailableMemoryWindows();
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
totalMemory = GetTotalMemoryLinux();
availableMemory = GetAvailableMemoryLinux();
}
var result = new Dictionary<int, PlayerData>();
var sync = Task.Run(() => OnGetServerInformation?.Invoke(result));
sync.Wait();
return new(0, "Success", new()
{
ServerTime = DateTime.Now.ToUnixSec(),
MaxMemory = totalMemory,
ProgramUsedMemory = currentProcessMemory / 1024 / 1024,
UsedMemory = totalMemory - availableMemory,
OnlinePlayers = result.Values.Select(x => new SimplePlayerInformationData()
{
Name = x.Name ?? "",
HeadIconId = x.HeadIcon,
Uid = x.Uid
}).ToList(),
});
}
return new(2, "Session not found!", null);
}
public static PlayerInformationResponse GetPlayerInformation(string sessionId, int uid)
{
if (Sessions.TryGetValue(sessionId, out MuipSession? value))
{
var session = value;
if (session.ExpireTimeStamp < DateTime.Now.ToUnixSec())
{
Sessions.Remove(sessionId);
return new(1, "Session has expired!", null);
}
var result = new Dictionary<int, PlayerData>();
var sync = Task.Run(() => OnGetServerInformation?.Invoke(result));
sync.Wait();
result.TryGetValue(uid, out var player);
if (player == null) return new(2, "Player not exist or is offline!", null);
var status = PlayerStatusEnum.Offline;
var statusSync = Task.Run(() => OnGetPlayerStatus?.Invoke(player.Uid, out status));
statusSync.Wait();
var avatarData = DatabaseHelper.Instance!.GetInstance<AvatarData>(player.Uid)!;
var missionData = DatabaseHelper.Instance!.GetInstance<MissionData>(player.Uid)!;
return new(0, "Success", new()
{
Uid = player.Uid,
Name = player.Name ?? "",
Signature = player.Signature ?? "",
Stamina = player.Stamina,
RecoveryStamina = (int)player.StaminaReserve,
HeadIconId = player.HeadIcon,
CurFloorId = player.FloorId,
CurPlaneId = player.PlaneId,
AssistAvatarList = avatarData.AssistAvatars,
DisplayAvatarList = avatarData.DisplayAvatars,
AcceptedSubMissionIdList = missionData.RunningSubMissionIds,
AcceptedMainMissionIdList = missionData.RunningMainMissionIds,
FinishedMainMissionIdList = missionData.FinishedMainMissionIds,
FinishedSubMissionIdList = missionData.FinishedSubMissionIds,
PlayerStatus = status
});
}
return new(3, "Session not found!", null);
}
#region Tools
/// <summary>
/// get rsa key pair
/// </summary>
@@ -167,5 +281,57 @@ namespace EggLink.DanhengServer.WebServer.Server
return result;
}
public static float GetTotalMemoryWindows()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem");
foreach (var obj in searcher.Get())
{
var memory = Convert.ToUInt64(obj["TotalPhysicalMemory"]);
return memory / 1024 / 1024;
}
}
return 0;
}
public static float GetAvailableMemoryWindows()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var pc = new PerformanceCounter("Memory", "Available MBytes");
return pc.NextValue();
}
return 0;
}
public static float GetTotalMemoryLinux()
{
string[] lines = File.ReadAllLines("/proc/meminfo");
foreach (string line in lines)
{
if (line.StartsWith("MemTotal"))
{
return float.Parse(line.Split(':')[1].Trim().Split(' ')[0]) / 1024;
}
}
return 0;
}
public static float GetAvailableMemoryLinux()
{
string[] lines = File.ReadAllLines("/proc/meminfo");
foreach (string line in lines)
{
if (line.StartsWith("MemAvailable"))
{
return float.Parse(line.Split(':')[1].Trim().Split(' ')[0]) / 1024;
}
}
return 0;
}
#endregion
}
}

View File

@@ -19,6 +19,7 @@
<PackageReference Include="SQLitePCLRaw.provider.e_sqlite3" Version="2.1.8" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.143" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageReference Include="System.Management" Version="8.0.0" />
<ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>