70 lines
3.9 KiB
C#
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");
|
|
}
|
|
}
|