From b2373d15569e685409046303c14c0a04317f9d5b Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Mon, 13 Nov 2023 21:12:12 +0100 Subject: [PATCH] feat: channel selection working --- Server/DB/Documents/Character.cs | 9 + Server/DB/Documents/InventoryItem.cs | 2 +- ...192405_AdditionalCharacterData.Designer.cs | 249 ++++++++++++++++++ .../20231113192405_AdditionalCharacterData.cs | 155 +++++++++++ .../WonderkingContextModelSnapshot.cs | 70 ++++- Server/DB/WonderkingContext.cs | 2 + .../PacketHandlers/ChannelSelectionHandler.cs | 79 ++++++ Server/docker-compose.yml | 2 + .../Game/Data/Character}/Gender.cs | 2 +- .../Game/Data/Character}/PvPLevel.cs | 2 +- Wonderking/Game/Data/Item/ElementalStats.cs | 2 +- Wonderking/Game/Data/Item/Stats.cs | 2 +- Wonderking/Game/Data/ItemObject.cs | 1 - .../Game/Reader/ItemReaderExtensions.cs | 4 +- Wonderking/Packets/Outgoing/BaseStats.cs | 6 +- .../ChannelSelectionResponsePacket.cs | 53 ++-- Wonderking/Packets/Outgoing/CharacterData.cs | 11 +- Wonderking/Packets/Outgoing/JobData.cs | 6 +- 18 files changed, 609 insertions(+), 48 deletions(-) create mode 100644 Server/DB/Migrations/20231113192405_AdditionalCharacterData.Designer.cs create mode 100644 Server/DB/Migrations/20231113192405_AdditionalCharacterData.cs rename {Server/DB/Documents => Wonderking/Game/Data/Character}/Gender.cs (63%) rename {Server/DB/Documents => Wonderking/Game/Data/Character}/PvPLevel.cs (92%) diff --git a/Server/DB/Documents/Character.cs b/Server/DB/Documents/Character.cs index 2c737c8..49293fd 100644 --- a/Server/DB/Documents/Character.cs +++ b/Server/DB/Documents/Character.cs @@ -1,3 +1,6 @@ +using Wonderking.Game.Data.Character; +using Wonderking.Packets.Outgoing; + namespace Server.DB.Documents; public class Character @@ -15,4 +18,10 @@ public class Character public long Experience { get; set; } public byte Level { get; set; } public ICollection InventoryItems { get; set; } + + public BaseStats BaseStats { get; set; } + + public JobData JobData { get; set; } + public int Health { get; set; } + public int Mana { get; set; } } diff --git a/Server/DB/Documents/InventoryItem.cs b/Server/DB/Documents/InventoryItem.cs index f85c981..58ddd55 100644 --- a/Server/DB/Documents/InventoryItem.cs +++ b/Server/DB/Documents/InventoryItem.cs @@ -5,7 +5,7 @@ public class InventoryItem public Guid CharacterId { get; set; } public Character Character { get; set; } public Guid Id { get; set; } - public short ItemId { get; set; } + public ushort ItemId { get; set; } public ushort Count { get; set; } public byte Slot { get; set; } public ItemType ItemType { get; set; } diff --git a/Server/DB/Migrations/20231113192405_AdditionalCharacterData.Designer.cs b/Server/DB/Migrations/20231113192405_AdditionalCharacterData.Designer.cs new file mode 100644 index 0000000..345b7b3 --- /dev/null +++ b/Server/DB/Migrations/20231113192405_AdditionalCharacterData.Designer.cs @@ -0,0 +1,249 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Server.DB; + +#nullable disable + +namespace Server.DB.Migrations +{ + [DbContext(typeof(WonderkingContext))] + [Migration("20231113192405_AdditionalCharacterData")] + partial class AdditionalCharacterData + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.13") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Server.DB.Documents.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Email") + .HasColumnType("text"); + + b.Property("Password") + .HasColumnType("bytea"); + + b.Property("PermissionLevel") + .HasColumnType("smallint"); + + b.Property("Salt") + .HasColumnType("bytea"); + + b.Property("Username") + .HasColumnType("varchar(20)"); + + b.HasKey("Id"); + + b.ToTable("Accounts"); + }); + + modelBuilder.Entity("Server.DB.Documents.Character", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("uuid"); + + b.Property("Experience") + .HasColumnType("bigint"); + + b.Property("Gender") + .HasColumnType("smallint"); + + b.Property("Health") + .HasColumnType("integer"); + + b.Property("LastXCoordinate") + .HasColumnType("smallint"); + + b.Property("LastYCoordinate") + .HasColumnType("smallint"); + + b.Property("Level") + .HasColumnType("smallint"); + + b.Property("Mana") + .HasColumnType("integer"); + + b.Property("MapId") + .HasColumnType("integer"); + + b.Property("Name") + .HasColumnType("varchar(20)"); + + b.Property("PvPLevel") + .HasColumnType("smallint"); + + b.Property("ServerId") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.ToTable("Characters"); + }); + + modelBuilder.Entity("Server.DB.Documents.InventoryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AddOption") + .HasColumnType("smallint"); + + b.Property("AddOption2") + .HasColumnType("smallint"); + + b.Property("AddOption3") + .HasColumnType("smallint"); + + b.Property("CharacterId") + .HasColumnType("uuid"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("ItemId") + .HasColumnType("integer"); + + b.Property("ItemType") + .HasColumnType("smallint"); + + b.Property("Level") + .HasColumnType("smallint"); + + b.Property("Option") + .HasColumnType("smallint"); + + b.Property("Option2") + .HasColumnType("smallint"); + + b.Property("Option3") + .HasColumnType("smallint"); + + b.Property("Rarity") + .HasColumnType("smallint"); + + b.Property("Slot") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("CharacterId"); + + b.ToTable("InventoryItem"); + }); + + modelBuilder.Entity("Server.DB.Documents.Character", b => + { + b.HasOne("Server.DB.Documents.Account", "Account") + .WithMany("Characters") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("Wonderking.Packets.Outgoing.BaseStats", "BaseStats", b1 => + { + b1.Property("CharacterId") + .HasColumnType("uuid"); + + b1.Property("Dexterity") + .HasColumnType("smallint"); + + b1.Property("Intelligence") + .HasColumnType("smallint"); + + b1.Property("Luck") + .HasColumnType("smallint"); + + b1.Property("Strength") + .HasColumnType("smallint"); + + b1.Property("Vitality") + .HasColumnType("smallint"); + + b1.Property("Wisdom") + .HasColumnType("smallint"); + + b1.HasKey("CharacterId"); + + b1.ToTable("Characters"); + + b1.WithOwner() + .HasForeignKey("CharacterId"); + }); + + b.OwnsOne("Wonderking.Packets.Outgoing.JobData", "JobData", b1 => + { + b1.Property("CharacterId") + .HasColumnType("uuid"); + + b1.Property("FirstJob") + .HasColumnType("smallint"); + + b1.Property("FourthJob") + .HasColumnType("smallint"); + + b1.Property("SecondJob") + .HasColumnType("smallint"); + + b1.Property("ThirdJob") + .HasColumnType("smallint"); + + b1.HasKey("CharacterId"); + + b1.ToTable("Characters"); + + b1.WithOwner() + .HasForeignKey("CharacterId"); + }); + + b.Navigation("Account"); + + b.Navigation("BaseStats"); + + b.Navigation("JobData"); + }); + + modelBuilder.Entity("Server.DB.Documents.InventoryItem", b => + { + b.HasOne("Server.DB.Documents.Character", "Character") + .WithMany("InventoryItems") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("Server.DB.Documents.Account", b => + { + b.Navigation("Characters"); + }); + + modelBuilder.Entity("Server.DB.Documents.Character", b => + { + b.Navigation("InventoryItems"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Server/DB/Migrations/20231113192405_AdditionalCharacterData.cs b/Server/DB/Migrations/20231113192405_AdditionalCharacterData.cs new file mode 100644 index 0000000..49c9278 --- /dev/null +++ b/Server/DB/Migrations/20231113192405_AdditionalCharacterData.cs @@ -0,0 +1,155 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Server.DB.Migrations; + +/// +public partial class AdditionalCharacterData : Migration +{ + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "ItemId", + table: "InventoryItem", + type: "integer", + nullable: false, + oldClrType: typeof(short), + oldType: "smallint"); + + migrationBuilder.AddColumn( + name: "BaseStats_Dexterity", + table: "Characters", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "BaseStats_Intelligence", + table: "Characters", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "BaseStats_Luck", + table: "Characters", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "BaseStats_Strength", + table: "Characters", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "BaseStats_Vitality", + table: "Characters", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "BaseStats_Wisdom", + table: "Characters", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "Health", + table: "Characters", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "JobData_FirstJob", + table: "Characters", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "JobData_FourthJob", + table: "Characters", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "JobData_SecondJob", + table: "Characters", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "JobData_ThirdJob", + table: "Characters", + type: "smallint", + nullable: true); + + migrationBuilder.AddColumn( + name: "Mana", + table: "Characters", + type: "integer", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "BaseStats_Dexterity", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "BaseStats_Intelligence", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "BaseStats_Luck", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "BaseStats_Strength", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "BaseStats_Vitality", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "BaseStats_Wisdom", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "Health", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "JobData_FirstJob", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "JobData_FourthJob", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "JobData_SecondJob", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "JobData_ThirdJob", + table: "Characters"); + + migrationBuilder.DropColumn( + name: "Mana", + table: "Characters"); + + migrationBuilder.AlterColumn( + name: "ItemId", + table: "InventoryItem", + type: "smallint", + nullable: false, + oldClrType: typeof(int), + oldType: "integer"); + } +} diff --git a/Server/DB/Migrations/WonderkingContextModelSnapshot.cs b/Server/DB/Migrations/WonderkingContextModelSnapshot.cs index ab1f034..933467c 100644 --- a/Server/DB/Migrations/WonderkingContextModelSnapshot.cs +++ b/Server/DB/Migrations/WonderkingContextModelSnapshot.cs @@ -63,6 +63,9 @@ namespace Server.DB.Migrations b.Property("Gender") .HasColumnType("smallint"); + b.Property("Health") + .HasColumnType("integer"); + b.Property("LastXCoordinate") .HasColumnType("smallint"); @@ -72,6 +75,9 @@ namespace Server.DB.Migrations b.Property("Level") .HasColumnType("smallint"); + b.Property("Mana") + .HasColumnType("integer"); + b.Property("MapId") .HasColumnType("integer"); @@ -112,8 +118,8 @@ namespace Server.DB.Migrations b.Property("Count") .HasColumnType("integer"); - b.Property("ItemId") - .HasColumnType("smallint"); + b.Property("ItemId") + .HasColumnType("integer"); b.Property("ItemType") .HasColumnType("smallint"); @@ -151,7 +157,67 @@ namespace Server.DB.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.OwnsOne("Wonderking.Packets.Outgoing.BaseStats", "BaseStats", b1 => + { + b1.Property("CharacterId") + .HasColumnType("uuid"); + + b1.Property("Dexterity") + .HasColumnType("smallint"); + + b1.Property("Intelligence") + .HasColumnType("smallint"); + + b1.Property("Luck") + .HasColumnType("smallint"); + + b1.Property("Strength") + .HasColumnType("smallint"); + + b1.Property("Vitality") + .HasColumnType("smallint"); + + b1.Property("Wisdom") + .HasColumnType("smallint"); + + b1.HasKey("CharacterId"); + + b1.ToTable("Characters"); + + b1.WithOwner() + .HasForeignKey("CharacterId"); + }); + + b.OwnsOne("Wonderking.Packets.Outgoing.JobData", "JobData", b1 => + { + b1.Property("CharacterId") + .HasColumnType("uuid"); + + b1.Property("FirstJob") + .HasColumnType("smallint"); + + b1.Property("FourthJob") + .HasColumnType("smallint"); + + b1.Property("SecondJob") + .HasColumnType("smallint"); + + b1.Property("ThirdJob") + .HasColumnType("smallint"); + + b1.HasKey("CharacterId"); + + b1.ToTable("Characters"); + + b1.WithOwner() + .HasForeignKey("CharacterId"); + }); + b.Navigation("Account"); + + b.Navigation("BaseStats"); + + b.Navigation("JobData"); }); modelBuilder.Entity("Server.DB.Documents.InventoryItem", b => diff --git a/Server/DB/WonderkingContext.cs b/Server/DB/WonderkingContext.cs index 807dfd8..b18817b 100644 --- a/Server/DB/WonderkingContext.cs +++ b/Server/DB/WonderkingContext.cs @@ -40,5 +40,7 @@ public class WonderkingContext : DbContext builder.Property(c => c.Name).HasColumnType("varchar(20)"); builder.HasMany(e => e.InventoryItems).WithOne(e => e.Character) .HasForeignKey(e => e.CharacterId).IsRequired(); + builder.OwnsOne(p => p.BaseStats); + builder.OwnsOne(p => p.JobData); }).Entity(builder => { builder.HasKey(i => i.Id); }); } diff --git a/Server/PacketHandlers/ChannelSelectionHandler.cs b/Server/PacketHandlers/ChannelSelectionHandler.cs index 12c2030..74364d5 100644 --- a/Server/PacketHandlers/ChannelSelectionHandler.cs +++ b/Server/PacketHandlers/ChannelSelectionHandler.cs @@ -1,5 +1,16 @@ + +/* Nicht gemergte Änderung aus Projekt "Server(net7.0)" +Vor: +using System.Net; using Microsoft.EntityFrameworkCore; +Nach: +using Microsoft.EntityFrameworkCore; +*/ +using Microsoft.EntityFrameworkCore; +using Server.DB.Documents; +using Wonderking.Game.Data.Character; using Wonderking.Packets.Incoming; +using Wonderking.Packets.Outgoing; namespace Server.PacketHandlers; @@ -30,8 +41,76 @@ public class ChannelSelectionHandler : IPacketHandler { var authSession = (AuthSession)session; var charactersOfAccount = this._wonderkingContext.Accounts.Include(account => account.Characters) + .ThenInclude(character => character.InventoryItems) .FirstOrDefault(a => a.Id == authSession.AccountId) ?.Characters; + ChannelSelectionResponsePacket responsePacket; + + if (charactersOfAccount != null && false) + { + responsePacket = new ChannelSelectionResponsePacket + { + ChannelIsFullFlag = 0, + Endpoint = "127.0.0.1", + Port = 12345, + Characters = charactersOfAccount.Select((character, + _) => new CharacterData + { + Name = character.Name, + Job = character.JobData, + Gender = character.Gender, + Level = character.Level, + Experience = 0, + Stats = character.BaseStats, + Health = character.Health, + Mana = character.Mana, + EquippedItems = + character.InventoryItems.Where(item => item.ItemType == ItemType.WornEquipment) + .Select(item => item.ItemId) + .ToArray(), + EquippedCashItems = character.InventoryItems + .Where(item => item.ItemType == ItemType.WornCashEquipment) + .Select(item => item.ItemId) + .ToArray(), + }) + .ToArray(), + }; + } + else + { + responsePacket = new ChannelSelectionResponsePacket + { + ChannelIsFullFlag = 0, + Endpoint = "127.0.0.1", + Port = 12345, + Characters = new[] + { + new CharacterData + { + Name = "Test243", + Job = new JobData { FirstJob = 1, SecondJob = 0, ThirdJob = 0, FourthJob = 0 }, + Gender = Gender.None, + Level = ushort.MaxValue - 1, + Experience = 255, + Stats = new BaseStats + { + Strength = 5, + Dexterity = 5, + Intelligence = 5, + Vitality = 5, + Luck = 5, + Wisdom = 5 + }, + Health = int.MaxValue - 1, + Mana = int.MaxValue - 1, + EquippedItems = Enumerable.Repeat((ushort)25,20).ToArray(), + EquippedCashItems = Enumerable.Repeat((ushort)25,20).ToArray() + }, + }, + }; + } + + authSession.Send(responsePacket); return Task.CompletedTask; } } diff --git a/Server/docker-compose.yml b/Server/docker-compose.yml index 8659b0b..1f8fa76 100644 --- a/Server/docker-compose.yml +++ b/Server/docker-compose.yml @@ -33,6 +33,8 @@ - POSTGRES_PASSWORD=continuity networks: - continuity + ports: + - "5432:5432" volumes: - db-data:/var/lib/postgresql/data healthcheck: diff --git a/Server/DB/Documents/Gender.cs b/Wonderking/Game/Data/Character/Gender.cs similarity index 63% rename from Server/DB/Documents/Gender.cs rename to Wonderking/Game/Data/Character/Gender.cs index 441de51..49f9949 100644 --- a/Server/DB/Documents/Gender.cs +++ b/Wonderking/Game/Data/Character/Gender.cs @@ -1,4 +1,4 @@ -namespace Server.DB.Documents; +namespace Wonderking.Game.Data.Character; public enum Gender : byte { diff --git a/Server/DB/Documents/PvPLevel.cs b/Wonderking/Game/Data/Character/PvPLevel.cs similarity index 92% rename from Server/DB/Documents/PvPLevel.cs rename to Wonderking/Game/Data/Character/PvPLevel.cs index d1bb1ec..8fbaca4 100644 --- a/Server/DB/Documents/PvPLevel.cs +++ b/Wonderking/Game/Data/Character/PvPLevel.cs @@ -1,4 +1,4 @@ -namespace Server.DB.Documents; +namespace Wonderking.Game.Data.Character; public enum PvPLevel : byte { diff --git a/Wonderking/Game/Data/Item/ElementalStats.cs b/Wonderking/Game/Data/Item/ElementalStats.cs index 1599a5f..e56739b 100644 --- a/Wonderking/Game/Data/Item/ElementalStats.cs +++ b/Wonderking/Game/Data/Item/ElementalStats.cs @@ -1,6 +1,6 @@ using System.Runtime.InteropServices; -namespace Wonderking.GameData.Item; +namespace Wonderking.Game.Data.Item; [StructLayout(LayoutKind.Explicit, Size = 64)] public struct ElementalStats diff --git a/Wonderking/Game/Data/Item/Stats.cs b/Wonderking/Game/Data/Item/Stats.cs index ab60dd0..009fa3d 100644 --- a/Wonderking/Game/Data/Item/Stats.cs +++ b/Wonderking/Game/Data/Item/Stats.cs @@ -1,6 +1,6 @@ using System.Runtime.InteropServices; -namespace Wonderking.GameData.Item; +namespace Wonderking.Game.Data.Item; [StructLayout(LayoutKind.Explicit, Size = 24)] public struct Stats diff --git a/Wonderking/Game/Data/ItemObject.cs b/Wonderking/Game/Data/ItemObject.cs index 2f1bf2e..4284d2f 100644 --- a/Wonderking/Game/Data/ItemObject.cs +++ b/Wonderking/Game/Data/ItemObject.cs @@ -1,6 +1,5 @@ using System.Text.Json.Serialization; using Wonderking.Game.Data.Item; -using Wonderking.GameData.Item; using Wonderking.Utils; namespace Wonderking.Game.Data; diff --git a/Wonderking/Game/Reader/ItemReaderExtensions.cs b/Wonderking/Game/Reader/ItemReaderExtensions.cs index df9d71f..97a8b72 100644 --- a/Wonderking/Game/Reader/ItemReaderExtensions.cs +++ b/Wonderking/Game/Reader/ItemReaderExtensions.cs @@ -1,6 +1,6 @@ -using Wonderking.GameData.Item; +using Wonderking.Game.Data.Item; -namespace Wonderking.Game.Data.Item; +namespace Wonderking.Game.Reader; public static class ItemReaderExtensions { diff --git a/Wonderking/Packets/Outgoing/BaseStats.cs b/Wonderking/Packets/Outgoing/BaseStats.cs index 61b9bf9..b525c87 100644 --- a/Wonderking/Packets/Outgoing/BaseStats.cs +++ b/Wonderking/Packets/Outgoing/BaseStats.cs @@ -1,9 +1,9 @@ -using System.Runtime.InteropServices; +using JetBrains.Annotations; namespace Wonderking.Packets.Outgoing; -[StructLayout(LayoutKind.Auto)] -public struct BaseStats +[UsedImplicitly] +public class BaseStats { public required short Strength { get; set; } public required short Dexterity { get; set; } diff --git a/Wonderking/Packets/Outgoing/ChannelSelectionResponsePacket.cs b/Wonderking/Packets/Outgoing/ChannelSelectionResponsePacket.cs index 100f7dc..1293949 100644 --- a/Wonderking/Packets/Outgoing/ChannelSelectionResponsePacket.cs +++ b/Wonderking/Packets/Outgoing/ChannelSelectionResponsePacket.cs @@ -6,10 +6,11 @@ namespace Wonderking.Packets.Outgoing; [PacketId(OperationCode.ChannelSelectionResponse)] public class ChannelSelectionResponsePacket : IPacket { - public required byte UnknownFlag { get; set; } + public required byte ChannelIsFullFlag { get; set; } public required string Endpoint { get; set; } public required ushort Port { get; set; } public required CharacterData[] Characters { get; set; } + public required string GuildName { get; set; } public void Deserialize(byte[] data) { @@ -18,54 +19,52 @@ public class ChannelSelectionResponsePacket : IPacket public byte[] Serialize() { - Span data = stackalloc byte[1 + 16 + 2 + 2 + 132 * this.Characters.Length]; + Span data = stackalloc byte[1 + 16 + 2 + 2 + 132 * this.Characters.Length + 20]; data.Clear(); - data[0] = this.UnknownFlag; + data[0] = this.ChannelIsFullFlag; Encoding.ASCII.GetBytes(this.Endpoint, data.Slice(1, 16)); BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(17, 2), this.Port); - BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(19, 2), (ushort)this.Characters.Length); + data[19] = (byte)this.Characters.Length; // Character Data for (var i = 0; i < Characters.Length; i++) { var character = Characters[i]; - BinaryPrimitives.WriteInt32LittleEndian(data.Slice(21, 4), i); - Encoding.ASCII.GetBytes(character.Name, data.Slice(25 + (i * 132), 16)); + BinaryPrimitives.WriteInt32LittleEndian(data.Slice(20, 4), i); + Encoding.ASCII.GetBytes(character.Name, data.Slice(24 + (i * 132), 20)); // Job Data - data[41 + (i * 132)] = character.Job.FirstJob; - data[42 + (i * 132)] = character.Job.SecondJob; - data[43 + (i * 132)] = character.Job.ThirdJob; - data[44 + (i * 132)] = character.Job.FourthJob; + data[44 + (i * 132)] = character.Job.FirstJob; + data[45 + (i * 132)] = character.Job.SecondJob; + data[46 + (i * 132)] = character.Job.ThirdJob; + data[47 + (i * 132)] = character.Job.FourthJob; - data[45 + (i * 132)] = character.Gender; - data[46 + (i * 132)] = character.Level; - data[47 + (i * 132)] = character.Unknown; - data[48 + (i * 132)] = (byte)character.Experience; + data[48 + (i * 132)] = (byte)character.Gender; + BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(49 + (i * 132), 2), character.Level); + data[51 + (i * 132)] = (byte)character.Experience; // Stats - BinaryPrimitives.WriteInt16LittleEndian(data.Slice(49 + (i * 132), 2), character.Stats.Strength); - BinaryPrimitives.WriteInt16LittleEndian(data.Slice(51 + (i * 132), 2), character.Stats.Dexterity); - BinaryPrimitives.WriteInt16LittleEndian(data.Slice(53 + (i * 132), 2), character.Stats.Intelligence); - BinaryPrimitives.WriteInt16LittleEndian(data.Slice(55 + (i * 132), 2), character.Stats.Vitality); - BinaryPrimitives.WriteInt16LittleEndian(data.Slice(57 + (i * 132), 2), character.Stats.Luck); - BinaryPrimitives.WriteInt16LittleEndian(data.Slice(59 + (i * 132), 2), character.Stats.Wisdom); + BinaryPrimitives.WriteInt16LittleEndian(data.Slice(52 + (i * 132), 2), character.Stats.Strength); + BinaryPrimitives.WriteInt16LittleEndian(data.Slice(54 + (i * 132), 2), character.Stats.Dexterity); + BinaryPrimitives.WriteInt16LittleEndian(data.Slice(56 + (i * 132), 2), character.Stats.Intelligence); + BinaryPrimitives.WriteInt16LittleEndian(data.Slice(58 + (i * 132), 2), character.Stats.Vitality); + BinaryPrimitives.WriteInt16LittleEndian(data.Slice(60 + (i * 132), 2), character.Stats.Luck); + BinaryPrimitives.WriteInt16LittleEndian(data.Slice(62 + (i * 132), 2), character.Stats.Wisdom); - BinaryPrimitives.WriteInt32LittleEndian(data.Slice(61 + (i * 132), 4), character.Health); - BinaryPrimitives.WriteInt32LittleEndian(data.Slice(65 + (i * 132), 4), character.Mana); + BinaryPrimitives.WriteInt32LittleEndian(data.Slice(64 + (i * 132), 4), character.Health); + BinaryPrimitives.WriteInt32LittleEndian(data.Slice(68 + (i * 132), 4), character.Mana); for (var j = 0; j < 20; j++) { // Equipped Items - BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(69 + (i * 132) + (j * 2), 2), - character.EquippedItems[j] ?? 0); + BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(72 + (i * 132) + (j * 2), 2), + character.EquippedItems.Length > j ? character.EquippedItems[j] : (ushort)0); // Equipped Cash Items - BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(109 + (i * 132) + (j * 2), 2), - character.EquippedCashItems[j] ?? 0); + BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(112 + (i * 132) + (j * 2), 2), + character.EquippedCashItems.Length > j ? character.EquippedCashItems[j] : (ushort)0); } } - return data.ToArray(); } } diff --git a/Wonderking/Packets/Outgoing/CharacterData.cs b/Wonderking/Packets/Outgoing/CharacterData.cs index 6e401b6..b6d95af 100644 --- a/Wonderking/Packets/Outgoing/CharacterData.cs +++ b/Wonderking/Packets/Outgoing/CharacterData.cs @@ -1,16 +1,17 @@ +using Wonderking.Game.Data.Character; + namespace Wonderking.Packets.Outgoing; public struct CharacterData { public required string Name { get; set; } public required JobData Job { get; set; } - public required byte Gender { get; set; } - public required byte Level { get; set; } - public required byte Unknown { get; set; } + public required Gender Gender { get; set; } + public required ushort Level { get; set; } public required float Experience { get; set; } public required BaseStats Stats { get; set; } public required int Health { get; set; } public required int Mana { get; set; } - public required ushort?[] EquippedItems { get; set; } - public required ushort?[] EquippedCashItems { get; set; } + public required ushort[] EquippedItems { get; set; } + public required ushort[] EquippedCashItems { get; set; } } diff --git a/Wonderking/Packets/Outgoing/JobData.cs b/Wonderking/Packets/Outgoing/JobData.cs index 89d0b0a..6c2c9fe 100644 --- a/Wonderking/Packets/Outgoing/JobData.cs +++ b/Wonderking/Packets/Outgoing/JobData.cs @@ -1,9 +1,9 @@ -using System.Runtime.InteropServices; +using JetBrains.Annotations; namespace Wonderking.Packets.Outgoing; -[StructLayout(LayoutKind.Auto)] -public struct JobData +[UsedImplicitly] +public class JobData { public required byte FirstJob { get; set; } public required byte SecondJob { get; set; }