Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ protected HashSet<MongoId> GetCompatibleCartridgesFromMagazineTemplate(TemplateI
}

var magazineTemplate = itemHelper.GetItem(
magazineSlot.Properties?.Filters.FirstOrDefault()?.Filter?.FirstOrDefault() ?? new MongoId(null)
magazineSlot.Properties?.Filters.FirstOrDefault()?.Filter?.FirstOrDefault() ?? MongoId.Empty()
);
if (!magazineTemplate.Key)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ BotGeneratorHelper botGeneratorHelper
{
var firstSlotAmmoTpl =
magTemplate.Properties?.Cartridges?.FirstOrDefault()?.Properties?.Filters?.First().Filter?.FirstOrDefault()
?? new MongoId(null);
?? MongoId.Empty();
var ammoMaxStackSize = itemHelper.GetItem(firstSlotAmmoTpl).Value?.Properties?.StackMaxSize ?? 1;
chamberBulletCount =
ammoMaxStackSize == 1
Expand Down
47 changes: 44 additions & 3 deletions Libraries/SPTarkov.Server.Core/Models/Common/MongoId.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Buffers.Binary;
using System.Security.Cryptography;
using System.Text;
using SPTarkov.Server.Core.Extensions;

namespace SPTarkov.Server.Core.Models.Common;
Expand Down Expand Up @@ -78,17 +79,20 @@ public MongoId()
_pidAndIncrement = BitConverter.ToInt32(bytes[8..]);
}

public MongoId(string? hex)
public MongoId(ReadOnlySpan<char> hex)
{
if (string.IsNullOrEmpty(hex) || hex == "000000000000000000000000")
if (hex.IsEmpty)
{
this = default;
return;
}

if (hex.Length != 24)
{
throw new ArgumentException("ObjectId must be a 24-character hex string.", hex);
throw new ArgumentException(
$"ObjectId must be a 24-character hex string, but got \"{hex}\" (length {hex.Length}).",
nameof(hex)
);
}

Span<byte> bytes = stackalloc byte[12];
Expand All @@ -109,6 +113,43 @@ public MongoId(string? hex)
_pidAndIncrement = BitConverter.ToInt32(bytes[8..]);
}

public MongoId(ReadOnlySpan<byte> hex)
{
if (hex.IsEmpty)
{
this = default;
return;
}

if (hex.Length != 24)
{
throw new ArgumentException(
$"ObjectId must be a 24-character hex string, but got \"{Encoding.UTF8.GetString(hex)}\" (length {hex.Length}).",
nameof(hex)
);
}

Span<byte> bytes = stackalloc byte[12];
for (var i = 0; i < 12; i++)
{
var hi = HexCharToValue((char)hex[2 * i]);
var lo = HexCharToValue((char)hex[(2 * i) + 1]);

if (hi == -1 || lo == -1)
{
throw new FormatException("ObjectId contains invalid hex characters.");
}

bytes[i] = (byte)((hi << 4) | lo);
}

_timestampAndMachine = BitConverter.ToInt64(bytes);
_pidAndIncrement = BitConverter.ToInt32(bytes[8..]);
}

public MongoId(string? hex)
: this(hex.AsSpan()) { }

/// <summary>
/// Converts a hexadecimal character into its corresponding integer nibble value.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ protected void AddRevolverCylinderAmmoToLinkedItems(TemplateItem cylinder, HashS
}

// Get the first cylinder filter tpl
var cylinderTpl = cylinderMod.Properties?.Filters?.First().Filter?.FirstOrDefault() ?? new MongoId(null);
var cylinderTpl = cylinderMod.Properties?.Filters?.First().Filter?.FirstOrDefault() ?? MongoId.Empty();

if (!cylinderTpl.IsValidMongoId())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,30 @@ public sealed class StringToMongoIdConverter : JsonConverter<MongoId>
{
public override MongoId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
if (reader.TokenType is not JsonTokenType.String)
{
return new MongoId(reader.GetString());
throw new JsonException($"The JsonTokenType was not of type string, it was: {reader.TokenType}");
}

throw new JsonException($"The JsonTokenType was not of type string, it was: {reader.TokenType}");
return Read(ref reader);
}

// Deserialize MongoId as a dictionary key
public override MongoId ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return Read(ref reader);
}

private static MongoId Read(ref Utf8JsonReader reader)
{
if (!reader.HasValueSequence && !reader.ValueIsEscaped)
{
return new MongoId(reader.ValueSpan);
}

Span<char> buffer = stackalloc char[24];
var written = reader.CopyString(buffer);
return new MongoId(buffer[..written]);
}

public override void Write(Utf8JsonWriter writer, MongoId mongoId, JsonSerializerOptions options)
Expand All @@ -29,12 +47,6 @@ public override void Write(Utf8JsonWriter writer, MongoId mongoId, JsonSerialize
}
}

// Deserialize MongoId as a dictionary key
public override MongoId ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new MongoId(reader.GetString());
}

// Serialize MongoId as a dictionary key
public override void WriteAsPropertyName(Utf8JsonWriter writer, MongoId value, JsonSerializerOptions options)
{
Expand Down
2 changes: 1 addition & 1 deletion Testing/UnitTests/Tests/MongoIDTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void GenerateTest()
public void Constructor_EmptyAndNull_ReturnsDefaultInstance()
{
// Arrange & Act
var fromNull = new MongoId(null);
var fromNull = MongoId.Empty();
var fromEmpty = new MongoId(string.Empty);
var fromZeroes = new MongoId(ZeroHexZeroHex);
var defaultInstance = default(MongoId);
Expand Down
Loading