64 lines
2.1 KiB
C#
64 lines
2.1 KiB
C#
|
|
namespace AnsonBot.Core;
|
||
|
|
|
||
|
|
/// <summary>A player as reported by Palworld's ShowPlayers command.</summary>
|
||
|
|
public record PalworldPlayer(string Name, string PlayerUid, string SteamId)
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Stable key for tracking. Prefers SteamId, falls back to PlayerUid, then
|
||
|
|
/// name. Palworld sometimes reports "00000000" for a uid mid-connection.
|
||
|
|
/// </summary>
|
||
|
|
public string Id =>
|
||
|
|
IsUsable(SteamId) ? SteamId :
|
||
|
|
IsUsable(PlayerUid) ? PlayerUid :
|
||
|
|
Name;
|
||
|
|
|
||
|
|
private static bool IsUsable(string value) =>
|
||
|
|
!string.IsNullOrWhiteSpace(value) && value.Trim('0').Length > 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static class ShowPlayersParser
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Parses ShowPlayers output, which looks like:
|
||
|
|
/// name,playeruid,steamid
|
||
|
|
/// Sam,1234567890,76561198000000000
|
||
|
|
/// Malformed or incomplete rows are skipped rather than throwing, because a
|
||
|
|
/// single bad row shouldn't take down the polling loop.
|
||
|
|
/// </summary>
|
||
|
|
public static IReadOnlyList<PalworldPlayer> Parse(string raw)
|
||
|
|
{
|
||
|
|
if (string.IsNullOrWhiteSpace(raw))
|
||
|
|
return Array.Empty<PalworldPlayer>();
|
||
|
|
|
||
|
|
var players = new List<PalworldPlayer>();
|
||
|
|
|
||
|
|
var lines = raw.Split('\n', StringSplitOptions.RemoveEmptyEntries)
|
||
|
|
.Select(l => l.Trim('\r', ' '))
|
||
|
|
.Where(l => l.Length > 0);
|
||
|
|
|
||
|
|
foreach (var line in lines)
|
||
|
|
{
|
||
|
|
// Skip the header wherever it appears; rcon-cli sometimes echoes it.
|
||
|
|
if (line.StartsWith("name,", StringComparison.OrdinalIgnoreCase))
|
||
|
|
continue;
|
||
|
|
|
||
|
|
// Names may contain commas, so split from the right: the last two
|
||
|
|
// fields are uid and steamid, everything before is the name.
|
||
|
|
var parts = line.Split(',');
|
||
|
|
if (parts.Length < 3)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
var steamId = parts[^1].Trim();
|
||
|
|
var uid = parts[^2].Trim();
|
||
|
|
var name = string.Join(',', parts[..^2]).Trim();
|
||
|
|
|
||
|
|
if (string.IsNullOrWhiteSpace(name))
|
||
|
|
continue;
|
||
|
|
|
||
|
|
players.Add(new PalworldPlayer(name, uid, steamId));
|
||
|
|
}
|
||
|
|
|
||
|
|
return players;
|
||
|
|
}
|
||
|
|
}
|