~ruther/NosSmooth

81d4c246bfc998d8fd37f27b7ef7527d9a0d09bc — František Boháček 3 years ago 9829b8c + 2058d76
Merge branch 'in-packet-serialize' into 'main'

Serialize IN packet

See merge request Rutherther/nos-smooth!3
M Core/NosSmooth.Core/Extensions/ServiceCollectionExtensions.cs => Core/NosSmooth.Core/Extensions/ServiceCollectionExtensions.cs +3 -0
@@ 16,6 16,7 @@ using NosCore.Packets.Interfaces;
using NosSmooth.Core.Client;
using NosSmooth.Core.Commands;
using NosSmooth.Core.Packets;
using NosSmooth.Core.Packets.Converters;

namespace NosSmooth.Core.Extensions;



@@ 55,6 56,8 @@ public static class ServiceCollectionExtensions

        serviceCollection.AddSingleton<CommandProcessor>();

        serviceCollection.AddSpecificPacketConverter<InPacketSerializer>();

        return serviceCollection;
    }


A Core/NosSmooth.Core/Packets/Converters/InPacketSerializer.cs => Core/NosSmooth.Core/Packets/Converters/InPacketSerializer.cs +91 -0
@@ 0,0 1,91 @@
//
//  InPacketSerializer.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;
using System.Linq;
using NosCore.Packets.ServerPackets.Visibility;
using NosCore.Shared.Enumerations;
using Remora.Results;

namespace NosSmooth.Core.Packets.Converters;

/// <summary>
/// Deserializes InPacket correctly.
/// </summary>
public class InPacketSerializer : SpecificPacketSerializer<InPacket>
{
    private readonly PacketSerializerProvider _packetSerializerProvider;

    /// <summary>
    /// Initializes a new instance of the <see cref="InPacketSerializer"/> class.
    /// </summary>
    /// <param name="packetSerializerProvider">The provider of packet serializer.</param>
    public InPacketSerializer(PacketSerializerProvider packetSerializerProvider)
    {
        _packetSerializerProvider = packetSerializerProvider;
    }

    /// <inheritdoc />
    public override bool Serializer => false;

    /// <inheritdoc />
    public override bool Deserializer => true;

    /// <inheritdoc />
    public override Result<string> Serialize(InPacket packet)
    {
        throw new System.NotImplementedException();
    }

    /// <inheritdoc />
    public override Result<InPacket> Deserialize(string packetString)
    {
        try
        {
            var deserializer = _packetSerializerProvider.ServerSerializer.Deserializer;
            var splitted = packetString.Split(new char[] { ' ' }, 9).Skip(1).ToArray();

            if (!Enum.TryParse(splitted[0], out VisualType type))
            {
                return new ArgumentInvalidError(nameof(packetString), "The visual type is incorrect.");
            }

            var startAddress = type == VisualType.Player ? 3 : 2;
            var inPacket = new InPacket
            {
                VisualType = type,
                VNum = type != VisualType.Player ? long.Parse(splitted[1]) : null,
                Name = type == VisualType.Player ? splitted[1] : null,
                VisualId = long.Parse(splitted[startAddress]),
                PositionX = short.Parse(splitted[startAddress + 1]),
                PositionY = short.Parse(splitted[startAddress + 2]),
                Direction = byte.Parse(splitted[startAddress + 3])
            };

            switch (inPacket.VisualType)
            {
                case VisualType.Player:
                    inPacket.InCharacterSubPacket = (InCharacterSubPacket?)deserializer
                        .DeserializeHeaderlessIPacket(typeof(InCharacterSubPacket), splitted[7]);
                    break;
                case VisualType.Object:
                    inPacket.InItemSubPacket = (InItemSubPacket?)deserializer
                        .DeserializeHeaderlessIPacket(typeof(InItemSubPacket), splitted[6] + " " + splitted[7]);
                    break;
                default:
                    inPacket.InNonPlayerSubPacket = (InNonPlayerSubPacket?)deserializer
                        .DeserializeHeaderlessIPacket(typeof(InNonPlayerSubPacket), splitted[6] + " " + splitted[7]);
                    break;
            }

            return inPacket;
        }
        catch (Exception e)
        {
            return e;
        }
    }
}
\ No newline at end of file

M NosSmooth.sln => NosSmooth.sln +16 -1
@@ 36,7 36,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".metadata", ".metadata", "{
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleChat", "Samples\SimpleChat\SimpleChat.csproj", "{4017A4F4-5E59-48AA-A7D0-A8518148933A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tets", "Tets", "{C6A8760D-92CB-4307-88A7-36CCAEBA4AD1}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C6A8760D-92CB-4307-88A7-36CCAEBA4AD1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NosCore.Packets.Tests", "libs\NosCore.Packets\test\NosCore.Packets.Tests\NosCore.Packets.Tests.csproj", "{726188BA-F0EA-4ECA-ACF4-CCC066464FF0}"
EndProject


@@ 46,6 46,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LowLevel", "LowLevel", "{90
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WalkCommands", "Samples\WalkCommands\WalkCommands.csproj", "{18A62EF6-ADDA-4224-90AB-2D5DCFC95D3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NosSmooth.Core.Tests", "Tests\NosSmooth.Core.Tests\NosSmooth.Core.Tests.csproj", "{1A10C624-48E5-425D-938E-31A4CC7AC687}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU


@@ 210,6 212,18 @@ Global
		{18A62EF6-ADDA-4224-90AB-2D5DCFC95D3E}.Release|x64.Build.0 = Release|Any CPU
		{18A62EF6-ADDA-4224-90AB-2D5DCFC95D3E}.Release|x86.ActiveCfg = Release|Any CPU
		{18A62EF6-ADDA-4224-90AB-2D5DCFC95D3E}.Release|x86.Build.0 = Release|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Debug|x64.ActiveCfg = Debug|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Debug|x64.Build.0 = Debug|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Debug|x86.ActiveCfg = Debug|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Debug|x86.Build.0 = Debug|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Release|Any CPU.Build.0 = Release|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Release|x64.ActiveCfg = Release|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Release|x64.Build.0 = Release|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Release|x86.ActiveCfg = Release|Any CPU
		{1A10C624-48E5-425D-938E-31A4CC7AC687}.Release|x86.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE


@@ 227,6 241,7 @@ Global
		{9025731C-084E-4E82-8CD4-0F52D3AA1F54} = {F20FE754-FDEA-4F3A-93D4-0750CB9EBB33}
		{F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A} = {9025731C-084E-4E82-8CD4-0F52D3AA1F54}
		{4017A4F4-5E59-48AA-A7D0-A8518148933A} = {9025731C-084E-4E82-8CD4-0F52D3AA1F54}
		{1A10C624-48E5-425D-938E-31A4CC7AC687} = {C6A8760D-92CB-4307-88A7-36CCAEBA4AD1}
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {C5F46653-4DEC-429B-8580-4ED18ED9B4CA}

A Tests/NosSmooth.Core.Tests/NosSmooth.Core.Tests.csproj => Tests/NosSmooth.Core.Tests/NosSmooth.Core.Tests.csproj +27 -0
@@ 0,0 1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <Nullable>enable</Nullable>

        <IsPackable>false</IsPackable>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
        <PackageReference Include="xunit" Version="2.4.1" />
        <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
            <PrivateAssets>all</PrivateAssets>
        </PackageReference>
        <PackageReference Include="coverlet.collector" Version="3.1.0">
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
            <PrivateAssets>all</PrivateAssets>
        </PackageReference>
    </ItemGroup>

    <ItemGroup>
      <ProjectReference Include="..\..\Core\NosSmooth.Core\NosSmooth.Core.csproj" />
    </ItemGroup>

</Project>

A Tests/NosSmooth.Core.Tests/Packets/InPacketSerializerTest.cs => Tests/NosSmooth.Core.Tests/Packets/InPacketSerializerTest.cs +158 -0
@@ 0,0 1,158 @@
//
//  InPacketSerializerTest.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;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using NosCore.Packets.ServerPackets.Inventory;
using NosCore.Packets.ServerPackets.Visibility;
using NosCore.Shared.Enumerations;
using NosSmooth.Core.Packets;
using NosSmooth.Core.Packets.Converters;
using Xunit;

namespace NosSmooth.Core.Tests.Packets;

/// <summary>
/// Test class for <see cref="InPacketSerializerTest"/>.
/// </summary>
public class InPacketSerializerTest
{
    private readonly InPacketSerializer _inPacketSerializer;

    /// <summary>
    /// Initializes a new instance of the <see cref="InPacketSerializerTest"/> class.
    /// </summary>
    public InPacketSerializerTest()
    {
        var types = new List<Type>(new[]
        {
            typeof(InPacket),
            typeof(InAliveSubPacket),
            typeof(InNonPlayerSubPacket),
            typeof(InCharacterSubPacket),
            typeof(InItemSubPacket),
            typeof(InEquipmentSubPacket),
            typeof(UpgradeRareSubPacket),
            typeof(FamilySubPacket),
        });

        _inPacketSerializer = new ServiceCollection()
            .AddSingleton(
                p => new PacketSerializerProvider(types, types, p)
            )
            .AddSingleton<InPacketSerializer>()
            .BuildServiceProvider()
            .GetRequiredService<InPacketSerializer>();
    }

    /// <summary>
    /// Tests whether the serializer accepts to handle in packet.
    /// </summary>
    [Fact]
    public void AcceptsInPacket()
    {
        var shouldHandle = _inPacketSerializer.ShouldHandle(
            "in 1 dfrfgh - 1 79 2 6 2 1 0 106 2 -1.4480.4452.4468.4840.4132.-1.-1.-1.-1 100 100 0 -1 4 4 0 43 0 0 108 108 -1 - 26 0 0 0 0 99 0 0|0|0 0 0 10 80 0");
        Assert.True(shouldHandle);
    }

    /// <summary>
    /// Tests whether the serializer doesnt accept to handle non in packet.
    /// </summary>
    [Fact]
    public void DoesntAcceptNonInPacket()
    {
        var shouldHandle = _inPacketSerializer.ShouldHandle(
            "sr 5");
        Assert.False(shouldHandle);
    }

    /// <summary>
    /// Tests whether the result is successful when serializing player in packet.
    /// </summary>
    [Fact]
    public void SucceedsDeserializingPlayerIn()
    {
        var result = _inPacketSerializer.Deserialize(
            "in 1 dfrfgh - 1 79 2 6 2 1 0 106 2 -1.4480.4452.4468.4840.4132.-1.-1.-1.-1 50 98 0 -1 4 4 0 43 0 0 108 108 -1 - 26 0 0 0 0 99 0 0|0|0 0 0 10 80 0"
        );
        Assert.True(result.IsSuccess);
    }

    /// <summary>
    /// Tests whether the result is successful when serializing monster in packet.
    /// </summary>
    [Fact]
    public void SucceedsDeserializingMonsterIn()
    {
        var result = _inPacketSerializer.Deserialize(
            "in 2 334 1992 134 112 2 100 100 0 0 0 -1 1 0 -1 - 0 -1 0 0 0 0 0 0 0 0 0 0"
        );
        Assert.True(result.IsSuccess);
    }

    /// <summary>
    /// Tests whether the result of deserializing player is correct.
    /// </summary>
    [Fact]
    public void DeserializesPlayerInCorrectly()
    {
        var result = _inPacketSerializer.Deserialize(
            "in 1 dfrfgh - 55 79 2 6 2 1 0 106 2 -1.4480.4452.4468.4840.4132.-1.-1.-1.-1 50 95 0 -1 4 4 0 43 0 0 108 108 -1 - 26 0 0 0 0 99 0 0|0|0 0 0 10 80 0"
        ); // 55 is id, 50 hp, 95 mp

        Assert.True(result.IsSuccess);
        var inPacket = result.Entity;

        Assert.Equal(VisualType.Player, inPacket.VisualType);
        Assert.NotNull(inPacket.Name);
        Assert.Matches("dfrfgh", inPacket.Name);
        Assert.Equal(55, inPacket.VisualId);
        Assert.Equal(79, inPacket.PositionX);
        Assert.Equal(2, inPacket.PositionY);
        Assert.NotNull(inPacket.Direction);
        Assert.Equal(6, (byte)inPacket.Direction!);
        Assert.NotNull(inPacket.InCharacterSubPacket);
        var characterSubPacket = inPacket.InCharacterSubPacket!;
        Assert.Equal(AuthorityType.GameMaster, characterSubPacket.Authority);
        Assert.Equal(CharacterClassType.Archer, characterSubPacket.Class);
        Assert.NotNull(characterSubPacket.InAliveSubPacket);
        Assert.Equal(50, characterSubPacket.InAliveSubPacket!.Hp);
        Assert.Equal(95, characterSubPacket.InAliveSubPacket!.Mp);

        // TODO: check other things
    }

    /// <summary>
    /// Tests whether the result of deserializing monster is correct.
    /// </summary>
    [Fact]
    public void DeserializesMonsterInCorrectly()
    {
        var result = _inPacketSerializer.Deserialize(
            "in 2 334 1992 134 112 2 100 80 0 0 0 -1 1 0 -1 - 0 -1 0 0 0 0 0 0 0 0 0 0"
        );
        Assert.True(result.IsSuccess);
        var inPacket = result.Entity;
        Assert.Equal(VisualType.Npc, inPacket.VisualType);
        Assert.NotNull(inPacket.VNum);
        Assert.Equal(334, inPacket.VNum!.Value);
        Assert.Equal(1992, inPacket.VisualId);
        Assert.Equal(134, inPacket.PositionX);
        Assert.Equal(112, inPacket.PositionY);
        Assert.NotNull(inPacket.Direction);
        Assert.Equal(2, (byte)inPacket.Direction!);
        Assert.NotNull(inPacket.InNonPlayerSubPacket);
        var nonPlayerSubPacket = inPacket.InNonPlayerSubPacket!;
        Assert.NotNull(nonPlayerSubPacket.InAliveSubPacket);
        Assert.Equal(100, nonPlayerSubPacket.InAliveSubPacket!.Hp);
        Assert.Equal(80, nonPlayerSubPacket.InAliveSubPacket!.Mp);

        // TODO: check other things
    }
}
\ No newline at end of file

M libs/NosCore.Packets => libs/NosCore.Packets +1 -1
@@ 1,1 1,1 @@
Subproject commit 47377f323f57a7b0e9f9b14a671bb4b275020993
Subproject commit ccb432224367fa76403b794d4e5988b241ef19b6

Do not follow this link