Skip to content

Commit e849f29

Browse files
authored
Merge pull request #4 from Sichii/master
Colorized SPF, comments, ControlFiles
2 parents 7f6275a + 3620ca6 commit e849f29

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+3061
-493
lines changed

DALib/Abstractions/ISavable.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,20 @@
22

33
namespace DALib.Abstractions;
44

5+
/// <summary>
6+
/// Defines the pattern for an object that can be saved to a file or stream
7+
/// </summary>
58
public interface ISavable
69
{
10+
/// <summary>
11+
/// Saves the object to the specified path
12+
/// </summary>
13+
/// <param name="path">The path to save the object to</param>
714
void Save(string path);
815

16+
/// <summary>
17+
/// Writes the object to the specified stream
18+
/// </summary>
19+
/// <param name="stream">The stream to write the object to</param>
920
void Save(Stream stream);
1021
}

DALib/Cryptography/CRC16.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
namespace DALib.Cryptography;
22

3+
/// <summary>
4+
/// Provides methods for calculating 16 bit cyclic redundancy checks
5+
/// </summary>
36
public static class CRC16
47
{
58
private static readonly ushort[] CRC16_TABLE =
6-
{
9+
[
710
0x0000,
811
0x1021,
912
0x2042,
@@ -260,10 +263,20 @@ public static class CRC16
260263
0x3EB2,
261264
0x0ED1,
262265
0x1EF0
263-
};
266+
];
264267

268+
/// <summary>
269+
/// Calculates the 16bit checksum of the specified buffer
270+
/// </summary>
271+
/// <param name="buffer">The buffer to calculate the checksum of</param>
265272
public static ushort Calculate(byte[] buffer) => Calculate(buffer, 0, buffer.Length);
266273

274+
/// <summary>
275+
/// Calculates the 16bit checksum of the specified buffer
276+
/// </summary>
277+
/// <param name="buffer">The buffer to calculate the checksum of</param>
278+
/// <param name="offset">The offset within the buffer to start at</param>
279+
/// <param name="count">The number of bytes within the buffer to calculate for</param>
267280
public static ushort Calculate(byte[] buffer, int offset, int count)
268281
{
269282
ushort result = 0;

DALib/Cryptography/CRC32.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
namespace DALib.Cryptography;
22

3+
/// <summary>
4+
/// Provides methods for calculating 32 bit cyclic redundancy checks
5+
/// </summary>
36
public static class CRC32
47
{
58
private static readonly uint[] CRC32_TABLE =
@@ -262,8 +265,18 @@ public static class CRC32
262265
0x2D02EF8D
263266
};
264267

268+
/// <summary>
269+
/// Calculates the 32bit checksum of the specified buffer
270+
/// </summary>
271+
/// <param name="buffer">The buffer to calculate the checksum of</param>
265272
public static uint Calculate(byte[] buffer) => Calculate(buffer, 0, buffer.Length);
266273

274+
/// <summary>
275+
/// Calculates the 32bit checksum of the specified buffer
276+
/// </summary>
277+
/// <param name="buffer">The buffer to calculate the checksum of</param>
278+
/// <param name="offset">The offset within the buffer to start at</param>
279+
/// <param name="count">The number of bytes within the buffer to calculate for</param>
267280
public static uint Calculate(byte[] buffer, int offset, int count)
268281
{
269282
var result = 0xFFFFFFFF;

DALib/Cryptography/PacketCryptoProvider.cs

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
namespace DALib.Cryptography;
66

7+
/// <summary>
8+
/// Provides cryptographic services for packets.
9+
/// </summary>
710
public class PacketCryptoProvider
811
{
912
private const int MAXIMUM_SEED = 9;
@@ -20,10 +23,16 @@ public class PacketCryptoProvider
2023
private byte[] _keystream1;
2124
private byte[] _keystream2Table;
2225
private uint _randState;
23-
private byte[] _salt;
26+
private byte[] _salt = null!;
2427

2528
private byte _seed;
2629

30+
/// <summary>
31+
/// Gets or sets the Keystream property, which represents the keystream as a string.
32+
/// </summary>
33+
/// <value>The keystream as a string.</value>
34+
/// <exception cref="ArgumentNullException">Thrown if the value is null.</exception>
35+
/// <exception cref="Exception">Thrown if the value length is not equal to KEYSTREAM_LENGTH.</exception>
2736
public string Keystream
2837
{
2938
get => Encoding.ASCII.GetString(_keystream1);
@@ -41,6 +50,15 @@ public string Keystream
4150
}
4251
}
4352

53+
/// <summary>
54+
/// Gets or sets the seed value.
55+
/// </summary>
56+
/// <value>
57+
/// The value of the seed.
58+
/// </value>
59+
/// <remarks>
60+
/// Setting a new seed value will regenerate the salt using the new seed value.
61+
/// </remarks>
4462
public byte Seed
4563
{
4664
get => _seed;
@@ -55,13 +73,24 @@ public byte Seed
5573
}
5674
}
5775

76+
/// <summary>
77+
/// Initializes a new instance of the <see cref="PacketCryptoProvider" /> class.
78+
/// Uses the default seed and keystream values.
79+
/// </summary>
5880
public PacketCryptoProvider()
5981
: this(DEFAULT_SEED, DEFAULT_KEYSTREAM)
6082
{
6183
_keystream1[3] = 0xE5; // The default keystream is supposed to be UrkcnItnI,
6284
_keystream1[7] = 0xA3; // however Kru somehow managed to fuck that up. :-)
6385
}
6486

87+
/// <summary>
88+
/// Represents a packet crypto provider that encrypts and decrypts packets using a seed and a keystream.
89+
/// </summary>
90+
/// <remarks>
91+
/// The PacketCryptoProvider uses a seed value and a keystream to generate a salt and performs packet encryption and
92+
/// decryption operations.
93+
/// </remarks>
6594
public PacketCryptoProvider(byte seed, string keystream)
6695
{
6796
if (seed > MAXIMUM_SEED)
@@ -85,6 +114,16 @@ public PacketCryptoProvider(byte seed, string keystream)
85114
_buffer = new byte[BUFFER_LENGTH];
86115
}
87116

117+
/// <summary>
118+
/// Decrypts client data using the specified parameters.
119+
/// </summary>
120+
/// <param name="data">The byte array containing the encrypted client data.</param>
121+
/// <param name="offset">The starting index within the byte array.</param>
122+
/// <param name="count">The number of bytes to be decrypted.</param>
123+
/// <param name="useKeystream2">Specifies whether to use keystream 2 for decryption.</param>
124+
/// <returns>
125+
/// The decrypted client data as a byte array.
126+
/// </returns>
88127
public byte[] DecryptClientData(
89128
byte[] data,
90129
int offset,
@@ -142,6 +181,14 @@ public byte[] DecryptClientData(
142181
return result;
143182
}
144183

184+
/// <summary>
185+
/// Decrypts server data.
186+
/// </summary>
187+
/// <param name="data">The data to decrypt.</param>
188+
/// <param name="offset">The starting offset in the data.</param>
189+
/// <param name="count">The number of bytes to decrypt.</param>
190+
/// <param name="useKeystream2">Flag to indicate if keystream2 should be used for transformation.</param>
191+
/// <returns>The decrypted server data as a byte array.</returns>
145192
public byte[] DecryptServerData(
146193
byte[] data,
147194
int offset,
@@ -190,6 +237,15 @@ public byte[] DecryptServerData(
190237
return result;
191238
}
192239

240+
/// <summary>
241+
/// Encrypts the provided client data using the specified parameters.
242+
/// </summary>
243+
/// <param name="data">The data to encrypt.</param>
244+
/// <param name="offset">The starting index in the data array from which to begin encryption.</param>
245+
/// <param name="count">The number of bytes to encrypt.</param>
246+
/// <param name="sequence">The sequence value to use during encryption.</param>
247+
/// <param name="useKeystream2">Determines whether to use Keystream2 during encryption.</param>
248+
/// <returns>The encrypted client data.</returns>
193249
public byte[] EncryptClientData(
194250
byte[] data,
195251
int offset,
@@ -260,6 +316,15 @@ public byte[] EncryptClientData(
260316
return result;
261317
}
262318

319+
/// <summary>
320+
/// Encrypts server data using the specified parameters.
321+
/// </summary>
322+
/// <param name="data">The data to be encrypted.</param>
323+
/// <param name="offset">The starting offset within the data array.</param>
324+
/// <param name="count">The number of bytes to be encrypted.</param>
325+
/// <param name="sequence">The sequence number used for encryption.</param>
326+
/// <param name="useKeystream2">Determines whether to use the second keystream for encryption.</param>
327+
/// <returns>The encrypted server data as a byte array.</returns>
263328
public byte[] EncryptServerData(
264329
byte[] data,
265330
int offset,
@@ -325,6 +390,10 @@ private void GenerateKeystream2(ushort a, byte b)
325390
_keystream2[i] = _keystream2Table[(i * (KEYSTREAM_LENGTH * i + b * b) + a) % KEYSTREAM2_TABLE_LENGTH];
326391
}
327392

393+
/// <summary>
394+
/// Generates a keystream table based on the given name.
395+
/// </summary>
396+
/// <param name="name">The name to generate the keystream table from.</param>
328397
public void GenerateKeystream2Table(string name)
329398
{
330399
var table = GetMd5String(GetMd5String(name));
@@ -403,7 +472,9 @@ private string GetMd5String(string value)
403472
var valueBytes = Encoding.ASCII.GetBytes(value);
404473
var hashBytes = _md5.ComputeHash(valueBytes);
405474

406-
return BitConverter.ToString(hashBytes).Replace("-", string.Empty).ToLower();
475+
return BitConverter.ToString(hashBytes)
476+
.Replace("-", string.Empty)
477+
.ToLower();
407478
}
408479

409480
private uint NextRandState(ref uint state)

DALib/DALib.csproj

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3+
<!--suppress MsbuildTargetFrameworkTagInspection -->
34
<TargetFrameworks>net8.0</TargetFrameworks>
45
<PackageId>DALib</PackageId>
56
<PackageVersion>0.1.0</PackageVersion>
@@ -19,13 +20,14 @@
1920
<Description>A library for processing DOOMVAS v1 client data (such as Dark Ages MPF/EPF/SPF/DAT formats)</Description>
2021
<IsPackable>true</IsPackable>
2122
<Nullable>enable</Nullable>
22-
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
23+
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
24+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
2325
</PropertyGroup>
2426
<ItemGroup>
25-
<None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath="" />
27+
<None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath=""/>
2628
</ItemGroup>
2729
<ItemGroup>
28-
<None Include="hybrasyl-512x512.png" Pack="true" PackagePath="" />
30+
<None Include="hybrasyl-512x512.png" Pack="true" PackagePath=""/>
2931
</ItemGroup>
3032
<ItemGroup>
3133
<PackageReference Include="KGySoft.Drawing.SkiaSharp" Version="7.2.0"/>
@@ -36,4 +38,4 @@
3638
<SupportedPlatform Include="macOS"/>
3739
<SupportedPlatform Include="Windows"/>
3840
</ItemGroup>
39-
</Project>
41+
</Project>

DALib/Data/DataArchive.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010

1111
namespace DALib.Data;
1212

13+
/// <summary>
14+
/// Represents a DarkAges data archive that can be used for storing and manipulating data entries.
15+
/// </summary>
1316
public sealed class DataArchive() : KeyedCollection<string, DataArchiveEntry>(StringComparer.OrdinalIgnoreCase), ISavable, IDisposable
1417
{
1518
private bool IsDisposed;
@@ -55,6 +58,12 @@ private DataArchive(Stream stream, bool newFormat = false)
5558
}
5659
}
5760

61+
/// <summary>
62+
/// Returns a collection of data archive entries that match the given pattern and extension.
63+
/// </summary>
64+
/// <param name="pattern">The pattern to match the entry name against.</param>
65+
/// <param name="extension">The extension to match the entry name against.</param>
66+
/// <returns>A collection of <see cref="DataArchiveEntry" /> objects that match the pattern and extension.</returns>
5867
public IEnumerable<DataArchiveEntry> GetEntries(string pattern, string extension)
5968
{
6069
foreach (var entry in this)
@@ -69,6 +78,14 @@ public IEnumerable<DataArchiveEntry> GetEntries(string pattern, string extension
6978
}
7079
}
7180

81+
/// <summary>
82+
/// Retrieves all entries with a specified extension.
83+
/// </summary>
84+
/// <param name="extension">The extension to filter the entries with.</param>
85+
/// <returns>
86+
/// An <see cref="IEnumerable{T}" /> of <see cref="DataArchiveEntry" /> containing all entries with the specified
87+
/// extension.
88+
/// </returns>
7289
public IEnumerable<DataArchiveEntry> GetEntries(string extension)
7390
{
7491
foreach (var entry in this)
@@ -85,6 +102,13 @@ public IEnumerable<DataArchiveEntry> GetEntries(string extension)
85102
protected override string GetKeyForItem(DataArchiveEntry item) => item.EntryName;
86103
#endregion
87104

105+
/// <summary>
106+
/// Patches the DataArchive by appending a new entry that replaces an existing entry with the same name, or adds a new
107+
/// entry if no existing entry has the same name.
108+
/// </summary>
109+
/// <param name="entryName">The name of the entry to be patched.</param>
110+
/// <param name="item">The item to be patched.</param>
111+
/// <exception cref="InvalidOperationException">Thrown if the DataArchive is not in memory.</exception>
88112
public void Patch(string entryName, ISavable item)
89113
{
90114
ThrowIfDisposed();
@@ -116,6 +140,11 @@ public void Patch(string entryName, ISavable item)
116140
}
117141

118142
#region SaveTo
143+
/// <inheritdoc />
144+
/// <exception cref="ObjectDisposedException">Thrown if the object is already disposed.</exception>
145+
/// <exception cref="ArgumentNullException">Thrown if the path is null.</exception>
146+
/// <exception cref="ArgumentException">Thrown if the path is empty or contains invalid characters.</exception>
147+
/// <exception cref="PathTooLongException">Thrown if the path exceeds the maximum length allowed.</exception>
119148
public void Save(string path)
120149
{
121150
ThrowIfDisposed();
@@ -134,6 +163,9 @@ public void Save(string path)
134163
Save(stream);
135164
}
136165

166+
/// <inheritdoc />
167+
/// <exception cref="ObjectDisposedException">Thrown if the object has been disposed.</exception>
168+
/// <exception cref="InvalidOperationException">Thrown if an entry name is too long (must be 13 characters or less).</exception>
137169
public void Save(Stream stream)
138170
{
139171
ThrowIfDisposed();
@@ -182,6 +214,11 @@ public void Save(Stream stream)
182214
}
183215
}
184216

217+
/// <summary>
218+
/// Extracts the contents of the current archive to the specified directory.
219+
/// </summary>
220+
/// <param name="dir">The directory to which the contents will be extracted.</param>
221+
/// <exception cref="InvalidOperationException">Thrown when the archive is already disposed.</exception>
185222
public void ExtractTo(string dir)
186223
{
187224
ThrowIfDisposed();
@@ -199,6 +236,11 @@ public void ExtractTo(string dir)
199236
#endregion
200237

201238
#region LoadFrom
239+
/// <summary>
240+
/// Loads a DataArchive from a directory that contains already extracted entries
241+
/// </summary>
242+
/// <param name="dir">The directory path.</param>
243+
/// <returns>A new DataArchive object.</returns>
202244
public static DataArchive FromDirectory(string dir)
203245
{
204246
//create a new in-memory archive
@@ -241,6 +283,16 @@ public static DataArchive FromDirectory(string dir)
241283
return archive;
242284
}
243285

286+
/// <summary>
287+
/// Loads a DataArchive from the specified path
288+
/// </summary>
289+
/// <param name="path">The path to the file to create the DataArchive from.</param>
290+
/// <param name="cacheArchive">
291+
/// Indicates whether to cache the archive in memory or read from file using pointers. Default
292+
/// is false.
293+
/// </param>
294+
/// <param name="newformat">Indicates whether to use the new format when reading the archive. Default is false.</param>
295+
/// <returns>A new instance of the DataArchive class.</returns>
244296
public static DataArchive FromFile(string path, bool cacheArchive = false, bool newformat = false)
245297
{
246298
//if we don't want to cache the archive

0 commit comments

Comments
 (0)