Skip to content

Commit

Permalink
Gumpart and cliloc write encryption support (#133)
Browse files Browse the repository at this point in the history
  • Loading branch information
Krubster authored Feb 7, 2025
1 parent 14cc06e commit 6d54779
Show file tree
Hide file tree
Showing 11 changed files with 527 additions and 260 deletions.
17 changes: 11 additions & 6 deletions Ultima/FileIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,12 @@ public bool Valid(int index, out int length, out int extra, out bool patched)
}
}

public enum CompressionFlag
{
None = 0,
Zlib = 1,
Mythic = 3
}


[StructLayout(LayoutKind.Sequential, Pack = 1)]
Expand Down Expand Up @@ -423,7 +429,7 @@ public int Extra2
set => Extra = (int)((Extra & 0xFFFF0000) | (uint)value);
}

public int Flag { get => 0; set { } } // No compression, means that we have only three first fields
public CompressionFlag Flag { get => CompressionFlag.None; set { } } // No compression, means that we have only three first fields
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
Expand Down Expand Up @@ -454,7 +460,7 @@ public int Extra

public int Extra2 { get; set; }

public int Flag { get; set; }
public CompressionFlag Flag { get; set; }
}

// Dumb access to all possible fields of entries
Expand All @@ -466,8 +472,7 @@ public interface IEntry
public int DecompressedLength { get; set; }
public int Extra1 { get; set; }
public int Extra2 { get; set; }
public int Flag { get; set; }
//public IEntry Invalid { get; }
public CompressionFlag Flag { get; set; }
}

public interface IFileAccessor
Expand Down Expand Up @@ -658,7 +663,7 @@ public UopFileAccessor(string path, string uopEntryExtension, int length, int id
Index[idx].Lookup = (int)(offset + 8);
Index[idx].Length = compressedLength - 8;
Index[idx].DecompressedLength = decompressedLength;
Index[idx].Flag = flag;
Index[idx].Flag = (CompressionFlag)flag;
Index[idx].Extra = extra1 << 16 | extra2;
Index[idx].Extra1 = extra1;
Index[idx].Extra2 = extra2;
Expand All @@ -670,7 +675,7 @@ public UopFileAccessor(string path, string uopEntryExtension, int length, int id
Index[idx].Lookup = (int)(offset);
Index[idx].Length = compressedLength;
Index[idx].DecompressedLength = decompressedLength;
Index[idx].Flag = flag;
Index[idx].Flag = (CompressionFlag)flag;
Index[idx].Extra = 0x0FFFFFFF; // we cant read it right now, but -1 and 0 makes this entry invalid
}
}
Expand Down
10 changes: 4 additions & 6 deletions Ultima/Gumps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public static byte[] GetRawGump(int index, out int width, out int height)
stream.Read(buffer, 0, length);
stream.Close();

buffer = BwtDecompress.Decompress(buffer);
buffer = MythicDecompress.Decompress(buffer);
return buffer;
}

Expand Down Expand Up @@ -393,19 +393,17 @@ public static unsafe Bitmap GetGump(int index, out bool patched)
uint height = (uint)entry.Extra2;

// Compressed UOPs
if (entry.Flag >= 1)
if (entry.Flag >= CompressionFlag.Zlib)
{
var result = UopUtils.Decompress(_streamBuffer);
if (result.success is false)
{
return null;
}

if (entry.Flag == 3)
if (entry.Flag == CompressionFlag.Mythic)
{
_streamBuffer = BwtDecompress.Decompress(result.data);
_streamBuffer = MythicDecompress.Decompress(result.data);
}

using (BinaryReader reader = new BinaryReader(new MemoryStream(_streamBuffer)))
{
byte[] extra = reader.ReadBytes(8);
Expand Down
208 changes: 0 additions & 208 deletions Ultima/Helpers/BwtDecompress.cs

This file was deleted.

73 changes: 73 additions & 0 deletions Ultima/Helpers/MoveToFront.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using System.Windows.Documents;

namespace Ultima.Helpers
{
public static class MoveToFrontCoding
{

// complexity : O(256*N) -> O(N)
public static byte[] Encode(byte[] input)
{
Span<byte> symbols = stackalloc byte[256];
byte[] output = new byte[input.Length];

for (int i = 0; i < 256; i++)
symbols[i] = (byte)i;

for (int i = 0; i < input.Length; i++)
{
int ind = MoveToFront(symbols, input[i]);
output[i] = (byte)ind;
}
return output;
}

// complexity : O(256*N) -> O(N)
public static byte[] Decode(byte[] input)
{
Span<byte> symbols = stackalloc byte[256];
byte[] output = new byte[input.Length];

for (int i = 0; i < 256; i++)
symbols[i] = (byte)i;

for (int i = 0; i < input.Length; i++)
{
int ind = (int)input[i];
output[i] = (byte)symbols[ind];
MoveToFront(symbols, ind);
}
return output;
}

// params : array , element to move .
//get the index of the element and move it to the front .
// best case : O(1) , average and worst Case : O(N)
private static int MoveToFront(Span<byte> array, byte element)
{
if (array[0] == element) return 0;
int elementInd = -1;
for (int i = array.Length - 1; i > 0; i--)
{
if (array[i] == element) elementInd = i;
if (elementInd != -1) array[i] = array[i - 1];
}
array[0] = element;
return elementInd;
}

// params : array ,index of the element .
// move element to the front .
// complexity : O(elementInd) .
// best case : O(1) , worst case : O(N)
private static void MoveToFront(Span<byte> array, int elementInd)
{
byte element = (byte)array[elementInd];
for (int i = elementInd; i > 0; i--)
array[i] = array[i - 1];
array[0] = element;
}

}
}
Loading

0 comments on commit 6d54779

Please # to comment.