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