Files
2026-08-17 18:18:13 +08:00

70 lines
3.9 KiB
C#

#nullable enable
using System;
using System.Security.Cryptography;
using System.Text;
namespace ReplacedPerson.Core
{
public static class ReplacedStateHasher
{
public static string Compute(ReplacedMatchState state, Pcg32 random)
{
var text = new StringBuilder(2048);
text.Append(state.Round).Append('|').Append(state.LeadPlayer).Append('|').Append(state.InitiativeRoll)
.Append('|').Append((int)state.Phase).Append('|').Append((int)state.Winner).Append('|')
.Append(state.IsLastStand ? 1 : 0).Append('|').Append(state.LastStandUsed ? 1 : 0).Append('|')
.Append(state.ContentHash).Append('|').Append(random.State).Append('|').Append(random.Increment).Append('\n');
for (var index = 0; index < state.Players.Length; index++)
{
var player = state.Players[index];
text.Append(index).Append('|').Append(player.PlayerId).Append('|').Append(player.Health).Append('|')
.Append(player.Cost).Append('|').Append(player.Defense).Append('|').Append(player.BonusNormalDraw)
.Append('|').Append(player.GuaranteedDodge ? 1 : 0).Append('|').Append(player.SkipNextEndDraw ? 1 : 0)
.Append('|').Append(player.SpentThisRound).Append('|').Append(player.EffectiveEffectsThisRound)
.Append('|').Append(player.DamageThisRound).Append('\n');
AppendList(text, player.NormalDrawPile);
AppendList(text, player.NormalDiscard);
AppendList(text, player.NormalHand);
AppendList(text, player.EndDrawPile);
AppendList(text, player.EndDiscard);
AppendList(text, player.EndHand);
}
for (var i = 0; i < state.LastAcceptedSequence.Length; i++)
text.Append("S|").Append(i).Append('|').Append(state.LastAcceptedSequence[i]).Append('\n');
for (var i = 0; i < state.Submissions.Length; i++)
{
var submission = state.Submissions[i];
text.Append("C|").Append(i).Append('|');
if (submission == null)
{
text.Append("null\n");
continue;
}
text.Append(submission.Pass ? 1 : 0).Append('|').Append(submission.DiscardEndOnPass ? 1 : 0)
.Append('|').Append(submission.RerollSlot).Append('|');
AppendList(text, submission.NormalCardIds);
AppendList(text, submission.EndCardIds);
}
foreach (var resolution in state.LastResolution)
{
text.Append("R|").Append(resolution.SlotIndex).Append('|').Append((int)resolution.PlayerOneType).Append('|')
.Append((int)resolution.PlayerTwoType).Append('|').Append(resolution.PlayerOneRoll).Append('|')
.Append(resolution.PlayerTwoRoll).Append('|').Append(resolution.PlayerOneValue).Append('|')
.Append(resolution.PlayerTwoValue).Append('|').Append(resolution.PlayerOneRerolled ? 1 : 0).Append('|')
.Append(resolution.PlayerTwoRerolled ? 1 : 0).Append('|').Append(resolution.DamageToPlayerOne).Append('|')
.Append(resolution.DamageToPlayerTwo).Append('|').Append(resolution.Summary).Append('\n');
}
using var sha = SHA256.Create();
var bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(text.ToString()));
var result = new StringBuilder(bytes.Length * 2);
foreach (var value in bytes) result.Append(value.ToString("x2"));
return result.ToString();
}
private static void AppendList(StringBuilder target, System.Collections.Generic.IEnumerable<string> values) =>
target.Append('[').Append(string.Join(",", values)).Append("]\n");
}
}