Created
February 21, 2025 17:50
-
-
Save Thundernerd/5c12cdcc8c45aa5b8b07762e6267126f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class LevelHasher | |
{ | |
private const int PresentBlockID = 2264; | |
private static readonly Vector3Comparer _vector3Comparer = new(); | |
private static readonly IntSequenceComparer _intSequenceComparer = new(); | |
private static readonly FloatSequenceComparer _floatSequenceComparer = new(); | |
private static string Hash(ZeepLevel zeepLevel) | |
{ | |
if (zeepLevel == null) | |
{ | |
return null; | |
} | |
StringBuilder inputBuilder = new(); | |
inputBuilder.AppendCLRF(zeepLevel.Skybox.ToString()); | |
inputBuilder.AppendCLRF(zeepLevel.Ground.ToString()); | |
List<ZeepBlock> orderedBlocks = zeepLevel.Blocks | |
.Where(x => x.Id != PresentBlockID) | |
.OrderBy(x => x.Id) | |
.ThenBy(x => x.Position, _vector3Comparer) | |
.ThenBy(x => x.Euler, _vector3Comparer) | |
.ThenBy(x => x.Scale, _vector3Comparer) | |
.ThenBy(x => x.Paints, _intSequenceComparer) | |
.ThenBy(x => x.Options, _floatSequenceComparer) | |
.ToList(); | |
foreach (ZeepBlock block in orderedBlocks) | |
{ | |
inputBuilder.AppendCLRF(block.ToString()); | |
} | |
byte[] hash = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(inputBuilder.ToString())); | |
StringBuilder hashBuilder = new(hash.Length * 2); | |
foreach (byte b in hash) | |
{ | |
hashBuilder.Append(b.ToString("X2")); | |
} | |
return hashBuilder.ToString(); | |
} | |
} | |
internal class Vector3Comparer : IComparer<Vector3> | |
{ | |
public int Compare(Vector3 v1, Vector3 v2) | |
{ | |
int xComparison = v1.x.CompareTo(v2.x); | |
if (xComparison != 0) | |
return xComparison; | |
int yComparison = v1.y.CompareTo(v2.y); | |
if (yComparison != 0) | |
return yComparison; | |
return v1.z.CompareTo(v2.z); | |
} | |
} | |
internal class FloatSequenceComparer : IComparer<List<float>> | |
{ | |
public int Compare(List<float> x, List<float> y) | |
{ | |
if (x == null && y == null) | |
return 0; | |
if (x == null) | |
return -1; | |
if (y == null) | |
return 1; | |
int countComparison = x.Count.CompareTo(y.Count); | |
if (countComparison != 0) | |
return countComparison; | |
for (int i = 0; i < x.Count; i++) | |
{ | |
int elementComparison = x[i].CompareTo(y[i]); | |
if (elementComparison != 0) | |
return elementComparison; | |
} | |
return 0; | |
} | |
} | |
internal class IntSequenceComparer : IComparer<List<int>> | |
{ | |
public int Compare(List<int> x, List<int> y) | |
{ | |
if (x == null && y == null) | |
return 0; | |
if (x == null) | |
return -1; | |
if (y == null) | |
return 1; | |
int countComparison = x.Count.CompareTo(y.Count); | |
if (countComparison != 0) | |
return countComparison; | |
for (int i = 0; i < x.Count; i++) | |
{ | |
int elementComparison = x[i].CompareTo(y[i]); | |
if (elementComparison != 0) | |
return elementComparison; | |
} | |
return 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment