~ruther/NosSmooth

e67bb2bac9b1f0338596d5f2dfdf2508e7dee36b — Rutherther 2 years ago 0ad8b9a + df16102
Merge pull request #47 from Rutherther/feat/pass-nullable

Pass CanBeNull to string serializer and converter
34 files changed, 254 insertions(+), 113 deletions(-)

M Core/NosSmooth.Game/PacketHandlers/Relations/FriendInitResponder.cs
M Packets/NosSmooth.PacketSerializer.Abstractions/BaseStringConverter.cs
A Packets/NosSmooth.PacketSerializer.Abstractions/DeserializeOptions.cs
M Packets/NosSmooth.PacketSerializer.Abstractions/IStringConverter.cs
M Packets/NosSmooth.PacketSerializer.Abstractions/IStringSerializer.cs
M Packets/NosSmooth.PacketSerializer.Abstractions/NullableWrapper.cs
M Packets/NosSmooth.PacketSerializer/Converters/Basic/BasicTypeConverter.cs
M Packets/NosSmooth.PacketSerializer/Converters/Basic/BoolStringConverter.cs
M Packets/NosSmooth.PacketSerializer/Converters/Common/NameStringConverter.cs
M Packets/NosSmooth.PacketSerializer/Converters/Common/NullableWrapperConverter.cs
M Packets/NosSmooth.PacketSerializer/Converters/Packets/UpgradeRareSubPacketConverter.cs
M Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/EnumStringConverter.cs
M Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/ListStringConverter.cs
M Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/NullableStringConverter.cs
M Packets/NosSmooth.PacketSerializer/Converters/Special/StringSerializer.cs
M Packets/NosSmooth.PacketSerializer/PacketSerializer.cs
M Packets/NosSmooth.PacketSerializersGenerator/ConverterDeserializationGenerator.cs
M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BasicInlineConverterGenerator.cs
M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BoolInlineConverterGenerator.cs
M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/EnumInlineConverterGenerator.cs
M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/FallbackInlineConverterGenerator.cs
M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/IInlineConverterGenerator.cs
M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/ListInlineConverterGenerator.cs
M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/StringInlineConverterGenerator.cs
M Packets/NosSmooth.PacketSerializersGenerator/InlineTypeConverterGenerator.cs
M Packets/NosSmooth.PacketSerializersGenerator/PacketConverterGenerator.cs
M Packets/NosSmooth.PacketSerializersGenerator/SourceGenerator.cs
M Packets/NosSmooth.Packets/Server/Character/AscrPacket.cs
M Packets/NosSmooth.Packets/Server/Portals/GpPacket.cs
M Packets/NosSmooth.Packets/Server/Relations/FInitSubPacket.cs
M Tests/NosSmooth.Packets.Tests/Converters/Basic/BoolStringConverterTests.cs
M Tests/NosSmooth.Packets.Tests/Converters/Basic/StringConverterTests.cs
M Tests/NosSmooth.Packets.Tests/Converters/Packets/CListPacketConverterTests.cs
M Tests/NosSmooth.Packets.Tests/Converters/Packets/PinitPacketConverterTest.cs
M Core/NosSmooth.Game/PacketHandlers/Relations/FriendInitResponder.cs => Core/NosSmooth.Game/PacketHandlers/Relations/FriendInitResponder.cs +1 -1
@@ 63,7 63,7 @@ public class FriendInitResponder : IPacketResponder<FInfoPacket>, IPacketRespond
        var friends = packet.FriendSubPackets
            .Select
            (
                x => new Friend(x.PlayerId, x.RelationType ?? CharacterRelationType.Blocked)
                x => new Friend(x.PlayerId, x.RelationType)
                {
                    PlayerId = x.PlayerId,
                    CharacterName = x.Name,

M Packets/NosSmooth.PacketSerializer.Abstractions/BaseStringConverter.cs => Packets/NosSmooth.PacketSerializer.Abstractions/BaseStringConverter.cs +3 -3
@@ 19,12 19,12 @@ public abstract class BaseStringConverter<TParseType> : IStringConverter<TParseT
    public abstract Result Serialize(TParseType? obj, PacketStringBuilder builder);

    /// <inheritdoc />
    public abstract Result<TParseType?> Deserialize(ref PacketStringEnumerator stringEnumerator);
    public abstract Result<TParseType?> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options);

    /// <inheritdoc/>
    Result<object?> IStringConverter.Deserialize(ref PacketStringEnumerator stringEnumerator)
    Result<object?> IStringConverter.Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
    {
        var result = Deserialize(ref stringEnumerator);
        var result = Deserialize(ref stringEnumerator, options);
        if (!result.IsSuccess)
        {
            return Result<object?>.FromError(result);

A Packets/NosSmooth.PacketSerializer.Abstractions/DeserializeOptions.cs => Packets/NosSmooth.PacketSerializer.Abstractions/DeserializeOptions.cs +27 -0
@@ 0,0 1,27 @@
//
//  DeserializeOptions.cs
//
//  Copyright (c) František Boháček. All rights reserved.
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Diagnostics.CodeAnalysis;

namespace NosSmooth.PacketSerializer.Abstractions;

/// <summary>
/// Options for deserialization.
/// </summary>
/// <param name="CanBeNull">Whether the argument may be null.</param>
[SuppressMessage
(
    "StyleCop.CSharp.NamingRules",
    "SA1313:Parameter names should begin with lower-case letter",
    Justification = "Fix this."
)]
public record struct DeserializeOptions(bool CanBeNull = false)
{
    /// <summary>
    /// Gets the nullable deserialize options.
    /// </summary>
    public static DeserializeOptions Nullable => new DeserializeOptions(true);
}
\ No newline at end of file

M Packets/NosSmooth.PacketSerializer.Abstractions/IStringConverter.cs => Packets/NosSmooth.PacketSerializer.Abstractions/IStringConverter.cs +4 -2
@@ 17,8 17,9 @@ public interface IStringConverter
    /// Convert the data from the enumerator to the given type.
    /// </summary>
    /// <param name="stringEnumerator">The packet string enumerator with the current position.</param>
    /// <param name="options">The deserialization options.</param>
    /// <returns>The parsed object or an error.</returns>
    public Result<object?> Deserialize(ref PacketStringEnumerator stringEnumerator);
    public Result<object?> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options);

    /// <summary>
    /// Serializes the given object to string by appending to the packet string builder.


@@ 42,8 43,9 @@ public interface IStringConverter<TParseType> : IStringConverter
    /// Convert the data from the enumerator to the given type.
    /// </summary>
    /// <param name="stringEnumerator">The packet string enumerator with the current position.</param>
    /// <param name="options">The deserialization options.</param>
    /// <returns>The parsed object or an error.</returns>
    public new Result<TParseType?> Deserialize(ref PacketStringEnumerator stringEnumerator);
    public new Result<TParseType?> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options);

    /// <summary>
    /// Serializes the given object to string by appending to the packet string builder.

M Packets/NosSmooth.PacketSerializer.Abstractions/IStringSerializer.cs => Packets/NosSmooth.PacketSerializer.Abstractions/IStringSerializer.cs +4 -2
@@ 18,8 18,9 @@ public interface IStringSerializer
    /// </summary>
    /// <param name="parseType">The type of the object to serialize.</param>
    /// <param name="stringEnumerator">The packet string enumerator with the current position.</param>
    /// <param name="options">The deserialization options.</param>
    /// <returns>The parsed object or an error.</returns>
    public Result<object?> Deserialize(Type parseType, ref PacketStringEnumerator stringEnumerator);
    public Result<object?> Deserialize(Type parseType, ref PacketStringEnumerator stringEnumerator, DeserializeOptions options);

    /// <summary>
    /// Serializes the given object to string by appending to the packet string builder.


@@ 35,8 36,9 @@ public interface IStringSerializer
    /// </summary>
    /// <param name="stringEnumerator">The packet string enumerator with the current position.</param>
    /// <typeparam name="TParseType">The type of the object to serialize.</typeparam>
    /// <param name="options">The deserialization options.</param>
    /// <returns>The parsed object or an error.</returns>
    public Result<TParseType?> Deserialize<TParseType>(ref PacketStringEnumerator stringEnumerator);
    public Result<TParseType?> Deserialize<TParseType>(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options);

    /// <summary>
    /// Serializes the given object to string by appending to the packet string builder.

M Packets/NosSmooth.PacketSerializer.Abstractions/NullableWrapper.cs => Packets/NosSmooth.PacketSerializer.Abstractions/NullableWrapper.cs +6 -1
@@ 17,7 17,7 @@ namespace NosSmooth.PacketSerializer.Abstractions;
/// <param name="Value">The value.</param>
/// <typeparam name="T">The underlying type.</typeparam>
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "Fix this, this should not happen.")]
public record NullableWrapper<T>(T? Value)
public record struct NullableWrapper<T>(T? Value)
{
    /// <summary>
    /// Unwrap the underlying value.


@@ 28,4 28,9 @@ public record NullableWrapper<T>(T? Value)
    {
        return wrapper.Value;
    }

    public static implicit operator NullableWrapper<T>(T? value)
    {
        return new NullableWrapper<T>(value);
    }
}
\ No newline at end of file

M Packets/NosSmooth.PacketSerializer/Converters/Basic/BasicTypeConverter.cs => Packets/NosSmooth.PacketSerializer/Converters/Basic/BasicTypeConverter.cs +7 -4
@@ 24,7 24,7 @@ public abstract class BasicTypeConverter<TBasicType> : BaseStringConverter<TBasi
    }

    /// <inheritdoc />
    public override Result<TBasicType?> Deserialize(ref PacketStringEnumerator stringEnumerator)
    public override Result<TBasicType?> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
    {
        var nextTokenResult = stringEnumerator.GetNextToken(out var packetToken);
        if (!nextTokenResult.IsSuccess)


@@ 32,10 32,13 @@ public abstract class BasicTypeConverter<TBasicType> : BaseStringConverter<TBasi
            return Result<TBasicType?>.FromError(nextTokenResult);
        }

        var nullSymbol = GetNullSymbol();
        if (packetToken.Token.Length == nullSymbol.Length && packetToken.Token.StartsWith(nullSymbol))
        if (options.CanBeNull)
        {
            return Result<TBasicType?>.FromSuccess(default);
            var nullSymbol = GetNullSymbol();
            if (packetToken.Token.Length == nullSymbol.Length && packetToken.Token.StartsWith(nullSymbol))
            {
                return Result<TBasicType?>.FromSuccess(default);
            }
        }

        return Deserialize(packetToken.Token);

M Packets/NosSmooth.PacketSerializer/Converters/Basic/BoolStringConverter.cs => Packets/NosSmooth.PacketSerializer/Converters/Basic/BoolStringConverter.cs +4 -9
@@ 4,6 4,7 @@
//  Copyright (c) František Boháček. All rights reserved.
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using NosSmooth.PacketSerializer.Abstractions;
using Remora.Results;



@@ 12,7 13,7 @@ namespace NosSmooth.PacketSerializer.Converters.Basic;
/// <summary>
/// Converter of <see cref="bool"/>.
/// </summary>
public class BoolStringConverter : BaseStringConverter<bool>
public class BoolStringConverter : BasicTypeConverter<bool>
{
    /// <inheritdoc />
    public override Result Serialize(bool obj, PacketStringBuilder builder)


@@ 22,14 23,8 @@ public class BoolStringConverter : BaseStringConverter<bool>
    }

    /// <inheritdoc />
    public override Result<bool> Deserialize(ref PacketStringEnumerator stringEnumerator)
    protected override Result<bool> Deserialize(ReadOnlySpan<char> value)
    {
        var nextTokenResult = stringEnumerator.GetNextToken(out var packetToken);
        if (!nextTokenResult.IsSuccess)
        {
            return Result<bool>.FromError(nextTokenResult);
        }

        return packetToken.Token[0] == '1' ? true : false;
        return value[0] == '1';
    }
}
\ No newline at end of file

M Packets/NosSmooth.PacketSerializer/Converters/Common/NameStringConverter.cs => Packets/NosSmooth.PacketSerializer/Converters/Common/NameStringConverter.cs +6 -3
@@ 29,7 29,7 @@ public class NameStringConverter : BaseStringConverter<NameString>
    }

    /// <inheritdoc />
    public override Result<NameString?> Deserialize(ref PacketStringEnumerator stringEnumerator)
    public override Result<NameString?> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
    {
        var tokenResult = stringEnumerator.GetNextToken(out var packetToken);
        if (!tokenResult.IsSuccess)


@@ 37,9 37,12 @@ public class NameStringConverter : BaseStringConverter<NameString>
            return Result<NameString?>.FromError(tokenResult);
        }

        if (packetToken.Token[0] == '-' && packetToken.Token.Length == 1)
        if (options.CanBeNull)
        {
            return Result<NameString?>.FromSuccess(null);
            if (packetToken.Token[0] == '-' && packetToken.Token.Length == 1)
            {
                return Result<NameString?>.FromSuccess(null);
            }
        }

        return NameString.FromPacket(packetToken.Token.ToString());

M Packets/NosSmooth.PacketSerializer/Converters/Common/NullableWrapperConverter.cs => Packets/NosSmooth.PacketSerializer/Converters/Common/NullableWrapperConverter.cs +8 -8
@@ 28,9 28,9 @@ public class NullableWrapperConverter<T> : BaseStringConverter<NullableWrapper<T
    }

    /// <inheritdoc />
    public override Result Serialize(NullableWrapper<T>? obj, PacketStringBuilder builder)
    public override Result Serialize(NullableWrapper<T> obj, PacketStringBuilder builder)
    {
        if (obj is null || obj.Value is null)
        if (obj.Value is null)
        {
            builder.Append("-1");
        }


@@ 49,29 49,29 @@ public class NullableWrapperConverter<T> : BaseStringConverter<NullableWrapper<T
    }

    /// <inheritdoc />
    public override Result<NullableWrapper<T>?> Deserialize(ref PacketStringEnumerator stringEnumerator)
    public override Result<NullableWrapper<T>> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
    {
        var tokenResult = stringEnumerator.GetNextToken(out var packetToken, false);
        if (!tokenResult.IsSuccess)
        {
            return Result<NullableWrapper<T>?>.FromError(tokenResult);
            return Result<NullableWrapper<T>>.FromError(tokenResult);
        }

        if (packetToken.Token.Length == 2 && packetToken.Token.StartsWith("-1"))
        {
            return Result<NullableWrapper<T>?>.FromSuccess(new NullableWrapper<T>(default));
            return Result<NullableWrapper<T>>.FromSuccess(new NullableWrapper<T>(default));
        }

        var converterResult = _converterRepository.GetTypeConverter<T>();
        if (!converterResult.IsDefined(out var converter))
        {
            return Result<NullableWrapper<T>?>.FromError(converterResult);
            return Result<NullableWrapper<T>>.FromError(converterResult);
        }

        var deserializationResult = converter.Deserialize(ref stringEnumerator);
        var deserializationResult = converter.Deserialize(ref stringEnumerator, new DeserializeOptions(true));
        if (!deserializationResult.IsDefined(out var deserialization))
        {
            return Result<NullableWrapper<T>?>.FromError(deserializationResult);
            return Result<NullableWrapper<T>>.FromError(deserializationResult);
        }

        return new NullableWrapper<T>(deserialization);

M Packets/NosSmooth.PacketSerializer/Converters/Packets/UpgradeRareSubPacketConverter.cs => Packets/NosSmooth.PacketSerializer/Converters/Packets/UpgradeRareSubPacketConverter.cs +1 -1
@@ 31,7 31,7 @@ public class UpgradeRareSubPacketConverter : BaseStringConverter<UpgradeRareSubP
    }

    /// <inheritdoc />
    public override Result<UpgradeRareSubPacket?> Deserialize(ref PacketStringEnumerator stringEnumerator)
    public override Result<UpgradeRareSubPacket?> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
    {
        var tokenResult = stringEnumerator.GetNextToken(out var packetToken);
        if (!tokenResult.IsSuccess)

M Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/EnumStringConverter.cs => Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/EnumStringConverter.cs +2 -2
@@ 35,9 35,9 @@ public class EnumStringConverter<TEnum, TUnderlyingType> : BaseStringConverter<T
    }

    /// <inheritdoc />
    public override Result<TEnum?> Deserialize(ref PacketStringEnumerator stringEnumerator)
    public override Result<TEnum?> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
    {
        var result = _serializer.Deserialize<TUnderlyingType>(ref stringEnumerator);
        var result = _serializer.Deserialize<TUnderlyingType>(ref stringEnumerator, options);
        if (!result.IsSuccess)
        {
            return Result<TEnum?>.FromError(result);

M Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/ListStringConverter.cs => Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/ListStringConverter.cs +2 -2
@@ 57,7 57,7 @@ public class ListStringConverter<TGeneric> : BaseStringConverter<IReadOnlyList<T
    }

    /// <inheritdoc />
    public override Result<IReadOnlyList<TGeneric>?> Deserialize(ref PacketStringEnumerator stringEnumerator)
    public override Result<IReadOnlyList<TGeneric>?> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
    {
        var list = new List<TGeneric>();



@@ 68,7 68,7 @@ public class ListStringConverter<TGeneric> : BaseStringConverter<IReadOnlyList<T
                return new ArgumentInvalidError(nameof(stringEnumerator), "The string enumerator has to have a prepared level for all lists.");
            }

            var result = _serializer.Deserialize<TGeneric>(ref stringEnumerator);
            var result = _serializer.Deserialize<TGeneric>(ref stringEnumerator, default);

            // If we know that we are not on the last token in the item level, just skip to the end of the item.
            // Note that if this is the case, then that means the converter is either corrupted

M Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/NullableStringConverter.cs => Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/NullableStringConverter.cs +12 -6
@@ 43,7 43,7 @@ public class NullableStringConverter<T> : BaseStringConverter<Nullable<T>>
    }

    /// <inheritdoc />
    public override Result<T?> Deserialize(ref PacketStringEnumerator stringEnumerator)
    public override Result<T?> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
    {
        var nextToken = stringEnumerator.GetNextToken(out var packetToken, false);
        if (!nextToken.IsSuccess)


@@ 51,13 51,19 @@ public class NullableStringConverter<T> : BaseStringConverter<Nullable<T>>
            return Result<T?>.FromError(nextToken);
        }

        if (packetToken.Token.Length == 2 && packetToken.Token.StartsWith("-1"))
        {
            stringEnumerator.GetNextToken(out _); // seek.
            return Result<T?>.FromSuccess(null);
        if (options.CanBeNull)
        { // even though this is nullable converter and it could be expected
          // that only nullables will be passed, it's possible that
          // due to easier management, a non nullable entity will be passed
          // here.
            if (packetToken.Token.Length == 2 && packetToken.Token.StartsWith("-1"))
            {
                stringEnumerator.GetNextToken(out _); // seek.
                return Result<T?>.FromSuccess(null);
            }
        }

        var result = _stringSerializer.Deserialize<T>(ref stringEnumerator);
        var result = _stringSerializer.Deserialize<T>(ref stringEnumerator, options);
        if (!result.IsSuccess)
        {
            return Result<T?>.FromError(result);

M Packets/NosSmooth.PacketSerializer/Converters/Special/StringSerializer.cs => Packets/NosSmooth.PacketSerializer/Converters/Special/StringSerializer.cs +4 -4
@@ 25,7 25,7 @@ public class StringSerializer : IStringSerializer
    }

    /// <inheritdoc />
    public Result<object?> Deserialize(Type parseType, ref PacketStringEnumerator stringEnumerator)
    public Result<object?> Deserialize(Type parseType, ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
    {
        var converterResult = _converterRepository.GetTypeConverter(parseType);
        if (!converterResult.IsSuccess)


@@ 33,7 33,7 @@ public class StringSerializer : IStringSerializer
            return Result<object?>.FromError(converterResult);
        }

        var deserializedResult = converterResult.Entity.Deserialize(ref stringEnumerator);
        var deserializedResult = converterResult.Entity.Deserialize(ref stringEnumerator, options);
        if (!deserializedResult.IsSuccess)
        {
            return Result<object?>.FromError(deserializedResult);


@@ 55,7 55,7 @@ public class StringSerializer : IStringSerializer
    }

    /// <inheritdoc />
    public Result<TParseType?> Deserialize<TParseType>(ref PacketStringEnumerator stringEnumerator)
    public Result<TParseType?> Deserialize<TParseType>(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
    {
        var converterResult = _converterRepository.GetTypeConverter<TParseType>();
        if (!converterResult.IsSuccess)


@@ 63,7 63,7 @@ public class StringSerializer : IStringSerializer
            return Result<TParseType?>.FromError(converterResult);
        }

        return converterResult.Entity.Deserialize(ref stringEnumerator);
        return converterResult.Entity.Deserialize(ref stringEnumerator, options);
    }

    /// <inheritdoc />

M Packets/NosSmooth.PacketSerializer/PacketSerializer.cs => Packets/NosSmooth.PacketSerializer/PacketSerializer.cs +1 -1
@@ 73,7 73,7 @@ public class PacketSerializer : IPacketSerializer
        }

        var packetInfo = packetInfoResult.Entity;
        var deserializedResult = packetInfo.PacketConverter.Deserialize(ref packetStringEnumerator);
        var deserializedResult = packetInfo.PacketConverter.Deserialize(ref packetStringEnumerator, default);
        if (!deserializedResult.IsSuccess)
        {
            return Result<IPacket>.FromError(deserializedResult);

M Packets/NosSmooth.PacketSerializersGenerator/ConverterDeserializationGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/ConverterDeserializationGenerator.cs +1 -1
@@ 188,7 188,7 @@ if ({nullableVariableName} is null) {{
    public void DeserializeAndCheck(ParameterInfo parameter, PacketInfo packet, InlineTypeConverterGenerator inlineTypeConverter)
    {
        _textWriter.WriteLine($"var {parameter.GetResultVariableName()} = ");
        inlineTypeConverter.CallDeserialize(_textWriter, packet);
        inlineTypeConverter.CallDeserialize(_textWriter, packet, parameter.Nullable);

        _textWriter.WriteLine($"if (!{parameter.GetResultVariableName()}.IsSuccess)");
        _textWriter.Indent++;

M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BasicInlineConverterGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BasicInlineConverterGenerator.cs +8 -5
@@ 47,7 47,7 @@ public class BasicInlineConverterGenerator : IInlineConverterGenerator
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol, bool nullable)
    {
        var type = typeSyntax is not null
            ? typeSyntax.ToString().TrimEnd('?')


@@ 57,7 57,7 @@ public class BasicInlineConverterGenerator : IInlineConverterGenerator
            throw new Exception("TypeSyntax or TypeSymbol has to be non null.");
        }

        textWriter.WriteLine($"{Constants.HelperClass}.ParseBasic{type}(typeConverter, ref stringEnumerator);");
        textWriter.WriteLine($"{Constants.HelperClass}.ParseBasic{type}(typeConverter, ref stringEnumerator, {nullable.ToString().ToLower()});");
        return null;
    }



@@ 67,7 67,7 @@ public class BasicInlineConverterGenerator : IInlineConverterGenerator
        foreach (var type in HandleTypes)
        {
            textWriter.WriteMultiline($@"
public static Result<{type}?> ParseBasic{type}(IStringConverter typeConverter, ref PacketStringEnumerator stringEnumerator)
public static Result<{type}?> ParseBasic{type}(IStringConverter typeConverter, ref PacketStringEnumerator stringEnumerator, bool nullable)
{{
    var tokenResult = stringEnumerator.GetNextToken(out var packetToken);
    if (!tokenResult.IsSuccess)


@@ 76,9 76,12 @@ public static Result<{type}?> ParseBasic{type}(IStringConverter typeConverter, r
    }}

    var token = packetToken.Token;
    if (token.Length == 2 && token.StartsWith(""-1""))
    if (nullable)
    {{
        return Result<{type}?>.FromSuccess(null);
        if (token.Length == 2 && token.StartsWith(""-1""))
        {{
            return Result<{type}?>.FromSuccess(null);
        }}
    }}

    if (!{type}.TryParse(token, out var val))

M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BoolInlineConverterGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BoolInlineConverterGenerator.cs +8 -5
@@ 42,9 42,9 @@ public class BoolInlineConverterGenerator : IInlineConverterGenerator
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol, bool nullable)
    {
        textWriter.WriteLine($"{Constants.HelperClass}.ParseBool(ref stringEnumerator);");
        textWriter.WriteLine($"{Constants.HelperClass}.ParseBool(ref stringEnumerator, {nullable.ToString().ToLower()});");
        return null;
    }



@@ 52,7 52,7 @@ public class BoolInlineConverterGenerator : IInlineConverterGenerator
    public void GenerateHelperMethods(IndentedTextWriter textWriter)
    {
        textWriter.WriteLine(@"
public static Result<bool?> ParseBool(ref PacketStringEnumerator stringEnumerator)
public static Result<bool?> ParseBool(ref PacketStringEnumerator stringEnumerator, bool nullable)
{{
    var tokenResult = stringEnumerator.GetNextToken(out var packetToken);
    if (!tokenResult.IsSuccess)


@@ 61,9 61,12 @@ public static Result<bool?> ParseBool(ref PacketStringEnumerator stringEnumerato
    }}

    var token = packetToken.Token;
    if (token.Length == 2 && token.StartsWith(""-1""))
    if (nullable)
    {{
        return Result<bool?>.FromSuccess(null);
        if (token.Length == 2 && token.StartsWith(""-1""))
        {{
            return Result<bool?>.FromSuccess(null);
        }}
    }}

    return token[0] == '1' ? true : false;

M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/EnumInlineConverterGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/EnumInlineConverterGenerator.cs +8 -5
@@ 57,7 57,7 @@ public class EnumInlineConverterGenerator : IInlineConverterGenerator
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol, bool nullable)
    {
        if (_enumTypes.All(x => x.ToString() != typeSymbol!.ToString()))
        {


@@ 66,7 66,7 @@ public class EnumInlineConverterGenerator : IInlineConverterGenerator

        textWriter.WriteLine
        (
            $"{Constants.HelperClass}.ParseEnum{typeSymbol?.ToString().TrimEnd('?').Replace('.', '_')}(typeConverter, ref stringEnumerator);"
            $"{Constants.HelperClass}.ParseEnum{typeSymbol?.ToString().TrimEnd('?').Replace('.', '_')}(typeConverter, ref stringEnumerator, {nullable.ToString().ToLower()});"
        );
        return null;
    }


@@ 80,7 80,7 @@ public class EnumInlineConverterGenerator : IInlineConverterGenerator
            textWriter.WriteMultiline
            (
                $@"
public static Result<{type}?> ParseEnum{type.ToString().Replace('.', '_')}(IStringConverter typeConverter, ref PacketStringEnumerator stringEnumerator)
public static Result<{type}?> ParseEnum{type.ToString().Replace('.', '_')}(IStringConverter typeConverter, ref PacketStringEnumerator stringEnumerator, bool nullable)
{{
    var tokenResult = stringEnumerator.GetNextToken(out var packetToken);
    if (!tokenResult.IsSuccess)


@@ 89,9 89,12 @@ public static Result<{type}?> ParseEnum{type.ToString().Replace('.', '_')}(IStri
    }}

    var token = packetToken.Token;
    if (token[0] == '-')
    if (nullable)
    {{
        return Result<{type}?>.FromSuccess(null);
        if (token[0] == '-')
        {{
            return Result<{type}?>.FromSuccess(null);
        }}
    }}

    if (!{underlyingType}.TryParse(token, out var val))

M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/FallbackInlineConverterGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/FallbackInlineConverterGenerator.cs +3 -2
@@ 44,11 44,12 @@ public class FallbackInlineConverterGenerator : IInlineConverterGenerator
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol, bool nullable)
    {
        var options = nullable ? "DeserializeOptions.Nullable" : "default";
        textWriter.WriteLine
        (
            $"_stringSerializer.Deserialize<{(typeSyntax?.ToString() ?? typeSymbol!.ToString()).TrimEnd('?')}?>(ref stringEnumerator);"
            $"_stringSerializer.Deserialize<{(typeSyntax?.ToString() ?? typeSymbol!.ToString()).TrimEnd('?')}?>(ref stringEnumerator, {options});"
        );
        return null;
    }

M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/IInlineConverterGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/IInlineConverterGenerator.cs +2 -1
@@ 41,8 41,9 @@ public interface IInlineConverterGenerator
    /// <param name="textWriter">The text writer to write to.</param>
    /// <param name="typeSyntax">The type syntax.</param>
    /// <param name="typeSymbol">The type symbol.</param>
    /// <param name="nullable">Whether the parameter is nullable.</param>
    /// <returns>An error, if any.</returns>
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol);
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol, bool nullable);

    /// <summary>
    /// Generate helper methods to HelperClass.

M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/ListInlineConverterGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/ListInlineConverterGenerator.cs +15 -8
@@ 76,7 76,7 @@ public class ListInlineConverterGenerator : IInlineConverterGenerator
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol, bool nullable)
    {
        ITypeSymbol genericArgument = ((INamedTypeSymbol)typeSymbol!).TypeArguments[0];
        if (_listTypes.All


@@ 89,25 89,24 @@ public class ListInlineConverterGenerator : IInlineConverterGenerator
        }

        textWriter.WriteLine
            ($"{Constants.HelperClass}.{GetMethodName(genericArgument)}(typeConverter, _stringSerializer, ref stringEnumerator);");
            ($"{Constants.HelperClass}.{GetMethodName(genericArgument, nullable)}(typeConverter, _stringSerializer, ref stringEnumerator);");
        return null;
    }

    private string GetMethodName(ITypeSymbol genericArgumentType)
    private string GetMethodName(ITypeSymbol genericArgumentType, bool nullable)
    {
        return
            $"ParseList{genericArgumentType.ToString().TrimEnd('?').Replace('.', '_').Replace('<', '_').Replace('>', '_')}{((genericArgumentType.IsNullable() ?? false) ? "Nullable" : string.Empty)}";
            $"ParseList{genericArgumentType.ToString().TrimEnd('?').Replace('.', '_').Replace('<', '_').Replace('>', '_')}{((genericArgumentType.IsNullable() ?? false) ? "Nullable" : string.Empty)}{(nullable ? "NullableSupport" : string.Empty)}";
    }

    /// <inheritdoc />
    public void GenerateHelperMethods(IndentedTextWriter textWriter)
    private void GenerateHelperMethods(IndentedTextWriter textWriter, bool nullable)
    {
        foreach (var type in _listTypes)
        {
            textWriter.WriteLine
            (
                @$"
public static Result<IReadOnlyList<{type.GetActualType()}>> {GetMethodName(type)}(IStringConverter typeConverter, IStringSerializer _stringSerializer, ref PacketStringEnumerator stringEnumerator)
public static Result<IReadOnlyList<{type.GetActualType()}>> {GetMethodName(type, nullable)}(IStringConverter typeConverter, IStringSerializer _stringSerializer, ref PacketStringEnumerator stringEnumerator)
{{
    var data = new List<{type.GetActualType()}>();



@@ 120,7 119,7 @@ public static Result<IReadOnlyList<{type.GetActualType()}>> {GetMethodName(type)

        var result = "
            );
            /*var error = */_inlineConverters.CallDeserialize(textWriter, null, type); // TODO handle error
            /*var error = */_inlineConverters.CallDeserialize(textWriter, null, type, nullable); // TODO handle error

            textWriter.WriteMultiline(@$"



@@ 159,4 158,12 @@ if (result.Entity is null)
            textWriter.WriteLine("}");
        }
    }

    /// <inheritdoc />
    public void GenerateHelperMethods(IndentedTextWriter textWriter)
    {
        GenerateHelperMethods(textWriter, true);
        GenerateHelperMethods(textWriter, false);
    }

}
\ No newline at end of file

M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/StringInlineConverterGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/StringInlineConverterGenerator.cs +8 -5
@@ 28,9 28,9 @@ public class StringInlineConverterGenerator : IInlineConverterGenerator
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol, bool nullable)
    {
        textWriter.WriteLine($"{Constants.HelperClass}.ParseString(ref stringEnumerator);");
        textWriter.WriteLine($"{Constants.HelperClass}.ParseString(ref stringEnumerator, {nullable.ToString().ToLower()});");
        return null;
    }



@@ 40,7 40,7 @@ public class StringInlineConverterGenerator : IInlineConverterGenerator
        textWriter.WriteLine
        (
            @"
public static Result<string?> ParseString(ref PacketStringEnumerator stringEnumerator)
public static Result<string?> ParseString(ref PacketStringEnumerator stringEnumerator, bool nullable)
{{
    var tokenResult = stringEnumerator.GetNextToken(out var packetToken);
    if (!tokenResult.IsSuccess)


@@ 48,9 48,12 @@ public static Result<string?> ParseString(ref PacketStringEnumerator stringEnume
        return Result<string?>.FromError(tokenResult);
    }}

    if (packetToken.Token.Length == 1 && packetToken.Token[0] == '-')
    if (nullable)
    {{
        return Result<string?>.FromSuccess(null);
        if (packetToken.Token.Length == 1 && packetToken.Token[0] == '-')
        {{
            return Result<string?>.FromSuccess(null);
        }}
    }}

    return packetToken.Token.ToString();

M Packets/NosSmooth.PacketSerializersGenerator/InlineTypeConverterGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/InlineTypeConverterGenerator.cs +9 -6
@@ 38,8 38,9 @@ public class InlineTypeConverterGenerator
    /// </summary>
    /// <param name="textWriter">The text writer.</param>
    /// <param name="packet">The packet.</param>
    /// <param name="nullable">Whether the parameter is nullable.</param>
    /// <returns>An error, if any.</returns>
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet, bool nullable)
    {
        var parameter = packet.Parameters.Current;
        var shouldGenerateInline = packet.GenerateAttribute.GetIndexedValue<bool>(0);


@@ 49,12 50,12 @@ public class InlineTypeConverterGenerator
            {
                if (generator.ShouldHandle(parameter.Parameter.Type, parameter.Type))
                {
                    return generator.CallDeserialize(textWriter, parameter.Parameter.Type, parameter.Type);
                    return generator.CallDeserialize(textWriter, parameter.Parameter.Type, parameter.Type, nullable);
                }
            }
        }

        return _fallbackInlineConverterGenerator.CallDeserialize(textWriter, parameter.Parameter.Type, parameter.Type);
        return _fallbackInlineConverterGenerator.CallDeserialize(textWriter, parameter.Parameter.Type, parameter.Type, nullable);
    }

    /// <summary>


@@ 63,23 64,25 @@ public class InlineTypeConverterGenerator
    /// <param name="textWriter">The text writer.</param>
    /// <param name="typeSyntax">The type syntax.</param>
    /// <param name="typeSymbol">The type symbol.</param>
    /// <param name="nullable">Whether the parameter is nullable.</param>
    /// <returns>An error, if any.</returns>
    public IError? CallDeserialize
    (
        IndentedTextWriter textWriter,
        TypeSyntax? typeSyntax,
        ITypeSymbol? typeSymbol
        ITypeSymbol? typeSymbol,
        bool nullable
    )
    {
        foreach (var generator in _typeGenerators)
        {
            if (generator.ShouldHandle(typeSyntax, typeSymbol))
            {
                return generator.CallDeserialize(textWriter, typeSyntax, typeSymbol);
                return generator.CallDeserialize(textWriter, typeSyntax, typeSymbol, nullable);
            }
        }

        return _fallbackInlineConverterGenerator.CallDeserialize(textWriter, typeSyntax, typeSymbol);
        return _fallbackInlineConverterGenerator.CallDeserialize(textWriter, typeSyntax, typeSymbol, nullable);
    }

    /// <summary>

M Packets/NosSmooth.PacketSerializersGenerator/PacketConverterGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/PacketConverterGenerator.cs +1 -1
@@ 94,7 94,7 @@ public override Result Serialize({_packetInfo.Name}? obj, PacketStringBuilder bu
}}

/// <inheritdoc />
public override Result<{_packetInfo.Name}?> Deserialize(ref PacketStringEnumerator stringEnumerator)
public override Result<{_packetInfo.Name}?> Deserialize(ref PacketStringEnumerator stringEnumerator, DeserializeOptions options)
{{
    var typeConverter = this;
"

M Packets/NosSmooth.PacketSerializersGenerator/SourceGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/SourceGenerator.cs +0 -6
@@ 130,12 130,6 @@ public class SourceGenerator : ISourceGenerator
                    $"{packetRecord.GetPrefix()}.{packetRecord.Identifier.NormalizeWhitespace().ToFullString()}Converter.g.cs",
                    stringWriter.GetStringBuilder().ToString()
                );

                File.WriteAllText
                (
                    Path.Combine(Path.GetTempPath(), $"{packetRecord.GetPrefix()}.{packetRecord.Identifier.NormalizeWhitespace().ToFullString()}Converter.g.cs"),
                    stringWriter.GetStringBuilder().ToString()
                );
            }
        }


M Packets/NosSmooth.Packets/Server/Character/AscrPacket.cs => Packets/NosSmooth.Packets/Server/Character/AscrPacket.cs +1 -1
@@ 42,5 42,5 @@ public record AscrPacket
    [PacketIndex(7)]
    int DieGroup,
    [PacketIndex(8)]
    AscrPacketType? Type
    AscrPacketType Type
) : IPacket;
\ No newline at end of file

M Packets/NosSmooth.Packets/Server/Portals/GpPacket.cs => Packets/NosSmooth.Packets/Server/Portals/GpPacket.cs +1 -1
@@ 29,7 29,7 @@ public record GpPacket
    [PacketIndex(2)]
    int TargetMapId,
    [PacketIndex(3)]
    PortalType? PortalType,
    PortalType PortalType,
    [PacketIndex(4)]
    long PortalId,
    [PacketIndex(5)]

M Packets/NosSmooth.Packets/Server/Relations/FInitSubPacket.cs => Packets/NosSmooth.Packets/Server/Relations/FInitSubPacket.cs +1 -1
@@ 25,7 25,7 @@ public record FInitSubPacket
    [PacketIndex(0)]
    long PlayerId,
    [PacketIndex(1)]
    CharacterRelationType? RelationType,
    CharacterRelationType RelationType,
    [PacketIndex(2)]
    bool IsConnected,
    [PacketIndex(3)]

M Tests/NosSmooth.Packets.Tests/Converters/Basic/BoolStringConverterTests.cs => Tests/NosSmooth.Packets.Tests/Converters/Basic/BoolStringConverterTests.cs +3 -3
@@ 52,7 52,7 @@ public class BoolStringConverterTests
    {
        var deserialize = "-1";
        var stringEnumerator = new PacketStringEnumerator(deserialize);
        var deserializeResult = _stringSerializer.Deserialize<bool?>(ref stringEnumerator);
        var deserializeResult = _stringSerializer.Deserialize<bool?>(ref stringEnumerator, default);
        Assert.True(deserializeResult.IsSuccess, !deserializeResult.IsSuccess ? deserializeResult.Error.Message : string.Empty);
        Assert.Null(deserializeResult.Entity);
    }


@@ 65,7 65,7 @@ public class BoolStringConverterTests
    {
        var deserialize = "1";
        var stringEnumerator = new PacketStringEnumerator(deserialize);
        var deserializeResult = _stringSerializer.Deserialize<bool?>(ref stringEnumerator);
        var deserializeResult = _stringSerializer.Deserialize<bool?>(ref stringEnumerator, default);
        Assert.True(deserializeResult.IsSuccess, !deserializeResult.IsSuccess ? deserializeResult.Error.Message : string.Empty);
        Assert.True(deserializeResult.Entity);
    }


@@ 78,7 78,7 @@ public class BoolStringConverterTests
    {
        var deserialize = "0";
        var stringEnumerator = new PacketStringEnumerator(deserialize);
        var deserializeResult = _stringSerializer.Deserialize<bool?>(ref stringEnumerator);
        var deserializeResult = _stringSerializer.Deserialize<bool?>(ref stringEnumerator, default);
        Assert.True(deserializeResult.IsSuccess, !deserializeResult.IsSuccess ? deserializeResult.Error.Message : string.Empty);
        Assert.False(deserializeResult.Entity);
    }

M Tests/NosSmooth.Packets.Tests/Converters/Basic/StringConverterTests.cs => Tests/NosSmooth.Packets.Tests/Converters/Basic/StringConverterTests.cs +16 -2
@@ 48,12 48,26 @@ public class StringConverterTests
    /// Tests that the serializer serializes null as -.
    /// </summary>
    [Fact]
    public void TestsTreatsMinusAsNull()
    public void TestsTreatsMinusAsNull_IfNullEnabled()
    {
        var deserialize = "-";
        var stringEnumerator = new PacketStringEnumerator(deserialize);
        var deserializeResult = _stringSerializer.Deserialize<string?>(ref stringEnumerator);
        var deserializeResult = _stringSerializer.Deserialize<string?>(ref stringEnumerator, DeserializeOptions.Nullable);
        Assert.True(deserializeResult.IsSuccess, !deserializeResult.IsSuccess ? deserializeResult.Error.Message : string.Empty);
        Assert.Null(deserializeResult.Entity);
    }

    /// <summary>
    /// Tests that the serializer serializes - as -.
    /// </summary>
    [Fact]
    public void TestsTreatsMinusAsNull_IfNullDisabled()
    {
        var deserialize = "-";
        var stringEnumerator = new PacketStringEnumerator(deserialize);
        var deserializeResult = _stringSerializer.Deserialize<string?>(ref stringEnumerator, default);
        Assert.True(deserializeResult.IsSuccess, !deserializeResult.IsSuccess ? deserializeResult.Error.Message : string.Empty);
        Assert.NotNull(deserializeResult.Entity);
        Assert.Equal("-", deserializeResult.Entity);
    }
}
\ No newline at end of file

M Tests/NosSmooth.Packets.Tests/Converters/Packets/CListPacketConverterTests.cs => Tests/NosSmooth.Packets.Tests/Converters/Packets/CListPacketConverterTests.cs +3 -2
@@ 8,6 8,7 @@ using Microsoft.Extensions.DependencyInjection;
using NosSmooth.Packets.Enums.Players;
using NosSmooth.Packets.Server.Login;
using NosSmooth.PacketSerializer;
using NosSmooth.PacketSerializer.Abstractions;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Extensions;
using NosSmooth.PacketSerializer.Packets;


@@ 68,7 69,7 @@ public class CListPacketConverterTests
            string.Empty,
            1,
            1,
            new[]
            new NullableWrapper<CListPetSubPacket>[]
            {
                new CListPetSubPacket(0, 2105),
                new CListPetSubPacket(0, 319),


@@ 141,7 142,7 @@ public class CListPacketConverterTests
            string.Empty,
            1,
            1,
            new[]
            new NullableWrapper<CListPetSubPacket>[]
            {
                new CListPetSubPacket(0, 2105),
                new CListPetSubPacket(0, 319),

M Tests/NosSmooth.Packets.Tests/Converters/Packets/PinitPacketConverterTest.cs => Tests/NosSmooth.Packets.Tests/Converters/Packets/PinitPacketConverterTest.cs +74 -9
@@ 6,6 6,7 @@

using Microsoft.Extensions.DependencyInjection;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.Packets.Enums.Mates;
using NosSmooth.Packets.Server.Groups;
using NosSmooth.PacketSerializer;
using NosSmooth.PacketSerializer.Abstractions.Attributes;


@@ 41,11 42,41 @@ public class PinitPacketConverterTest
    [Fact]
    public void Converter_Serialization_SerializesCorrectly()
    {
        var packet = new PinitPacket(2, new[]
        {
            new PinitSubPacket(EntityType.Npc, 345377, 0, 83, "Kliff", -1, 319, 1, 0, null, null, null),
            new PinitSubPacket(EntityType.Npc, 345384, 1, 83, "@", -1, 2105, 0, 0, null, null, null)
        });
        var packet = new PinitPacket
        (
            2,
            new[]
            {
                new PinitSubPacket
                (
                    EntityType.Npc,
                    345377,
                    new PinitMateSubPacket
                    (
                        MateType.Partner,
                        83,
                        "Kliff",
                        null,
                        319
                    ),
                    null
                ),
                new PinitSubPacket
                (
                    EntityType.Npc,
                    345384,
                    new PinitMateSubPacket
                    (
                        MateType.Pet,
                        83,
                        "@",
                        null,
                        2105
                    ),
                    null
                )
            }
        );
        var result = _packetSerializer.Serialize(packet);
        Assert.True(result.IsSuccess);



@@ 64,10 95,44 @@ public class PinitPacketConverterTest

        var actualPacket = (PinitPacket)result.Entity;

        Assert.Equal(2, actualPacket.GroupSize);
        Assert.Equal(2, actualPacket.SubPacketsCount);
        Assert.NotNull(actualPacket.PinitSubPackets);
        Assert.Equal(2, actualPacket.PinitSubPackets!.Count);
        Assert.StrictEqual(new PinitSubPacket(EntityType.Npc, 345377, 0, 83, "Kliff", null, 319, 1, 0, null, null, null), actualPacket.PinitSubPackets[0]);
        Assert.StrictEqual(new PinitSubPacket(EntityType.Npc, 345384, 1, 83, "@", null, 2105, 0, 0, null, null, null), actualPacket.PinitSubPackets[1]);
        Assert.StrictEqual
        (
            new PinitSubPacket
            (
                EntityType.Npc,
                345377,
                new PinitMateSubPacket
                (
                    MateType.Partner,
                    83,
                    "Kliff",
                    null,
                    319
                ),
                null
            ),
            actualPacket.PinitSubPackets[0]
        );
        Assert.StrictEqual
        (
            new PinitSubPacket
            (
                EntityType.Npc,
                345384,
                new PinitMateSubPacket
                (
                    MateType.Pet,
                    83,
                    "@",
                    null,
                    2105
                ),
                null
            ),
            actualPacket.PinitSubPackets[1]
        );
    }
}
}
\ No newline at end of file

Do not follow this link