~ruther/NosSmooth

8154990e3f07a5de484867c29fe2b1dfc2dd1768 — Rutherther 2 years ago e5bc58f
feat(packets): add many new packets
86 files changed, 1976 insertions(+), 27 deletions(-)

M Core/NosSmooth.Game/Helpers/EntityHelpers.cs
M Core/NosSmooth.Game/PacketHandlers/Characters/CharacterInitResponder.cs
M Core/NosSmooth.Game/PacketHandlers/Entities/SkillUsedResponder.cs
M Core/NosSmooth.Game/PacketHandlers/Map/InResponder.cs
M Packets/NosSmooth.Packets/Client/Battle/NcifPacket.cs
M Packets/NosSmooth.Packets/Client/Battle/UseSkillPacket.cs
A Packets/NosSmooth.Packets/Client/Login/CClosePacket.cs
A Packets/NosSmooth.Packets/Client/Login/GameStartPacket.cs
A Packets/NosSmooth.Packets/Client/Login/LbsPacket.cs
A Packets/NosSmooth.Packets/Client/Login/SelectPacket.cs
M Packets/NosSmooth.Packets/Enums/Entities/EntityType.cs
M Packets/NosSmooth.Packets/Enums/Entities/FactionType.cs
A Packets/NosSmooth.Packets/Enums/Mates/PartnerSkillRank.cs
A Packets/NosSmooth.Packets/Enums/Packets/AscrPacketType.cs
A Packets/NosSmooth.Packets/Enums/Packets/QSlotType.cs
M Packets/NosSmooth.Packets/Enums/Players/AuthorityType.cs
A Packets/NosSmooth.Packets/Enums/Quests/QuestGoalType.cs
A Packets/NosSmooth.Packets/Enums/Relations/CharacterRelationType.cs
M Packets/NosSmooth.Packets/Server/Act4/FcPacket.cs
M Packets/NosSmooth.Packets/Server/Battle/BsPacket.cs
M Packets/NosSmooth.Packets/Server/Battle/SuPacket.cs
A Packets/NosSmooth.Packets/Server/Character/AscrPacket.cs
R Packets/NosSmooth.Packets/Server/{Players => Character}/CInfoPacket.cs
A Packets/NosSmooth.Packets/Server/Character/CInfoResetPacket.cs
R Packets/NosSmooth.Packets/Server/{Players => Character}/CModePacket.cs
R Packets/NosSmooth.Packets/Server/{Players => Character}/FamilySubPacket.cs
A Packets/NosSmooth.Packets/Server/Character/FdPacket.cs
A Packets/NosSmooth.Packets/Server/Character/FsPacket.cs
R Packets/NosSmooth.Packets/Server/{Players => Character}/LevPacket.cs
A Packets/NosSmooth.Packets/Server/Character/RagePacket.cs
A Packets/NosSmooth.Packets/Server/Character/ResistanceSubPacket.cs
A Packets/NosSmooth.Packets/Server/Character/RsfiPacket.cs
A Packets/NosSmooth.Packets/Server/Character/RsfpPacket.cs
A Packets/NosSmooth.Packets/Server/Character/ScArmorSubPacket.cs
A Packets/NosSmooth.Packets/Server/Character/ScPacket.cs
A Packets/NosSmooth.Packets/Server/Character/ScWeaponSubPacket.cs
A Packets/NosSmooth.Packets/Server/Character/TitPacket.cs
A Packets/NosSmooth.Packets/Server/Character/TitinfoPacket.cs
A Packets/NosSmooth.Packets/Server/Character/TitlePacket.cs
A Packets/NosSmooth.Packets/Server/Character/TitleSubPacket.cs
M Packets/NosSmooth.Packets/Server/Chat/SayPacket.cs
M Packets/NosSmooth.Packets/Server/Entities/CondPacket.cs
M Packets/NosSmooth.Packets/Server/Entities/MovePacket.cs
M Packets/NosSmooth.Packets/Server/Entities/StPacket.cs
A Packets/NosSmooth.Packets/Server/Families/GidxPacket.cs
M Packets/NosSmooth.Packets/Server/Groups/PinitSubPacket.cs
M Packets/NosSmooth.Packets/Server/Inventory/EqPacket.cs
A Packets/NosSmooth.Packets/Server/Inventory/EquipPacket.cs
A Packets/NosSmooth.Packets/Server/Inventory/EquipSubPacket.cs
A Packets/NosSmooth.Packets/Server/Inventory/ExtsPacket.cs
A Packets/NosSmooth.Packets/Server/Inventory/GoldPacket.cs
A Packets/NosSmooth.Packets/Server/Inventory/PairyPacket.cs
A Packets/NosSmooth.Packets/Server/Login/CListEndPacket.cs
A Packets/NosSmooth.Packets/Server/Login/CListEquipmentSubPacket.cs
A Packets/NosSmooth.Packets/Server/Login/CListPacket.cs
A Packets/NosSmooth.Packets/Server/Login/CListPetSubPacket.cs
A Packets/NosSmooth.Packets/Server/Login/CListStartPacket.cs
A Packets/NosSmooth.Packets/Server/Login/FStashEndPacket.cs
A Packets/NosSmooth.Packets/Server/Login/OkPacket.cs
A Packets/NosSmooth.Packets/Server/Maps/Bgm2Packet.cs
M Packets/NosSmooth.Packets/Server/Maps/InPacket.cs
M Packets/NosSmooth.Packets/Server/Maps/InPlayerSubPacket.cs
M Packets/NosSmooth.Packets/Server/Maps/OutPacket.cs
A Packets/NosSmooth.Packets/Server/Mates/ScNEquipmentSubPacket.cs
A Packets/NosSmooth.Packets/Server/Mates/ScNPacket.cs
A Packets/NosSmooth.Packets/Server/Mates/ScNSkillSubPacket.cs
A Packets/NosSmooth.Packets/Server/Mates/ScNSpSubPacket.cs
A Packets/NosSmooth.Packets/Server/Mates/ScPPacket.cs
A Packets/NosSmooth.Packets/Server/Npc/ShopPacket.cs
A Packets/NosSmooth.Packets/Server/Quests/QstListObjectiveSubPacket.cs
A Packets/NosSmooth.Packets/Server/Quests/QstListPacket.cs
A Packets/NosSmooth.Packets/Server/Quests/QstListSubPacket.cs
A Packets/NosSmooth.Packets/Server/Quicklist/QSlotPacket.cs
A Packets/NosSmooth.Packets/Server/Quicklist/QSlotSubPacket.cs
A Packets/NosSmooth.Packets/Server/Relations/FInfoPacket.cs
A Packets/NosSmooth.Packets/Server/Relations/FInfoSubPacket.cs
A Packets/NosSmooth.Packets/Server/Relations/FInitPacket.cs
A Packets/NosSmooth.Packets/Server/Relations/FInitSubPacket.cs
A Packets/NosSmooth.Packets/Server/UI/Act6Packet.cs
A Packets/NosSmooth.Packets/Server/UI/BnPacket.cs
A Packets/NosSmooth.Packets/Server/UI/TwkPacket.cs
M Tests/NosSmooth.Packets.Tests/Converters/Packets/FcPacketConverterTests.cs
M Tests/NosSmooth.Packets.Tests/Converters/Packets/InPacketConverterTests.cs
M Tests/NosSmooth.Packets.Tests/Converters/Packets/MovePacketConverterTests.cs
M Tests/NosSmooth.Packets.Tests/Converters/Packets/PinitPacketConverterTest.cs
M Tests/NosSmooth.Packets.Tests/Converters/Packets/SkiPacketConverterTests.cs
M Core/NosSmooth.Game/Helpers/EntityHelpers.cs => Core/NosSmooth.Game/Helpers/EntityHelpers.cs +1 -1
@@ 5,7 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Game.Data.Entities;
using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;

namespace NosSmooth.Game.Helpers;


M Core/NosSmooth.Game/PacketHandlers/Characters/CharacterInitResponder.cs => Core/NosSmooth.Game/PacketHandlers/Characters/CharacterInitResponder.cs +1 -1
@@ 10,7 10,7 @@ using NosSmooth.Game.Data.Info;
using NosSmooth.Game.Data.Social;
using NosSmooth.Game.Events.Characters;
using NosSmooth.Game.Events.Core;
using NosSmooth.Packets.Server.Players;
using NosSmooth.Packets.Server.Character;
using Remora.Results;

namespace NosSmooth.Game.PacketHandlers.Characters;

M Core/NosSmooth.Game/PacketHandlers/Entities/SkillUsedResponder.cs => Core/NosSmooth.Game/PacketHandlers/Entities/SkillUsedResponder.cs +1 -4
@@ 5,11 5,9 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.Extensions.Logging;
using Microsoft.VisualBasic;
using NosSmooth.Core.Extensions;
using NosSmooth.Core.Packets;
using NosSmooth.Data.Abstractions;
using NosSmooth.Data.Abstractions.Enums;
using NosSmooth.Game.Data.Characters;
using NosSmooth.Game.Data.Entities;
using NosSmooth.Game.Data.Info;


@@ 19,8 17,7 @@ using NosSmooth.Game.Events.Core;
using NosSmooth.Game.Events.Entities;
using NosSmooth.Game.Extensions;
using NosSmooth.Game.Helpers;
using NosSmooth.Packets.Client.Battle;
using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.Packets.Server.Battle;
using NosSmooth.Packets.Server.Skills;
using Remora.Results;

M Core/NosSmooth.Game/PacketHandlers/Map/InResponder.cs => Core/NosSmooth.Game/PacketHandlers/Map/InResponder.cs +1 -3
@@ 10,13 10,11 @@ using NosSmooth.Core.Packets;
using NosSmooth.Data.Abstractions;
using NosSmooth.Game.Data.Entities;
using NosSmooth.Game.Data.Info;
using NosSmooth.Game.Data.Items;
using NosSmooth.Game.Data.Social;
using NosSmooth.Game.Events.Core;
using NosSmooth.Game.Events.Entities;
using NosSmooth.Game.Helpers;
using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Server.Entities;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.Packets.Server.Maps;
using Remora.Results;


M Packets/NosSmooth.Packets/Client/Battle/NcifPacket.cs => Packets/NosSmooth.Packets/Client/Battle/NcifPacket.cs +1 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Client.Battle;

M Packets/NosSmooth.Packets/Client/Battle/UseSkillPacket.cs => Packets/NosSmooth.Packets/Client/Battle/UseSkillPacket.cs +1 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Client.Battle;

A Packets/NosSmooth.Packets/Client/Login/CClosePacket.cs => Packets/NosSmooth.Packets/Client/Login/CClosePacket.cs +21 -0
@@ 0,0 1,21 @@
//
//  CClosePacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Client.Login;

/// <summary>
/// Unknown function
/// </summary>
/// <param name="Unknown">Unknown, seems to be either 0 or 1.</param>
[GenerateSerializer(true)]
[PacketHeader("c_close", PacketSource.Client)]
public record CClosePacket
(
    [PacketIndex(0)]
    byte Unknown
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Client/Login/GameStartPacket.cs => Packets/NosSmooth.Packets/Client/Login/GameStartPacket.cs +24 -0
@@ 0,0 1,24 @@
//
//  GameStartPacket.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 NosSmooth.Packets.Server.Login;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Client.Login;

/// <summary>
/// Start the game.
/// </summary>
/// <remarks>
/// Sent after <see cref="OkPacket"/> that was received
/// after sending <see cref="SelectPacket"/>.
///
/// After <see cref="GameStartPacket"/>, <see cref="LbsPacket"/>
/// should follow.
/// </remarks>
[GenerateSerializer(true)]
[PacketHeader("game_start", PacketSource.Client)]
public record GameStartPacket() : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Client/Login/LbsPacket.cs => Packets/NosSmooth.Packets/Client/Login/LbsPacket.cs +28 -0
@@ 0,0 1,28 @@
//
//  LbsPacket.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 NosSmooth.Packets.Server.Login;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Client.Login;

/// <summary>
/// Function unknown, sent
/// right after <see cref="GameStartPacket"/>.
/// </summary>
/// <remarks>
/// After <see cref="OkPacket"/> was received,
/// <see cref="GameStartPacket"/> and <see cref="LbsPacket"/>
/// should follow.
/// </remarks>
/// <param name="Unknown">Unknown, seems to be always 0.</param>
[PacketHeader("lbs", PacketSource.Client)]
[GenerateSerializer(true)]
public record LbsPacket
(
    [PacketIndex(0)]
    byte Unknown = 0
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Client/Login/SelectPacket.cs => Packets/NosSmooth.Packets/Client/Login/SelectPacket.cs +29 -0
@@ 0,0 1,29 @@
//
//  SelectPacket.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 NosSmooth.Packets.Server.Login;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Client.Login;

/// <summary>
/// Select character on the given slot from <see cref="CListPacket"/>.
/// </summary>
/// <remarks>
/// <see cref="OkPacket"/> should be sent from the server
/// after select.
///
/// Then the client sends <see cref="GameStartPacket"/>
/// and <see cref="LbsPacket"/>.
/// </remarks>
/// <param name="Slot">The slot of the character from clist.</param>
[GenerateSerializer(true)]
[PacketHeader("select", PacketSource.Client)]
public record SelectPacket
(
    [PacketIndex(0)]
    byte Slot
) : IPacket;
\ No newline at end of file

M Packets/NosSmooth.Packets/Enums/Entities/EntityType.cs => Packets/NosSmooth.Packets/Enums/Entities/EntityType.cs +1 -1
@@ 4,7 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.

namespace NosSmooth.Packets.Enums;
namespace NosSmooth.Packets.Enums.Entities;

/// <summary>
/// Type of the entity.

M Packets/NosSmooth.Packets/Enums/Entities/FactionType.cs => Packets/NosSmooth.Packets/Enums/Entities/FactionType.cs +1 -1
@@ 4,7 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.

namespace NosSmooth.Packets.Enums;
namespace NosSmooth.Packets.Enums.Entities;

/// <summary>
/// Faction of an entity.

A Packets/NosSmooth.Packets/Enums/Mates/PartnerSkillRank.cs => Packets/NosSmooth.Packets/Enums/Mates/PartnerSkillRank.cs +53 -0
@@ 0,0 1,53 @@
//
//  PartnerSkillRank.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.

namespace NosSmooth.Packets.Enums.Mates;

/// <summary>
/// Ranks of partner sp skills.
/// </summary>
public enum PartnerSkillRank
{
    /// <summary>
    /// The skills rank must be revealed first.
    /// </summary>
    NotIdentifiedYet = 0,

    /// <summary>
    /// Worst skill rank.
    /// </summary>
    F = 1,

    /// <summary>
    /// E skill rank.
    /// </summary>
    E = 2,

    /// <summary>
    /// D skill rank.
    /// </summary>
    D = 3,

    /// <summary>
    /// C skill rank.
    /// </summary>
    C = 4,

    /// <summary>
    /// B skill rank.
    /// </summary>
    B = 5,

    /// <summary>
    /// A skill rank.
    /// </summary>
    A = 6,

    /// <summary>
    /// Best skill rank.
    /// </summary>
    S = 7
}
\ No newline at end of file

A Packets/NosSmooth.Packets/Enums/Packets/AscrPacketType.cs => Packets/NosSmooth.Packets/Enums/Packets/AscrPacketType.cs +35 -0
@@ 0,0 1,35 @@
//
//  AscrPacketType.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 NosSmooth.Packets.Server.Character;

namespace NosSmooth.Packets.Enums.Packets;

/// <summary>
/// Type of <see cref="AscrPacket"/>.
/// </summary>
public enum AscrPacketType
{
    /// <summary>
    /// Unknown TODO.
    /// </summary>
    Close = -1,

    /// <summary>
    /// Unknown TOOD.
    /// </summary>
    Alone = 0,

    /// <summary>
    /// Unknown TODO.
    /// </summary>
    Group = 1,

    /// <summary>
    /// Unknown TODO.
    /// </summary>
    Family = 2
}
\ No newline at end of file

A Packets/NosSmooth.Packets/Enums/Packets/QSlotType.cs => Packets/NosSmooth.Packets/Enums/Packets/QSlotType.cs +38 -0
@@ 0,0 1,38 @@
//
//  QSlotType.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.

namespace NosSmooth.Packets.Enums.Packets;

/// <summary>
/// Type of a qslot packet.
/// </summary>
public enum QSlotType
{
    /// <summary>
    /// Unknown TODO.
    /// </summary>
    Default = 0,

    /// <summary>
    /// Set the given slot to new value.
    /// </summary>
    Set = 1,

    /// <summary>
    /// Move the given slot item.
    /// </summary>
    Move = 2,

    /// <summary>
    /// Remove the given slot item.
    /// </summary>
    Remove = 3,

    /// <summary>
    /// Reset the given slot.
    /// </summary>
    Reset = 7
}
\ No newline at end of file

M Packets/NosSmooth.Packets/Enums/Players/AuthorityType.cs => Packets/NosSmooth.Packets/Enums/Players/AuthorityType.cs +1 -1
@@ 4,7 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.

namespace NosSmooth.Packets.Enums;
namespace NosSmooth.Packets.Enums.Players;

/// <summary>
/// Authority of a player.

A Packets/NosSmooth.Packets/Enums/Quests/QuestGoalType.cs => Packets/NosSmooth.Packets/Enums/Quests/QuestGoalType.cs +47 -0
@@ 0,0 1,47 @@
//
//  QuestGoalType.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;

#pragma warning disable CS1591
namespace NosSmooth.Packets.Enums.Quests;

/// <summary>
/// A goal type of a quest.
/// </summary>
/// <remarks>
/// Says when the reward may be obtained.
/// </remarks>
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1602:Enumeration items should be documented", Justification = "Too many fields that are self-explanatory.")]
public enum QuestGoalType
{
    Hunt = 1,
    SpecialCollect = 2,
    CollectInRaid = 3,
    Brings = 4,
    CaptureWithoutGettingTheMonster = 5,
    Capture = 6,
    TimesSpace = 7,
    Product = 8,
    NumberOfKill = 9,
    TargetReput = 10,
    TsPoint = 11,
    Dialog1 = 12,
    CollectInTs = 13, // Collect in TimeSpace
    Required = 14,
    Wear = 15,
    Needed = 16,
    Collect = 17, // Collect basic items & quests items
    TransmitGold = 18,
    GoTo = 19,
    CollectMapEntity = 20, // Collect from map entity ( Ice Flower / Water )
    Use = 21,
    Dialog2 = 22,
    UnKnow = 23,
    Inspect = 24,
    WinRaid = 25,
    FlowerQuest = 26,
}
\ No newline at end of file

A Packets/NosSmooth.Packets/Enums/Relations/CharacterRelationType.cs => Packets/NosSmooth.Packets/Enums/Relations/CharacterRelationType.cs +33 -0
@@ 0,0 1,33 @@
//
//  CharacterRelationType.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.

namespace NosSmooth.Packets.Enums.Relations;

/// <summary>
/// Type of character-player relation.
/// </summary>
public enum CharacterRelationType
{
    /// <summary>
    /// The player is blocked.
    /// </summary>
    Blocked = -1,

    /// <summary>
    /// The player is a friend.
    /// </summary>
    Friend = 0,

    /// <summary>
    /// The player is a hidden spouse.
    /// </summary>
    HiddenSpouse = 2,

    /// <summary>
    /// The player is spouse.
    /// </summary>
    Spouse = 5,
}
\ No newline at end of file

M Packets/NosSmooth.Packets/Server/Act4/FcPacket.cs => Packets/NosSmooth.Packets/Server/Act4/FcPacket.cs +1 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Act4;

M Packets/NosSmooth.Packets/Server/Battle/BsPacket.cs => Packets/NosSmooth.Packets/Server/Battle/BsPacket.cs +1 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Battle;

M Packets/NosSmooth.Packets/Server/Battle/SuPacket.cs => Packets/NosSmooth.Packets/Server/Battle/SuPacket.cs +1 -0
@@ 6,6 6,7 @@

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Battle;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Battle;

A Packets/NosSmooth.Packets/Server/Character/AscrPacket.cs => Packets/NosSmooth.Packets/Server/Character/AscrPacket.cs +46 -0
@@ 0,0 1,46 @@
//
//  AscrPacket.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 NosSmooth.Packets.Enums.Packets;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Character statistics (kills, deaths) packet.
/// </summary>
/// <param name="CurrentKill">The current kill count.</param>
/// <param name="CurrentDie">The current die count.</param>
/// <param name="CurrentTc">The current tc count.</param>
/// <param name="ArenaKill">The current arena kill count.</param>
/// <param name="ArenaDie">The current arena die count.</param>
/// <param name="ArenaTc">The current arena tc count.</param>
/// <param name="KillGroup">Unknown TODO.</param>
/// <param name="DieGroup">Unknown TODO.</param>
/// <param name="Type">The type of the ascr packet.</param>
[PacketHeader("ascr", PacketSource.Server)]
[GenerateSerializer(true)]
public record AscrPacket
(
    [PacketIndex(0)]
    int CurrentKill,
    [PacketIndex(1)]
    int CurrentDie,
    [PacketIndex(2)]
    int CurrentTc,
    [PacketIndex(3)]
    int ArenaKill,
    [PacketIndex(4)]
    int ArenaDie,
    [PacketIndex(5)]
    int ArenaTc,
    [PacketIndex(6)]
    int KillGroup,
    [PacketIndex(7)]
    int DieGroup,
    [PacketIndex(8)]
    AscrPacketType? Type
) : IPacket;
\ No newline at end of file

R Packets/NosSmooth.Packets/Server/Players/CInfoPacket.cs => Packets/NosSmooth.Packets/Server/Character/CInfoPacket.cs +1 -2
@@ 4,11 4,10 @@
//  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 NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Players;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Players;
namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Information about the playing character.

A Packets/NosSmooth.Packets/Server/Character/CInfoResetPacket.cs => Packets/NosSmooth.Packets/Server/Character/CInfoResetPacket.cs +30 -0
@@ 0,0 1,30 @@
//
//  CInfoResetPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Reset information about the character
/// (except for stuff from c_info)
/// </summary>
/// <remarks>
/// Sent upon game initialization,
/// seems that it should reset the
/// character information. May be
/// useful when relogging as
/// different character.
///
/// This is sent AFTER c_info,
/// that means not everything from
/// the character should be reset,
/// only fields that are not
/// in c_info.
/// </remarks>
[PacketHeader("c_info_reset", PacketSource.Server)]
[GenerateSerializer(true)]
public record CInfoResetPacket() : IPacket;
\ No newline at end of file

R Packets/NosSmooth.Packets/Server/Players/CModePacket.cs => Packets/NosSmooth.Packets/Server/Character/CModePacket.cs +2 -2
@@ 4,10 4,10 @@
//  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 NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Players;
namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// TODO

R Packets/NosSmooth.Packets/Server/Players/FamilySubPacket.cs => Packets/NosSmooth.Packets/Server/Character/FamilySubPacket.cs +1 -1
@@ 6,7 6,7 @@

using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Players;
namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Sub packet with family information.

A Packets/NosSmooth.Packets/Server/Character/FdPacket.cs => Packets/NosSmooth.Packets/Server/Character/FdPacket.cs +30 -0
@@ 0,0 1,30 @@
//
//  FdPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Reputation and dignity packet.
/// </summary>
/// <param name="Reputation">The character's reputation.</param>
/// <param name="ReputationIcon">The character's reputation icon.</param>
/// <param name="Dignity">The character's dignity.</param>
/// <param name="DignityIcon">The character's dignity icon.</param>
[PacketHeader("fd", PacketSource.Server)]
[GenerateSerializer(true)]
public record FdPacket
(
    [PacketIndex(0)]
    long Reputation,
    [PacketIndex(1)]
    short ReputationIcon,
    [PacketIndex(2)]
    int Dignity,
    [PacketIndex(3)]
    short DignityIcon
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/FsPacket.cs => Packets/NosSmooth.Packets/Server/Character/FsPacket.cs +22 -0
@@ 0,0 1,22 @@
//
//  FsPacket.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 NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Character's faction he belongs to.
/// </summary>
/// <param name="Faction">The faction the character belongs to.</param>
[PacketHeader("fs", PacketSource.Server)]
[GenerateSerializer(true)]
public record FsPacket
(
    [PacketIndex(0)]
    FactionType Faction
) : IPacket;
\ No newline at end of file

R Packets/NosSmooth.Packets/Server/Players/LevPacket.cs => Packets/NosSmooth.Packets/Server/Character/LevPacket.cs +1 -1
@@ 6,7 6,7 @@

using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Players;
namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Sent on map change.

A Packets/NosSmooth.Packets/Server/Character/RagePacket.cs => Packets/NosSmooth.Packets/Server/Character/RagePacket.cs +24 -0
@@ 0,0 1,24 @@
//
//  RagePacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Current rage of the character.
/// </summary>
/// <param name="RagePoints">The rage points.</param>
/// <param name="RagePointsMax">The maximum amount of rage points.</param>
[PacketHeader("rage", PacketSource.Server)]
[GenerateSerializer(true)]
public record RagePacket
(
    [PacketIndex(0)]
    long RagePoints,
    [PacketIndex(1)]
    long RagePointsMax
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/ResistanceSubPacket.cs => Packets/NosSmooth.Packets/Server/Character/ResistanceSubPacket.cs +30 -0
@@ 0,0 1,30 @@
//
//  ResistanceSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// A sub packet containing information about resistance.
/// </summary>
/// <param name="FireResistance">The fire resistance.</param>
/// <param name="WaterResistance">The water resistance.</param>
/// <param name="LightResistance">The light resistance.</param>
/// <param name="DarkResistance">The dark resistance.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record ResistanceSubPacket
(
    [PacketIndex(0)]
    short FireResistance,
    [PacketIndex(1)]
    short WaterResistance,
    [PacketIndex(2)]
    short LightResistance,
    [PacketIndex(3)]
    short DarkResistance
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/RsfiPacket.cs => Packets/NosSmooth.Packets/Server/Character/RsfiPacket.cs +37 -0
@@ 0,0 1,37 @@
//
//  RsfiPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// A packet containing information about act that
/// the client should play story.
/// </summary>
/// <param name="Act">The act.</param>
/// <param name="ActPart">The part of the act.</param>
/// <param name="Unknown1">Unknown TODO.</param>
/// <param name="Unknown2">Unknown TODO.</param>
/// <param name="Ts">Unknown TODO.</param>
/// <param name="TsMax">Unknown TODO.</param>
[PacketHeader("rsfi", PacketSource.Server)]
[GenerateSerializer(true)]
public record RsfiPacket
(
    [PacketIndex(0)]
    byte Act,
    [PacketIndex(1)]
    byte ActPart,
    [PacketIndex(2)]
    byte Unknown1,
    [PacketIndex(3)]
    byte Unknown2,
    [PacketIndex(4)]
    byte Ts,
    [PacketIndex(5)]
    byte TsMax
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/RsfpPacket.cs => Packets/NosSmooth.Packets/Server/Character/RsfpPacket.cs +24 -0
@@ 0,0 1,24 @@
//
//  RsfpPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Unknown. Sent upon world initialization.
/// </summary>
/// <param name="MapX">Unknown TODO.</param>
/// <param name="MapY">Unknown TODO.</param>
[PacketHeader("rsfp", PacketSource.Server)]
[GenerateSerializer(true)]
public record RsfpPacket
(
    [PacketIndex(0)]
    short? MapX,
    [PacketIndex(1)]
    short? MapY
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/ScArmorSubPacket.cs => Packets/NosSmooth.Packets/Server/Character/ScArmorSubPacket.cs +37 -0
@@ 0,0 1,37 @@
//
//  ScArmorSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// A sub packet for <see cref="ScPacket"/>
/// containing information about armor.
/// </summary>
/// <param name="ArmorUpgrade">The upgrade of the armor</param>
/// <param name="MeleeDefence">The melee defence of the armor.</param>
/// <param name="MeleeDefenceDodgeRate">The melee dodge rate of the armor.</param>
/// <param name="RangeDefence">The ranged defence of the armor.</param>
/// <param name="RangeDefenceDodgeRate">The ranged dodge rate of the armor.</param>
/// <param name="MagicalDefence">The magical defence of the armor.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record ScArmorSubPacket
(
    [PacketIndex(0)]
    byte ArmorUpgrade,
    [PacketIndex(1)]
    int MeleeDefence,
    [PacketIndex(2)]
    int MeleeDefenceDodgeRate,
    [PacketIndex(3)]
    int RangeDefence,
    [PacketIndex(4)]
    int RangeDefenceDodgeRate,
    [PacketIndex(5)]
    int MagicalDefence
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/ScPacket.cs => Packets/NosSmooth.Packets/Server/Character/ScPacket.cs +36 -0
@@ 0,0 1,36 @@
//
//  ScPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Information about character's weapons, armor, resistance.
/// </summary>
/// <param name="ClassMinusOne">The class of the character minus one.</param>
/// <param name="MainWeaponSubPacket">The information about character's main weapon.</param>
/// <param name="IsArcher">Whether the character is an archer.</param>
/// <param name="SecondaryWeaponSubPacket">The information about character's secondary weapon.</param>
/// <param name="ArmorSubPacket">The information about character's armor.</param>
/// <param name="ResistanceSubPacket">The character's resistance</param>
[PacketHeader("sc", PacketSource.Server)]
[GenerateSerializer(true)]
public record ScPacket
(
    [PacketIndex(0)]
    byte ClassMinusOne,
    [PacketIndex(1, InnerSeparator = ' ')]
    ScWeaponSubPacket MainWeaponSubPacket,
    [PacketIndex(2)]
    byte IsArcher,
    [PacketIndex(3, InnerSeparator = ' ')]
    ScWeaponSubPacket SecondaryWeaponSubPacket,
    [PacketIndex(4)]
    ScArmorSubPacket ArmorSubPacket,
    [PacketIndex(5)]
    ResistanceSubPacket ResistanceSubPacket
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/ScWeaponSubPacket.cs => Packets/NosSmooth.Packets/Server/Character/ScWeaponSubPacket.cs +37 -0
@@ 0,0 1,37 @@
//
//  ScWeaponSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// A sub packet of <see cref="ScPacket"/>
/// containing information about character's weapon.
/// </summary>
/// <param name="WeaponUpgrade">The upgrade of the weapon.</param>
/// <param name="MinHit">The minimal hit amount.</param>
/// <param name="MaxHit">The maximal hit amount.</param>
/// <param name="HitRate">The hit rate.</param>
/// <param name="CriticalHitRate">The critical hit rate.</param>
/// <param name="CriticalHitMultiplier">The critical hit multiplier.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record ScWeaponSubPacket
(
    [PacketIndex(0)]
    byte WeaponUpgrade,
    [PacketIndex(1)]
    int MinHit,
    [PacketIndex(2)]
    int MaxHit,
    [PacketIndex(3)]
    int HitRate,
    [PacketIndex(4)]
    int CriticalHitRate,
    [PacketIndex(5)]
    int CriticalHitMultiplier
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/TitPacket.cs => Packets/NosSmooth.Packets/Server/Character/TitPacket.cs +31 -0
@@ 0,0 1,31 @@
//
//  TitPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// A packet containing translated class name and the character's name.
/// </summary>
/// <remarks>
/// Sent during initialization.
/// I do not know what purpose of this packet is
/// as the client has all the information from
/// this packet already.
/// </remarks>
/// <param name="TranslatedClass">The class translated in client language.</param>
/// <param name="Name">The name of the client character.</param>
[PacketHeader("tit", PacketSource.Server)]
[GenerateSerializer(true)]
public record TitPacket
(
    [PacketIndex(0)]
    string TranslatedClass,
    [PacketGreedyIndex(1)]
    NameString Name
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/TitinfoPacket.cs => Packets/NosSmooth.Packets/Server/Character/TitinfoPacket.cs +31 -0
@@ 0,0 1,31 @@
//
//  TitinfoPacket.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 NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Information about titles of the character.
/// </summary>
/// <param name="EntityType">The type of the entity, seems to be always a player.</param>
/// <param name="CharacterId">The id of the character.</param>
/// <param name="UnknownTitleVNum1">Unknown, seems to be vnum of title, but which one?</param>
/// <param name="UnknownTitleVnum2">Unknown, seems to be vnum of title, but which one?</param>
[PacketHeader("titinfo", PacketSource.Server)]
[GenerateSerializer(true)]
public record TitinfoPacket
(
    [PacketIndex(0)]
    EntityType EntityType,
    [PacketIndex(1)]
    long CharacterId,
    [PacketIndex(2)]
    long UnknownTitleVNum1,
    [PacketIndex(3)]
    long UnknownTitleVnum2
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/TitlePacket.cs => Packets/NosSmooth.Packets/Server/Character/TitlePacket.cs +21 -0
@@ 0,0 1,21 @@
//
//  TitlePacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// Titles the player has obtained.
/// </summary>
/// <param name="TitleSubPackets">The obtained titles.</param>
[PacketHeader("title", PacketSource.Server)]
[GenerateSerializer(true)]
public record TitlePacket
(
    [PacketListIndex(0, InnerSeparator = '.', ListSeparator = ' ')]
    IReadOnlyList<TitleSubPacket> TitleSubPackets
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Character/TitleSubPacket.cs => Packets/NosSmooth.Packets/Server/Character/TitleSubPacket.cs +25 -0
@@ 0,0 1,25 @@
//
//  TitleSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Character;

/// <summary>
/// A sub packet for <see cref="TitlePacket"/>
/// with information about and obtained title.
/// </summary>
/// <param name="TitleId">The id of the title.</param>
/// <param name="TitleStatus">The status of the title.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record TitleSubPacket
(
    [PacketIndex(0)]
    short TitleId,
    [PacketIndex(1)]
    byte TitleStatus
) : IPacket;
\ No newline at end of file

M Packets/NosSmooth.Packets/Server/Chat/SayPacket.cs => Packets/NosSmooth.Packets/Server/Chat/SayPacket.cs +1 -0
@@ 6,6 6,7 @@

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Chat;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Chat;

M Packets/NosSmooth.Packets/Server/Entities/CondPacket.cs => Packets/NosSmooth.Packets/Server/Entities/CondPacket.cs +1 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Entities;

M Packets/NosSmooth.Packets/Server/Entities/MovePacket.cs => Packets/NosSmooth.Packets/Server/Entities/MovePacket.cs +1 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Entities;

M Packets/NosSmooth.Packets/Server/Entities/StPacket.cs => Packets/NosSmooth.Packets/Server/Entities/StPacket.cs +1 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Entities;

A Packets/NosSmooth.Packets/Server/Families/GidxPacket.cs => Packets/NosSmooth.Packets/Server/Families/GidxPacket.cs +39 -0
@@ 0,0 1,39 @@
//
//  GidxPacket.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 NosSmooth.Packets.Enums.Entities;
using NosSmooth.Packets.Server.Character;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;

namespace NosSmooth.Packets.Server.Families;

/// <summary>
/// Information about player's family.
/// </summary>
/// <param name="EntityType">The type of the entity (always a player).</param>
/// <param name="EntityId">The id of the player.</param>
/// <param name="FamilySubPacket">The sub packet with information about the family, or null, if not in family.</param>
/// <param name="FamilyName">The name of the family.</param>
/// <param name="FamilyCustomRank">The rank of the family.</param>
/// <param name="FamilyIcons">The icons of the family.</param>
[PacketHeader("gidx", PacketSource.Server)]
[GenerateSerializer(true)]
public record GidxPacket
(
    [PacketIndex(0)]
    EntityType EntityType,
    [PacketIndex(1)]
    long EntityId,
    [PacketIndex(2, InnerSeparator = '.')]
    FamilySubPacket FamilySubPacket,
    [PacketIndex(3)]
    NameString? FamilyName,
    [PacketIndex(4)]
    NameString? FamilyCustomRank,
    [PacketListIndex(5, ListSeparator = '|')]
    IReadOnlyList<bool> FamilyIcons
) : IPacket;
\ No newline at end of file

M Packets/NosSmooth.Packets/Server/Groups/PinitSubPacket.cs => Packets/NosSmooth.Packets/Server/Groups/PinitSubPacket.cs +1 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;


M Packets/NosSmooth.Packets/Server/Inventory/EqPacket.cs => Packets/NosSmooth.Packets/Server/Inventory/EqPacket.cs +1 -2
@@ 4,13 4,12 @@
//  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 NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Players;
using NosSmooth.Packets.Server.Maps;
using NosSmooth.Packets.Server.Weapons;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Entities;
namespace NosSmooth.Packets.Server.Inventory;

/// <summary>
/// Player

A Packets/NosSmooth.Packets/Server/Inventory/EquipPacket.cs => Packets/NosSmooth.Packets/Server/Inventory/EquipPacket.cs +28 -0
@@ 0,0 1,28 @@
//
//  EquipPacket.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 NosSmooth.Packets.Server.Weapons;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Inventory;

/// <summary>
/// Information about the player's equipped items.
/// </summary>
/// <param name="WeaponUpgradeRareSubPacket">The main weapon upgrade rare.</param>
/// <param name="ArmorUpgradeRareSubPacket">The armor upgrade rare.</param>
/// <param name="EquipSubPacket">The packet with equipment.</param>
[PacketHeader("equip", PacketSource.Server)]
[GenerateSerializer(true)]
public record EquipPacket
(
    [PacketIndex(0)]
    UpgradeRareSubPacket WeaponUpgradeRareSubPacket,
    [PacketIndex(1)]
    UpgradeRareSubPacket ArmorUpgradeRareSubPacket,
    [PacketListIndex(2, ListSeparator = ' ', InnerSeparator = '.')]
    IReadOnlyList<EquipSubPacket> EquipSubPacket
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Inventory/EquipSubPacket.cs => Packets/NosSmooth.Packets/Server/Inventory/EquipSubPacket.cs +37 -0
@@ 0,0 1,37 @@
//
//  EquipSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Inventory;

/// <summary>
/// A sub packet for <see cref="EquipPacket"/>
/// containing information about individual items equipped.
/// </summary>
/// <param name="Slot">The equipment slot.</param>
/// <param name="ItemVNum">The vnum of the item.</param>
/// <param name="Rare">The rare.</param>
/// <param name="DesignOrRare">Can be design for colored items, otherwise upgrade.</param>
/// <param name="Unknown">Unknown TODO. Seems to be always 0.</param>
/// <param name="RuneCount">The count of runes.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record EquipSubPacket
(
    [PacketIndex(0)]
    byte Slot,
    [PacketIndex(1)]
    long ItemVNum,
    [PacketIndex(2)]
    byte? Rare,
    [PacketIndex(3)]
    short DesignOrRare,
    [PacketIndex(4)]
    byte Unknown,
    [PacketIndex(5)]
    int RuneCount
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Inventory/ExtsPacket.cs => Packets/NosSmooth.Packets/Server/Inventory/ExtsPacket.cs +32 -0
@@ 0,0 1,32 @@
//
//  ExtsPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Inventory;

/// <summary>
/// Inventory extensions (slots) of the player.
/// Each field contains the number of slots
/// in the given inventory bag.
/// </summary>
/// <param name="Type">Unknown TODO.</param>
/// <param name="EquipmentSlots">The number of slots in equipment bag.</param>
/// <param name="MainSlots">The number of slots in main bag.</param>
/// <param name="EtcSlots">The number of slots in etc bag.</param>
[PacketHeader("exts", PacketSource.Server)]
[GenerateSerializer(true)]
public record ExtsPacket
(
    [PacketIndex(0)]
    byte Type,
    [PacketIndex(1)]
    byte EquipmentSlots,
    [PacketIndex(2)]
    byte MainSlots,
    [PacketIndex(3)]
    byte EtcSlots
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Inventory/GoldPacket.cs => Packets/NosSmooth.Packets/Server/Inventory/GoldPacket.cs +24 -0
@@ 0,0 1,24 @@
//
//  GoldPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Inventory;

/// <summary>
/// Amount of gold the character has.
/// </summary>
/// <param name="Gold">The amount of gold the character has.</param>
/// <param name="Unknown">Unknown TODO.</param>
[PacketHeader("gold", PacketSource.Server)]
[GenerateSerializer(true)]
public record GoldPacket
(
    [PacketIndex(0)]
    long Gold,
    [PacketIndex(1)]
    byte Unknown
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Inventory/PairyPacket.cs => Packets/NosSmooth.Packets/Server/Inventory/PairyPacket.cs +38 -0
@@ 0,0 1,38 @@
//
//  PairyPacket.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 NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Inventory;

/// <summary>
/// Information about a fairy of an entity.
/// </summary>
/// <param name="EntityType">The entity type.</param>
/// <param name="EntityId">The id of the entity.</param>
/// <param name="MoveType">The fairy's move type.</param>
/// <param name="Element">The fairy's element.</param>
/// <param name="ElementRate">The fairy's element rate.</param>
/// <param name="MorphVNum">The fairy's morph vnum.</param>
[PacketHeader("pairy", PacketSource.Server)]
[GenerateSerializer(true)]
public record PairyPacket
(
    [PacketIndex(0)]
    EntityType EntityType,
    [PacketIndex(1)]
    long EntityId,
    [PacketIndex(2)]
    int MoveType,
    [PacketIndex(3)]
    Element Element,
    [PacketIndex(4)]
    int ElementRate,
    [PacketIndex(5)]
    int MorphVNum
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Login/CListEndPacket.cs => Packets/NosSmooth.Packets/Server/Login/CListEndPacket.cs +21 -0
@@ 0,0 1,21 @@
//
//  CListEndPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Login;

/// <summary>
/// End of character list.
/// </summary>
/// <remarks>
/// Before clist, clist_start will be sent.
/// clist for each character will follow,
/// after that, clist_end will be sent.
/// </remarks>
[GenerateSerializer(true)]
[PacketHeader("clist_end", PacketSource.Server)]
public record CListEndPacket() : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Login/CListEquipmentSubPacket.cs => Packets/NosSmooth.Packets/Server/Login/CListEquipmentSubPacket.cs +44 -0
@@ 0,0 1,44 @@
//
//  CListEquipmentSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Login;

/// <summary>
/// Sub packet of <see cref="CListEquipmentSubPacket"/> present if the in packet
/// is for a player. Contains information about the player's
/// weapon.
/// /// </summary>
/// <param name="HatVNum">The VNum of the hat.</param>
/// <param name="ArmorVNum">The VNum of the armor.</param>
/// <param name="MainWeaponSkinOrWeaponVNum">The vnum of skin of the weapon or main weapon vnum.</param>
/// <param name="SecondaryWeaponVNum">The VNum of the secondary weapon.</param>
/// <param name="MaskVNum">The VNum of the mask.</param>
/// <param name="FairyVNum">The VNum of the fairy item.</param>
/// <param name="CostumeSuitVNum">The VNum of the costume suit.</param>
/// <param name="CostumeHatVNum">The VNum of the costume hat.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record CListEquipmentSubPacket
(
    [PacketIndex(0)]
    int? HatVNum,
    [PacketIndex(1)]
    int? ArmorVNum,
    [PacketIndex(2)]
    int? MainWeaponSkinOrWeaponVNum,
    [PacketIndex(3)]
    int? SecondaryWeaponVNum,
    [PacketIndex(4)]
    int? MaskVNum,
    [PacketIndex(5)]
    int? FairyVNum,
    [PacketIndex(6)]
    int? CostumeSuitVNum,
    [PacketIndex(7)]
    int? CostumeHatVNum
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Login/CListPacket.cs => Packets/NosSmooth.Packets/Server/Login/CListPacket.cs +81 -0
@@ 0,0 1,81 @@
//
//  CListPacket.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 NosSmooth.Packets.Enums.Players;
using NosSmooth.Packets.Server.Maps;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;

namespace NosSmooth.Packets.Server.Login;

/// <summary>
/// Contains information about a character in character
/// slect upon login.
/// </summary>
/// <remarks>
/// Before clist, clist_start will be sent.
/// clist for each character will follow,
/// after that, clist_end will be sent.
/// </remarks>
/// <param name="Slot">The character slot the character is from.</param>
/// <param name="Name">The name of the character.</param>
/// <param name="Unknown">Unknown, seems to be always 0.</param>
/// <param name="Sex">The sex of the character.</param>
/// <param name="HairStyle">The hair style of the character.</param>
/// <param name="HairColor">The hair color of the character.</param>
/// <param name="Unknown1">Unknown, seems to be always 0.</param>
/// <param name="Class">The class of the character.</param>
/// <param name="Level">The level of the character.</param>
/// <param name="HeroLevel">The hero level of the character.</param>
/// <param name="EquipmentSubPacket">The equipment of the player.</param>
/// <param name="JobLevel">The job level of the character.</param>
/// <param name="ExtraSpace">There is an extra space in the packet, for the converter to work correctly, this should be an empty string. TODO add Prefix field to PacketIndex and put Prefix ' ' on Unknown2.</param>
/// <param name="Unknown2">Unknown, seems to be always 1.</param>
/// <param name="Unknown3">Unknown, seems to be always 1.</param>
/// <param name="PetsSubPacket">The pets of the character.</param>
/// <param name="HatDesign">The design of the hat.</param>
/// <param name="Unknown4">Unknown, seems to be always 0.</param>
[GenerateSerializer(true)]
[PacketHeader("clist", PacketSource.Server)]
public record CListPacket
(
    [PacketIndex(0)]
    byte Slot,
    [PacketIndex(1)]
    NameString Name,
    [PacketIndex(2)]
    byte Unknown,
    [PacketIndex(3)]
    SexType Sex,
    [PacketIndex(4)]
    HairStyle HairStyle,
    [PacketIndex(5)]
    HairColor HairColor,
    [PacketIndex(6)]
    byte Unknown1,
    [PacketIndex(7)]
    PlayerClass Class,
    [PacketIndex(8)]
    byte Level,
    [PacketIndex(9)]
    byte HeroLevel,
    [PacketIndex(10, InnerSeparator = '.')]
    CListEquipmentSubPacket EquipmentSubPacket,
    [PacketIndex(11)]
    byte JobLevel,
    [PacketIndex(12)]
    string ExtraSpace,
    [PacketIndex(13)]
    byte Unknown2,
    [PacketIndex(14)]
    byte Unknown3,
    [PacketListIndex(15, ListSeparator = '.', InnerSeparator = '.')]
    IReadOnlyList<CListPetSubPacket> PetsSubPacket,
    [PacketIndex(16)]
    byte HatDesign,
    [PacketIndex(17)]
    byte Unknown4
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Login/CListPetSubPacket.cs => Packets/NosSmooth.Packets/Server/Login/CListPetSubPacket.cs +24 -0
@@ 0,0 1,24 @@
//
//  CListPetSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Login;

/// <summary>
/// An item of pet list inside of <see cref="CListPacket"/>.
/// </summary>
/// <param name="Skin">Skin of partner.</param>
/// <param name="PetVNum">The vnum of the pet.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record CListPetSubPacket
(
    [PacketIndex(0)]
    long? Skin,
    [PacketIndex(1)]
    long? PetVNum
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Login/CListStartPacket.cs => Packets/NosSmooth.Packets/Server/Login/CListStartPacket.cs +26 -0
@@ 0,0 1,26 @@
//
//  CListStartPacket.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 NosSmooth.Packets.Server.Groups;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Login;

/// <summary>
/// Signals start of character list.
/// </summary>
/// <remarks>
/// clist for each character will follow,
/// after that clist_end will be sent.
/// </remarks>
/// <param name="Unknown">Unknown, seems to be always 0.</param>
[GenerateSerializer(true)]
[PacketHeader("clist_start", PacketSource.Server)]
public record CListStartPacket
(
    [PacketIndex(0)]
    int Unknown = 0
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Login/FStashEndPacket.cs => Packets/NosSmooth.Packets/Server/Login/FStashEndPacket.cs +16 -0
@@ 0,0 1,16 @@
//
//  FStashEndPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Login;

/// <summary>
/// Unknown function.
/// </summary>
[PacketHeader("f_stash_end", PacketSource.Server)]
[GenerateSerializer(true)]
public record FStashEndPacket() : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Login/OkPacket.cs => Packets/NosSmooth.Packets/Server/Login/OkPacket.cs +20 -0
@@ 0,0 1,20 @@
//
//  OkPacket.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 NosSmooth.Packets.Client.Login;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Login;

/// <summary>
/// The selection of character is approved.
/// </summary>
/// <remarks>
/// Sent after <see cref="SelectPacket"/>.
/// </remarks>
[PacketHeader("OK", PacketSource.Server)]
[GenerateSerializer(true)]
public record OkPacket() : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Maps/Bgm2Packet.cs => Packets/NosSmooth.Packets/Server/Maps/Bgm2Packet.cs +21 -0
@@ 0,0 1,21 @@
//
//  Bgm2Packet.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Maps;

/// <summary>
/// A music to be played.
/// </summary>
/// <param name="MusicId">The id of the music to be played.</param>
[PacketHeader("bgm2", PacketSource.Server)]
[GenerateSerializer(true)]
public record Bgm2Packet
(
    [PacketIndex(0)]
    long MusicId
) : IPacket;
\ No newline at end of file

M Packets/NosSmooth.Packets/Server/Maps/InPacket.cs => Packets/NosSmooth.Packets/Server/Maps/InPacket.cs +1 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;


M Packets/NosSmooth.Packets/Server/Maps/InPlayerSubPacket.cs => Packets/NosSmooth.Packets/Server/Maps/InPlayerSubPacket.cs +3 -2
@@ 5,8 5,9 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.Packets.Enums.Players;
using NosSmooth.Packets.Server.Players;
using NosSmooth.Packets.Server.Character;
using NosSmooth.Packets.Server.Weapons;
using NosSmooth.PacketSerializer.Abstractions.Attributes;



@@ 84,7 85,7 @@ public record InPlayerSubPacket
    [PacketIndex(14)]
    byte Unknown2,
    [PacketIndex(15)]
    byte Unknown3,
    short Unknown3,
    [PacketIndex(16)]
    UpgradeRareSubPacket WeaponUpgradeRareSubPacket,
    [PacketIndex(17)]

M Packets/NosSmooth.Packets/Server/Maps/OutPacket.cs => Packets/NosSmooth.Packets/Server/Maps/OutPacket.cs +1 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Maps;

A Packets/NosSmooth.Packets/Server/Mates/ScNEquipmentSubPacket.cs => Packets/NosSmooth.Packets/Server/Mates/ScNEquipmentSubPacket.cs +29 -0
@@ 0,0 1,29 @@
//
//  ScNEquipmentSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Mates;

/// <summary>
/// A sub packet of <see cref="ScNPacket"/>
/// containing information about partner's
/// equipped item.
/// </summary>
/// <param name="ItemVNum"></param>
/// <param name="ItemRare"></param>
/// <param name="ItemUpgrade"></param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record ScNEquipmentSubPacket
(
    [PacketIndex(0)]
    long? ItemVNum,
    [PacketIndex(1, IsOptional = true)]
    long? ItemRare,
    [PacketIndex(2, IsOptional = true)]
    long? ItemUpgrade
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Mates/ScNPacket.cs => Packets/NosSmooth.Packets/Server/Mates/ScNPacket.cs +143 -0
@@ 0,0 1,143 @@
//
//  ScNPacket.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 NosSmooth.Packets.Enums;
using NosSmooth.Packets.Server.Character;
using NosSmooth.Packets.Server.Maps;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;

namespace NosSmooth.Packets.Server.Mates;

/// <summary>
/// Information about a partner the
/// character owns.
/// </summary>
/// <param name="PartnerId">The id of the partner entity.</param>
/// <param name="NpcVNum">The vnum of the partner.</param>
/// <param name="TransportId">Unknown TODO.</param>
/// <param name="Level">The level of the partner.</param>
/// <param name="Loyalty">The loyalty of the partner.</param>
/// <param name="Experience">The experience of the partner.</param>
/// <param name="WeaponSubPacket">Information about partner's weapon.</param>
/// <param name="ArmodSubPacket">Information about partner's armor.</param>
/// <param name="GauntletSubPacket">Information about partner's gauntlet.</param>
/// <param name="BootsSubPacket">Information about partner's boots.</param>
/// <param name="Unknown1">Unknown TODO.</param>
/// <param name="Unknown2">Unknown TODO.</param>
/// <param name="Unknown3">Unknown TODO.</param>
/// <param name="AttackUpgrade">The upgrade of attack.</param>
/// <param name="MinimumAttack">The minimum attack amount.</param>
/// <param name="MaximumAttack">The maximum attack amount.</param>
/// <param name="Precision">Unknown TODO.</param>
/// <param name="CriticalChance">The critical chance of the partner's hit.</param>
/// <param name="CriticalRate">The critical rate of the partner's hit.</param>
/// <param name="DefenceUpgrade">The partner's defence upgrade.</param>
/// <param name="MeleeDefence">The melee defence.</param>
/// <param name="MeleeDefenceDodge">The dodge of melee defence.</param>
/// <param name="RangeDefence">The ranged defence.</param>
/// <param name="RangeDodgeRate">The dodge of ranged defence.</param>
/// <param name="MagicalDefence">The magical defence.</param>
/// <param name="Element">The element of the partner.</param>
/// <param name="ResistanceSubPacket">Information about partner's resistance</param>
/// <param name="Hp">The current hp of the partner.</param>
/// <param name="HpMax">The maximum hp of the partner.</param>
/// <param name="Mp">The current mp of the partner.</param>
/// <param name="MpMax">The maximum mp of the partner.</param>
/// <param name="Unknown4">Unknown TODO.</param>
/// <param name="LevelExperience">The maximum experience in current level of the partner.</param>
/// <param name="Name">The name of the partner.</param>
/// <param name="MorphVNum">The morph vnum of the partner, if any.</param>
/// <param name="IsSummonable">Whether the partner is summonable.</param>
/// <param name="SpSubPacket">The currently equipped sp of the partner.</param>
/// <param name="Skill1SubPacket">Information about first skill of the partner's sp.</param>
/// <param name="Skill2SubPacket">Information about second skill of the partner's sp.</param>
/// <param name="Skill3SubPacket">Information about third skill of the partner's sp.</param>
[PacketHeader("sc_n", PacketSource.Server)]
[GenerateSerializer(true)]
public record ScNPacket
(
    [PacketIndex(0)]
    long PartnerId,
    [PacketIndex(1)]
    long NpcVNum,
    [PacketIndex(2)]
    long TransportId,
    [PacketIndex(3)]
    short Level,
    [PacketIndex(4)]
    short Loyalty,
    [PacketIndex(5)]
    long Experience,
    [PacketIndex(6, InnerSeparator = '.')]
    ScNEquipmentSubPacket? WeaponSubPacket,
    [PacketIndex(7, InnerSeparator = '.')]
    ScNEquipmentSubPacket? ArmodSubPacket,
    [PacketIndex(8, InnerSeparator = '.')]
    ScNEquipmentSubPacket? GauntletSubPacket,
    [PacketIndex(9, InnerSeparator = '.')]
    ScNEquipmentSubPacket? BootsSubPacket,
    [PacketIndex(10, InnerSeparator = '.')]
    short Unknown1,
    [PacketIndex(11)]
    short Unknown2,
    [PacketIndex(12)]
    short Unknown3,
    [PacketIndex(13)]
    short AttackUpgrade,
    [PacketIndex(14)]
    int MinimumAttack,
    [PacketIndex(15)]
    int MaximumAttack,
    [PacketIndex(16)]
    int Precision,
    [PacketIndex(17)]
    int CriticalChance,
    [PacketIndex(18)]
    int CriticalRate,
    [PacketIndex(19)]
    short DefenceUpgrade,
    [PacketIndex(20)]
    int MeleeDefence,
    [PacketIndex(21)]
    int MeleeDefenceDodge,
    [PacketIndex(22)]
    int RangeDefence,
    [PacketIndex(23)]
    int RangeDodgeRate,
    [PacketIndex(24)]
    int MagicalDefence,
    [PacketIndex(25)]
    Element Element,
    [PacketIndex(26, InnerSeparator = ' ')]
    ResistanceSubPacket ResistanceSubPacket,
    [PacketIndex(27)]
    int Hp,
    [PacketIndex(28)]
    int HpMax,
    [PacketIndex(29)]
    int Mp,
    [PacketIndex(30)]
    int MpMax,
    [PacketIndex(31)]
    int Unknown4,
    [PacketIndex(32)]
    int LevelExperience,
    [PacketIndex(33)]
    NameString Name,
    [PacketIndex(34)]
    int? MorphVNum,
    [PacketIndex(35)]
    bool IsSummonable,
    [PacketIndex(36, InnerSeparator = '.')]
    ScNSpSubPacket? SpSubPacket,
    [PacketIndex(37, InnerSeparator = '.')]
    ScNSkillSubPacket? Skill1SubPacket,
    [PacketIndex(38, InnerSeparator = '.')]
    ScNSkillSubPacket? Skill2SubPacket,
    [PacketIndex(39, InnerSeparator = '.')]
    ScNSkillSubPacket? Skill3SubPacket
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Mates/ScNSkillSubPacket.cs => Packets/NosSmooth.Packets/Server/Mates/ScNSkillSubPacket.cs +27 -0
@@ 0,0 1,27 @@
//
//  ScNSkillSubPacket.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 NosSmooth.Packets.Enums.Mates;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Mates;

/// <summary>
/// A sub packet of <see cref="ScNPacket"/>
/// containing information about partner's
/// sp skill.
/// </summary>
/// <param name="SkillVNum">The vnum of the skill.</param>
/// <param name="Rank">The rank of the skill.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record ScNSkillSubPacket
(
    [PacketIndex(0)]
    long? SkillVNum,
    [PacketIndex(1, IsOptional = true)]
    PartnerSkillRank? Rank
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Mates/ScNSpSubPacket.cs => Packets/NosSmooth.Packets/Server/Mates/ScNSpSubPacket.cs +26 -0
@@ 0,0 1,26 @@
//
//  ScNSpSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Mates;

/// <summary>
/// A sub packet of <see cref="ScNPacket"/>
/// containing information about sp of the
/// partner.
/// </summary>
/// <param name="ItemVNum"></param>
/// <param name="AgilityPercentage"></param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record ScNSpSubPacket
(
    [PacketIndex(0)]
    long? ItemVNum,
    [PacketIndex(1, IsOptional = true)]
    byte? AgilityPercentage
);
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Mates/ScPPacket.cs => Packets/NosSmooth.Packets/Server/Mates/ScPPacket.cs +112 -0
@@ 0,0 1,112 @@
//
//  ScPPacket.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 NosSmooth.Packets.Enums;
using NosSmooth.Packets.Server.Character;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;

namespace NosSmooth.Packets.Server.Mates;

/// <summary>
/// Information about a pet the
/// character owns.
/// </summary>
/// <param name="PetId">The id of the pet entity.</param>
/// <param name="NpcVNum">The vnum of the pet.</param>
/// <param name="TransportId">Unknown TODO.</param>
/// <param name="Level">The level of the pet.</param>
/// <param name="Loyalty">The loyalty of the pet.</param>
/// <param name="Experience">The experience of the pet.</param>
/// <param name="Unknown1">Unknown TODO.</param>
/// <param name="AttackUpgrade">The upgrade of attack.</param>
/// <param name="MinimumAttack">The minimum attack amount.</param>
/// <param name="MaximumAttack">The maximum attack amount.</param>
/// <param name="Concentrate">Unknown TODO.</param>
/// <param name="CriticalChance">The critical chance of the pet's hit.</param>
/// <param name="CriticalRate">The critical rate of the pet's hit.</param>
/// <param name="DefenceUpgrade">The pet's defence upgrade.</param>
/// <param name="MeleeDefence">The melee defence.</param>
/// <param name="MeleeDefenceDodge">The dodge of melee defence.</param>
/// <param name="RangeDefence">The ranged defence.</param>
/// <param name="RangeDodgeRate">The dodge of ranged defence.</param>
/// <param name="MagicalDefence">The magical defence.</param>
/// <param name="Element">The element of the pet.</param>
/// <param name="ResistanceSubPacket">Information about pet's resistance</param>
/// <param name="Hp">The current hp of the pet.</param>
/// <param name="HpMax">The maximum hp of the pet.</param>
/// <param name="Mp">The current mp of the pet.</param>
/// <param name="MpMax">The maximum mp of the pet.</param>
/// <param name="Unknown4">Unknown TODO.</param>
/// <param name="LevelExperience">The maximum experience in current level of the pet.</param>
/// <param name="CanPickUp">Whether the pet can pick up stuff.</param>
/// <param name="Name">The name of the pet.</param>
/// <param name="IsSummonable">Whether the pet is summonable.</param>
[PacketHeader("sc_p", PacketSource.Server)]
[GenerateSerializer(true)]
public record ScPPacket
(
    [PacketIndex(0)]
    long PetId,
    [PacketIndex(1)]
    long NpcVNum,
    [PacketIndex(2)]
    long TransportId,
    [PacketIndex(3)]
    short Level,
    [PacketIndex(4)]
    short Loyalty,
    [PacketIndex(5)]
    long Experience,
    [PacketIndex(6)]
    short Unknown1,
    [PacketIndex(7)]
    short AttackUpgrade,
    [PacketIndex(8)]
    int MinimumAttack,
    [PacketIndex(9)]
    int MaximumAttack,
    [PacketIndex(10)]
    int Concentrate,
    [PacketIndex(11)]
    int CriticalChance,
    [PacketIndex(12)]
    int CriticalRate,
    [PacketIndex(13)]
    short DefenceUpgrade,
    [PacketIndex(14)]
    int MeleeDefence,
    [PacketIndex(15)]
    int MeleeDefenceDodge,
    [PacketIndex(16)]
    int RangeDefence,
    [PacketIndex(17)]
    int RangeDodgeRate,
    [PacketIndex(18)]
    int MagicalDefence,
    [PacketIndex(19)]
    Element Element,
    [PacketIndex(20, InnerSeparator = ' ')]
    ResistanceSubPacket ResistanceSubPacket,
    [PacketIndex(21)]
    int Hp,
    [PacketIndex(22)]
    int HpMax,
    [PacketIndex(23)]
    int Mp,
    [PacketIndex(24)]
    int MpMax,
    [PacketIndex(25)]
    int Unknown4,
    [PacketIndex(26)]
    int LevelExperience,
    [PacketIndex(27)]
    bool CanPickUp,
    [PacketIndex(28)]
    NameString Name,
    [PacketIndex(29)]
    bool IsSummonable
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Npc/ShopPacket.cs => Packets/NosSmooth.Packets/Server/Npc/ShopPacket.cs +39 -0
@@ 0,0 1,39 @@
//
//  ShopPacket.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 NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;

namespace NosSmooth.Packets.Server.Npc;

/// <summary>
/// A shop on the map.
/// </summary>
/// <param name="EntityType">The type of the entity.</param>
/// <param name="EntityVNum">The entity vnum.</param>
/// <param name="ShopId">The id of the shop.</param>
/// <param name="MenuType">The menu type, unknown values.</param>
/// <param name="ShopType">The shop type, unkonwn values.</param>
/// <param name="Name">The name of the shop. (shown above the NPC)</param>
[PacketHeader("shop", PacketSource.Server)]
[GenerateSerializer(true)]
public record ShopPacket
(
    [PacketIndex(0)]
    EntityType EntityType,
    [PacketIndex(1)]
    long EntityVNum,
    [PacketIndex(2)]
    long ShopId,
    [PacketIndex(3)]
    byte MenuType,
    [PacketIndex(4, IsOptional = true)]
    byte? ShopType,
    [PacketGreedyIndex(5, IsOptional = true)]
    NameString? Name
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Quests/QstListObjectiveSubPacket.cs => Packets/NosSmooth.Packets/Server/Quests/QstListObjectiveSubPacket.cs +26 -0
@@ 0,0 1,26 @@
//
//  QstListObjectiveSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Quests;

/// <summary>
/// A sub packet of <see cref="QstListPacket"/>
/// containing information about a quest
/// objective.
/// </summary>
/// <param name="CurrentCount"></param>
/// <param name="MaxCount"></param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record QstListObjectiveSubPacket
(
    [PacketIndex(0)]
    short CurrentCount,
    [PacketIndex(1)]
    short MaxCount
);
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Quests/QstListPacket.cs => Packets/NosSmooth.Packets/Server/Quests/QstListPacket.cs +22 -0
@@ 0,0 1,22 @@
//
//  QstListPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Quests;

/// <summary>
/// A list of quests
/// that are currently active.
/// </summary>
/// <param name="QuestSubPackets">The list of the active quests.</param>
[PacketHeader("qstlist", PacketSource.Server)]
[GenerateSerializer(true)]
public record QstListPacket
(
    [PacketListIndex(0, InnerSeparator = '.', ListSeparator = ' ')]
    IReadOnlyList<QstListSubPacket> QuestSubPackets
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Quests/QstListSubPacket.cs => Packets/NosSmooth.Packets/Server/Quests/QstListSubPacket.cs +53 -0
@@ 0,0 1,53 @@
//
//  QstListSubPacket.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 NosSmooth.Packets.Enums.Quests;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Quests;

/// <summary>
/// A sub packet of <see cref="QstListPacket"/>
/// containing information about an active quest.
/// </summary>
/// <param name="QuestNumber">The number of the quest.</param>
/// <param name="InfoId">The info id of the quest to obtain it from .NOS files.</param>
/// <param name="InfoId2">Unknown TODO.</param>
/// <param name="GoalType">The quest goal type.</param>
/// <param name="Objective1SubPacket">The first objective of the quest.</param>
/// <param name="IsQuestFinished"></param>
/// <param name="Objective2SubPacket">The second objective of the quest.</param>
/// <param name="Objective3SubPacket">The third objective of the quest.</param>
/// <param name="Objective4SubPacket">The fourth objective of the quest.</param>
/// <param name="Objective5SubPacket">The fifth objective of the quest.</param>
/// <param name="ShowDialog">Whether to show dialog at start of the quest.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record QstListSubPacket
(
    [PacketIndex(0)]
    short QuestNumber,
    [PacketIndex(1)]
    short InfoId,
    [PacketIndex(2)]
    short InfoId2,
    [PacketIndex(3)]
    QuestGoalType GoalType,
    [PacketIndex(4, InnerSeparator = '.')]
    QstListObjectiveSubPacket Objective1SubPacket,
    [PacketIndex(5)]
    bool IsQuestFinished,
    [PacketIndex(6, InnerSeparator = '.')]
    QstListObjectiveSubPacket Objective2SubPacket,
    [PacketIndex(7, InnerSeparator = '.')]
    QstListObjectiveSubPacket Objective3SubPacket,
    [PacketIndex(8, InnerSeparator = '.')]
    QstListObjectiveSubPacket Objective4SubPacket,
    [PacketIndex(9, InnerSeparator = '.')]
    QstListObjectiveSubPacket Objective5SubPacket,
    [PacketIndex(10)]
    bool ShowDialog
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Quicklist/QSlotPacket.cs => Packets/NosSmooth.Packets/Server/Quicklist/QSlotPacket.cs +24 -0
@@ 0,0 1,24 @@
//
//  QSlotPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Quicklist;

/// <summary>
/// Quicklist slot information. (skills, items in quick list)
/// </summary>
/// <param name="Slot">The slot the information is about.</param>
/// <param name="DataSubPacket">The data (skills, items) in the slot.</param>
[PacketHeader("qslot", PacketSource.Server)]
[GenerateSerializer(true)]
public record QSlotPacket
(
    [PacketIndex(0)]
    byte Slot,
    [PacketListIndex(1, InnerSeparator = '.', ListSeparator = ' ')]
    IReadOnlyList<QSlotSubPacket> DataSubPacket
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Quicklist/QSlotSubPacket.cs => Packets/NosSmooth.Packets/Server/Quicklist/QSlotSubPacket.cs +32 -0
@@ 0,0 1,32 @@
//
//  QSlotSubPacket.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 NosSmooth.Packets.Enums.Packets;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Quicklist;

/// <summary>
/// A sub packet of <see cref="QSlotPacket"/>
/// containing information about an operation for a box in the slot.
/// </summary>
/// <param name="Type">The type of the operation.</param>
/// <param name="Slot">Unknown TODO.</param>
/// <param name="Position">Unknown TODO.</param>
/// <param name="Data">Unknown TODO.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record QSlotSubPacket
(
    [PacketIndex(0)]
    QSlotType Type,
    [PacketIndex(1)]
    short? Slot,
    [PacketIndex(2)]
    short? Position,
    [PacketIndex(3, IsOptional = true)]
    short? Data
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Relations/FInfoPacket.cs => Packets/NosSmooth.Packets/Server/Relations/FInfoPacket.cs +21 -0
@@ 0,0 1,21 @@
//
//  FInfoPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Relations;

/// <summary>
/// Information about friends of a character.
/// </summary>
/// <param name="FriendSubPackets">The friends list.</param>
[PacketHeader("finfo", PacketSource.Server)]
[GenerateSerializer(true)]
public record FInfoPacket
(
    [PacketListIndex(0, InnerSeparator = '.', ListSeparator = ' ')]
    IReadOnlyList<FInfoSubPacket> FriendSubPackets
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Relations/FInfoSubPacket.cs => Packets/NosSmooth.Packets/Server/Relations/FInfoSubPacket.cs +29 -0
@@ 0,0 1,29 @@
//
//  FInfoSubPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;

namespace NosSmooth.Packets.Server.Relations;

/// <summary>
/// A sub packet of <see cref="FInfoPacket"/>
/// containing information about a friend.
/// </summary>
/// <param name="PlayerId">The id of the friend.</param>
/// <param name="IsConnected">Whether the friend is connected.</param>
/// <param name="Name">The name of the friend.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record FInfoSubPacket
(
    [PacketIndex(0)]
    long PlayerId,
    [PacketIndex(1)]
    bool IsConnected,
    [PacketIndex(2)]
    NameString Name
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Relations/FInitPacket.cs => Packets/NosSmooth.Packets/Server/Relations/FInitPacket.cs +21 -0
@@ 0,0 1,21 @@
//
//  FInitPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.Relations;

/// <summary>
/// Information about friends (and other relations) of a character.
/// </summary>
/// <param name="FriendSubPackets"></param>
[PacketHeader("finit", PacketSource.Server)]
[GenerateSerializer(true)]
public record FInitPacket
(
    [PacketListIndex(0, InnerSeparator = '|', ListSeparator = ' ')]
    IReadOnlyList<FInitSubPacket> FriendSubPackets
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/Relations/FInitSubPacket.cs => Packets/NosSmooth.Packets/Server/Relations/FInitSubPacket.cs +33 -0
@@ 0,0 1,33 @@
//
//  FInitSubPacket.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 NosSmooth.Packets.Enums.Relations;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;

namespace NosSmooth.Packets.Server.Relations;

/// <summary>
/// A sub packet of <see cref="FInitSubPacket"/>
/// containing information about a friend.
/// </summary>
/// <param name="PlayerId">The id of the friend.</param>
/// <param name="RelationType">The relation between character-player.</param>
/// <param name="IsConnected">Whether the friend is connected.</param>
/// <param name="Name">The name of the friend.</param>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record FInitSubPacket
(
    [PacketIndex(0)]
    long PlayerId,
    [PacketIndex(1)]
    CharacterRelationType? RelationType,
    [PacketIndex(2)]
    bool IsConnected,
    [PacketIndex(3)]
    NameString Name
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/UI/Act6Packet.cs => Packets/NosSmooth.Packets/Server/UI/Act6Packet.cs +16 -0
@@ 0,0 1,16 @@
//
//  Act6Packet.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 NosSmooth.PacketSerializer.Abstractions.Attributes;

namespace NosSmooth.Packets.Server.UI;

/// <summary>
/// Unknown TODO.
/// </summary>
[PacketHeader(null, PacketSource.Server)]
[GenerateSerializer(true)]
public record Act6Packet() : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/UI/BnPacket.cs => Packets/NosSmooth.Packets/Server/UI/BnPacket.cs +29 -0
@@ 0,0 1,29 @@
//
//  BnPacket.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 NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;

namespace NosSmooth.Packets.Server.UI;

/// <summary>
/// A broadcast message.
/// </summary>
/// <remarks>
/// In the client this is shown on bottom left
/// under the chat.
/// </remarks>
/// <param name="BnNumber">The number of the message.</param>
/// <param name="Message">The message.</param>
[PacketHeader("bn", PacketSource.Server)]
[GenerateSerializer(true)]
public record BnPacket
(
    [PacketIndex(0)]
    byte BnNumber,
    [PacketIndex(1)]
    NameString Message
) : IPacket;
\ No newline at end of file

A Packets/NosSmooth.Packets/Server/UI/TwkPacket.cs => Packets/NosSmooth.Packets/Server/UI/TwkPacket.cs +42 -0
@@ 0,0 1,42 @@
//
//  TwkPacket.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 NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using NosSmooth.PacketSerializer.Abstractions.Common;

namespace NosSmooth.Packets.Server.UI;

/// <summary>
/// Information about account, character, language.
/// </summary>
/// <param name="EntityType">The type of the character entity.</param>
/// <param name="EntityId">The id of the character.</param>
/// <param name="AccountName">The name of the logged in account.</param>
/// <param name="CharacterName">The name of the character.</param>
/// <param name="Salt">A salt, seems to always be shtmxpdlfeoqkr.</param>
/// <param name="ServerLanguage">The language of the server.</param>
/// <param name="ClientLanguage">The language of the client.</param>
[PacketHeader("twk", PacketSource.Server)]
[GenerateSerializer(true)]
public record TwkPacket
(
    [PacketIndex(0)]
    EntityType EntityType,
    [PacketIndex(1)]
    long EntityId,
    [PacketIndex(2)]
    string AccountName,
    [PacketIndex(3)]
    NameString CharacterName,
    [PacketIndex(4)]
    string Salt,
    [PacketIndex(5, IsOptional = true)]
    string? ServerLanguage,
    [PacketIndex(6, IsOptional = true)]
    string? ClientLanguage
) : IPacket;
\ No newline at end of file

M Tests/NosSmooth.Packets.Tests/Converters/Packets/FcPacketConverterTests.cs => Tests/NosSmooth.Packets.Tests/Converters/Packets/FcPacketConverterTests.cs +1 -0
@@ 6,6 6,7 @@

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

M Tests/NosSmooth.Packets.Tests/Converters/Packets/InPacketConverterTests.cs => Tests/NosSmooth.Packets.Tests/Converters/Packets/InPacketConverterTests.cs +1 -1
@@ 9,8 9,8 @@ using Microsoft.Extensions.DependencyInjection;
using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Entities;
using NosSmooth.Packets.Enums.Players;
using NosSmooth.Packets.Server.Character;
using NosSmooth.Packets.Server.Maps;
using NosSmooth.Packets.Server.Players;
using NosSmooth.Packets.Server.Weapons;
using NosSmooth.PacketSerializer;
using NosSmooth.PacketSerializer.Abstractions.Attributes;

M Tests/NosSmooth.Packets.Tests/Converters/Packets/MovePacketConverterTests.cs => Tests/NosSmooth.Packets.Tests/Converters/Packets/MovePacketConverterTests.cs +1 -1
@@ 5,7 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

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

M Tests/NosSmooth.Packets.Tests/Converters/Packets/PinitPacketConverterTest.cs => Tests/NosSmooth.Packets.Tests/Converters/Packets/PinitPacketConverterTest.cs +1 -1
@@ 5,7 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

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

M Tests/NosSmooth.Packets.Tests/Converters/Packets/SkiPacketConverterTests.cs => Tests/NosSmooth.Packets.Tests/Converters/Packets/SkiPacketConverterTests.cs +0 -2
@@ 5,8 5,6 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

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