Scoring/Guarded.cs
using System;
namespace SquishyTerry.Scoring;
/// <summary>
/// A number kept obfuscated in memory: stored XOR'd with a fresh random key on every write, plus
/// a checksum. Memory scanners (Cheat Engine and the like) can't find the value by searching for
/// it, and editing the stored bits breaks the checksum, which flags <see cref="Tampered"/>.
/// </summary>
sealed class Guarded
{
static readonly Random Rng = new();
int _key, _masked, _check;
/// <summary>Set once the stored bits have been changed from outside; never clears.</summary>
public bool Tampered { get; private set; }
public Guarded( float value = 0f ) => Value = value;
public float Value
{
get
{
if ( Checksum( _masked, _key ) != _check )
{
Tampered = true;
return 0f;
}
return BitConverter.Int32BitsToSingle( _masked ^ _key );
}
set
{
_key = Rng.Next( int.MinValue, int.MaxValue );
_masked = BitConverter.SingleToInt32Bits( value ) ^ _key;
_check = Checksum( _masked, _key );
}
}
static int Checksum( int masked, int key )
{
unchecked
{
uint h = (uint)masked * 2654435761u;
h ^= (uint)key >> 7;
h *= 2246822519u;
return (int)(h ^ 0x2F6B3A1Du);
}
}
}