Skip to content

Commit f31ba9f

Browse files
Fix RLE Compression
1 parent a741335 commit f31ba9f

File tree

8 files changed

+157
-87
lines changed

8 files changed

+157
-87
lines changed

.github/workflows/codeql.yml.disabled

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ jobs:
6969
shell: pwsh
7070
run: |
7171
dotnet restore .\src
72-
dotnet build .\src\TEdit.sln /p:EnableWindowsTargeting=true /p:Configuration=Release
72+
dotnet build .\src\TEdit.slnx /p:EnableWindowsTargeting=true /p:Configuration=Release
7373

7474
# ℹ️ Command-line programs to run using the OS shell.
7575
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

.github/workflows/dotnet-desktop.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ jobs:
3131
shell: pwsh
3232
run: |
3333
dotnet restore .\src
34-
dotnet build .\src\TEdit.sln /p:EnableWindowsTargeting=true /p:Configuration=Release
34+
dotnet build .\src\TEdit.slnx /p:EnableWindowsTargeting=true /p:Configuration=Release

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,5 @@ build/
5353
/publish/
5454
/publish-avalonia/
5555
.idea/
56+
nul
57+
.claude

src/TEdit.Terraria/Tile.cs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
using System;
2+
using System.Collections.Generic;
23
using TEdit.Configuration;
34
using TEdit.Geometry;
45

56
namespace TEdit.Terraria;
67

7-
public class Tile
8+
public class Tile : IEquatable<Tile>
89
{
910
public static readonly Tile Empty = new Tile();
1011

@@ -62,6 +63,75 @@ public object Clone()
6263
return MemberwiseClone();
6364
}
6465

66+
public override bool Equals(object obj)
67+
{
68+
return Equals(obj as Tile);
69+
}
70+
71+
/// <summary>
72+
/// Compares serialized tile properties. Ignores [NonSerialized] cache fields.
73+
/// </summary>
74+
public bool Equals(Tile other)
75+
{
76+
return other is not null &&
77+
IsActive == other.IsActive &&
78+
Type == other.Type &&
79+
U == other.U &&
80+
V == other.V &&
81+
TileColor == other.TileColor &&
82+
Wall == other.Wall &&
83+
WallColor == other.WallColor &&
84+
LiquidAmount == other.LiquidAmount &&
85+
LiquidType == other.LiquidType &&
86+
WireRed == other.WireRed &&
87+
WireGreen == other.WireGreen &&
88+
WireBlue == other.WireBlue &&
89+
WireYellow == other.WireYellow &&
90+
BrickStyle == other.BrickStyle &&
91+
Actuator == other.Actuator &&
92+
InActive == other.InActive &&
93+
InvisibleBlock == other.InvisibleBlock &&
94+
InvisibleWall == other.InvisibleWall &&
95+
FullBrightBlock == other.FullBrightBlock &&
96+
FullBrightWall == other.FullBrightWall;
97+
}
98+
99+
public override int GetHashCode()
100+
{
101+
int hashCode = -1661845228;
102+
hashCode = hashCode * -1521134295 + IsActive.GetHashCode();
103+
hashCode = hashCode * -1521134295 + Type.GetHashCode();
104+
hashCode = hashCode * -1521134295 + U.GetHashCode();
105+
hashCode = hashCode * -1521134295 + V.GetHashCode();
106+
hashCode = hashCode * -1521134295 + TileColor.GetHashCode();
107+
hashCode = hashCode * -1521134295 + Wall.GetHashCode();
108+
hashCode = hashCode * -1521134295 + WallColor.GetHashCode();
109+
hashCode = hashCode * -1521134295 + LiquidAmount.GetHashCode();
110+
hashCode = hashCode * -1521134295 + LiquidType.GetHashCode();
111+
hashCode = hashCode * -1521134295 + WireRed.GetHashCode();
112+
hashCode = hashCode * -1521134295 + WireGreen.GetHashCode();
113+
hashCode = hashCode * -1521134295 + WireBlue.GetHashCode();
114+
hashCode = hashCode * -1521134295 + WireYellow.GetHashCode();
115+
hashCode = hashCode * -1521134295 + BrickStyle.GetHashCode();
116+
hashCode = hashCode * -1521134295 + Actuator.GetHashCode();
117+
hashCode = hashCode * -1521134295 + InActive.GetHashCode();
118+
hashCode = hashCode * -1521134295 + InvisibleBlock.GetHashCode();
119+
hashCode = hashCode * -1521134295 + InvisibleWall.GetHashCode();
120+
hashCode = hashCode * -1521134295 + FullBrightBlock.GetHashCode();
121+
hashCode = hashCode * -1521134295 + FullBrightWall.GetHashCode();
122+
return hashCode;
123+
}
124+
125+
public static bool operator ==(Tile left, Tile right)
126+
{
127+
return EqualityComparer<Tile>.Default.Equals(left, right);
128+
}
129+
130+
public static bool operator !=(Tile left, Tile right)
131+
{
132+
return !(left == right);
133+
}
134+
65135
// Added legacy enums back
66136
public enum WallType : int
67137
{

src/TEdit.Tests/Terraria/WorldTests.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,4 +296,61 @@ public void SaveWorldV2_144x_Test(string fileName)
296296
// essentially, just a save and load test
297297
var w2 = World.LoadWorld(saveTest);
298298
}
299+
300+
[Theory]
301+
[InlineData(".\\WorldFiles\\v1.4.4.1.wld")]
302+
[InlineData(".\\WorldFiles\\v1.4.4.2.wld")]
303+
[InlineData(".\\WorldFiles\\v1.4.4.3.wld")]
304+
[InlineData(".\\WorldFiles\\v1.4.4.4.wld")]
305+
[InlineData(".\\WorldFiles\\console.wld")]
306+
public void SaveWorld_RLE_Compression_Test(string fileName)
307+
{
308+
var fileInfo = new FileInfo(fileName);
309+
if (fileInfo.Length < 1_000_000)
310+
{
311+
// Skip files < 1MB (likely broken LFS links or stub files)
312+
return;
313+
}
314+
315+
var originalSize = fileInfo.Length;
316+
317+
var (world, errors) = World.LoadWorld(fileName);
318+
var saveTest = fileName + ".rle.test";
319+
World.Save(world, saveTest, incrementRevision: false);
320+
321+
var savedSize = new FileInfo(saveTest).Length;
322+
double sizeRatio = (double)savedSize / originalSize;
323+
324+
// Clean up test file
325+
if (File.Exists(saveTest))
326+
{
327+
File.Delete(saveTest);
328+
}
329+
330+
// Saved file should not be significantly larger (5% tolerance for metadata)
331+
Assert.True(sizeRatio <= 1.05,
332+
$"File grew from {originalSize:N0} to {savedSize:N0} bytes ({sizeRatio:P1}). " +
333+
$"RLE compression may not be working.");
334+
}
335+
336+
[Fact]
337+
public void Tile_Equals_Test()
338+
{
339+
var tile1 = new Tile { IsActive = true, Type = 1, Wall = 5 };
340+
var tile2 = (Tile)tile1.Clone();
341+
342+
// Cloned tiles should be equal
343+
Assert.True(tile1.Equals(tile2));
344+
Assert.True(tile1 == tile2);
345+
Assert.Equal(tile1.GetHashCode(), tile2.GetHashCode());
346+
347+
// Different cache values should not affect comparison
348+
tile2.uvTileCache = 999;
349+
Assert.True(tile1.Equals(tile2));
350+
351+
// Different serialized property should not be equal
352+
tile2.Type = 2;
353+
Assert.False(tile1.Equals(tile2));
354+
Assert.False(tile1 == tile2);
355+
}
299356
}

src/TEdit.sln

Lines changed: 0 additions & 82 deletions
This file was deleted.

src/TEdit.sln.DotSettings

Lines changed: 0 additions & 2 deletions
This file was deleted.

src/TEdit.slnx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Solution>
2+
<Folder Name="/Solution Items/">
3+
<File Path="../.editorconfig" />
4+
<File Path="../build.ps1" />
5+
</Folder>
6+
<Project Path="SettingsFileUpdater/SettingsFileUpdater.csproj">
7+
<Platform Solution="Debug|*" Project="x86" />
8+
<Build Project="false" />
9+
</Project>
10+
<Project Path="TEdit.Common/TEdit.Common.csproj" />
11+
<Project Path="TEdit.Configuration.Tests/TEdit.Configuration.Tests.csproj" />
12+
<Project Path="TEdit.Configuration/TEdit.Configuration.csproj" />
13+
<Project Path="TEdit.Editor/TEdit.Editor.csproj" />
14+
<Project Path="TEdit.Terraria/TEdit.Terraria.csproj" />
15+
<Project Path="TEdit.Tests/TEdit.Tests.csproj" />
16+
<Project Path="TEdit/TEdit.csproj" />
17+
<Project Path="TEdit5/TEdit5.csproj" />
18+
<Properties Name="ExtensibilityGlobals" Scope="PostLoad">
19+
<Property Name="RESX_PrefixTranslations" Value="False" />
20+
<Property Name="RESX_SortFileContentOnSave" Value="True" />
21+
</Properties>
22+
<Properties Name="TestCaseManagementSettings" Scope="PostLoad">
23+
<Property Name="CategoryFile" Value="TEdit.vsmdi" />
24+
</Properties>
25+
</Solution>

0 commit comments

Comments
 (0)