using Supercell.GUT.Titan.Math; using System.Runtime.CompilerServices; namespace Supercell.GUT.Titan.Encoding; public class ChecksumEncoder { private int _checksum; private int _snapshotChecksum; public ChecksumEncoder() { IsChecksumEnabled = true; } public virtual bool IsCheckSumOnlyMode => true; public virtual ChecksumEncoder WriteBoolean(bool value) => UpdateCheckSum(value ? 13 : 7); public virtual ChecksumEncoder WriteByte(byte value) => UpdateCheckSum(value + 11); public virtual ChecksumEncoder WriteShort(short value) => UpdateCheckSum(value + 19); public virtual ChecksumEncoder WriteInt(int value) => UpdateCheckSum(value + 9); public virtual void WriteLong(LogicLong value) => value.Encode(this); public virtual ChecksumEncoder WriteString(string? value) => UpdateCheckSum(value != null ? value.Length + 28 : 27); public virtual ChecksumEncoder WriteBytes(ReadOnlySpan value) => UpdateCheckSum(value.Length + 28); public bool IsChecksumEnabled { get; private set; } public int CheckSum => IsChecksumEnabled ? _checksum : _snapshotChecksum; public ChecksumEncoder EnableCheckSum(bool enable) { if (!IsChecksumEnabled && enable) { _checksum = _snapshotChecksum; } else { _snapshotChecksum = _checksum; } IsChecksumEnabled = enable; return this; } public ChecksumEncoder ResetCheckSum() { _checksum = 0; return this; } public override bool Equals(object? obj) { ChecksumEncoder? otherEncoder = obj as ChecksumEncoder; return otherEncoder?.CheckSum == CheckSum; } public override int GetHashCode() { // original: Debugger::error("ChecksumEncoder hashCode not designed"); return CheckSum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ChecksumEncoder UpdateCheckSum(int value) { _checksum = value + Ror4(_checksum, 31); return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int Ror4(int v, int c) => v >> c | v << 32 - c; }