Character info packet 5017

12/22/2011 17:18 Kiyono#1
I'm certain that all the values up till the string packer are correct since I just took them from Hybrid's source but I'm not too sure about the string packer part but it should be correct too yet it appears to be wrong and characters don't have names.
Code:
using System.Text;
using Albetros.Core.Enum;

namespace Albetros.Game.Packet
{
    public unsafe struct PlayerInfoPacket
    {
        public uint Id;
        public uint Lookface;
        public ushort Hair;
        public uint Money;
        public uint EMoney;
        public ulong Experience;
        public uint Unknown1;
        public uint Unknown2;
        public uint Unknown3;
        public uint Unknown4;
        public ushort Strength;
        public ushort Agility;
        public ushort Vitality;
        public ushort Spirit;
        public ushort AdditionalPoint;
        public ushort Life;
        public ushort Mana;
        public short Pk;
        public byte Level;
        public byte Profession;
        public byte Unknown5;
        public byte Metempsychosis;
        public byte NamesDisplayed;
        public byte Unknown6;
        public NetStringPacker StringPacker;

        public static PlayerInfoPacket Create(Player player)
        {
            var packet = new PlayerInfoPacket();

            packet.Id = player.UID;
            packet.Lookface = player.Mesh;
            packet.Hair = player.Hair;
            packet.Money = player.Money;
            packet.EMoney = player.CP;
            packet.Experience = player.Experience;
            packet.Strength = player.Strength;
            packet.Agility = player.Agility;
            packet.Vitality = player.Vitality;
            packet.Spirit = player.Spirit;
            packet.AdditionalPoint = player.StatPoint;
            packet.Life = (ushort)player.Health;
            packet.Mana = (ushort)player.Mana;
            packet.Pk = 0;
            packet.Level = player.Level;
            packet.Profession = player.Profession;
            packet.Metempsychosis = player.Reborn;
            packet.NamesDisplayed = 1;
            packet.StringPacker = new NetStringPacker();
            packet.StringPacker.AddString(player.Name);
            packet.StringPacker.AddString(player.Spouse);

            return packet;
        }

        public static implicit operator PlayerInfoPacket(byte* ptr)
        {
            var packet = new PlayerInfoPacket();
            packet.Id = *((uint*)(ptr + 4));
            packet.Lookface = *((uint*)(ptr + 8));
            packet.Hair = *((ushort*)(ptr + 12));
            packet.Money = *((uint*)(ptr + 14));
            packet.EMoney = *((uint*)(ptr + 18));
            packet.Experience = *((ulong*)(ptr + 22));
            packet.Unknown1 = *((uint*)(ptr + 30));
            packet.Unknown2 = *((uint*)(ptr + 34));
            packet.Unknown3 = *((uint*)(ptr + 38));
            packet.Unknown4 = *((uint*)(ptr + 42));
            packet.Strength = *((ushort*)(ptr + 46));
            packet.Agility = *((ushort*)(ptr + 48));
            packet.Vitality = *((ushort*)(ptr + 50));
            packet.Spirit = *((ushort*)(ptr + 52));
            packet.AdditionalPoint = *((ushort*)(ptr + 54));
            packet.Life = *((ushort*)(ptr + 56));
            packet.Mana = *((ushort*)(ptr + 58));
            packet.Pk = *((short*)(ptr + 60));
            packet.Level = *(ptr + 62);
            packet.Profession = *(ptr + 63);
            packet.Unknown5 = *(ptr + 64);
            packet.Metempsychosis = *(ptr + 65);
            packet.NamesDisplayed = *(ptr + 66);
            packet.Unknown6 = *(ptr + 67);
            packet.StringPacker = new NetStringPacker(ptr + 68);
            return packet;
        }

        public static implicit operator byte[](PlayerInfoPacket packet)
        {//108
            var buffer = new byte[68 + packet.StringPacker.Length];
            fixed (byte* ptr = buffer)
            {
                PacketBuilder.AppendHeader(ptr, buffer.Length, 1006);
                *((uint*)(ptr + 4)) = packet.Id;
                //new ushort for what?
                *((uint*)(ptr + 8)) = packet.Lookface;
                *((ushort*)(ptr + 12)) = packet.Hair;
                *((uint*)(ptr + 14)) = packet.Money;
                *((uint*)(ptr + 18)) = packet.EMoney;
                *((ulong*)(ptr + 22)) = packet.Experience;
                *((uint*)(ptr + 30)) = packet.Unknown1;
                *((uint*)(ptr + 34)) = packet.Unknown2;
                *((uint*)(ptr + 38)) = packet.Unknown3;
                *((uint*)(ptr + 42)) = packet.Unknown4;
                *((ushort*)(ptr + 46)) = packet.Strength;
                *((ushort*)(ptr + 48)) = packet.Agility;
                *((ushort*)(ptr + 50)) = packet.Vitality;
                *((ushort*)(ptr + 52)) = packet.Spirit;
                *((ushort*)(ptr + 54)) = packet.AdditionalPoint;
                *((ushort*)(ptr + 56)) = packet.Life;
                *((ushort*)(ptr + 58)) = packet.Mana;
                *((short*)(ptr + 60)) = packet.Pk;
                *(ptr + 62) = packet.Level;
                *(ptr + 63) = packet.Profession;
                *(ptr + 64) = packet.Unknown5;
                *(ptr + 65) = packet.Metempsychosis;
                *(ptr + 66) = packet.NamesDisplayed;
                *(ptr + 67) = packet.Unknown6;
                PacketBuilder.AppendNetStringPacker(ptr + 68, packet.StringPacker);
            }
            return buffer;
        }

        public override string ToString()
        {
            var builder = new StringBuilder();
            builder.AppendFormat("{0} {1} {2} {3} {4} {5}\r\n", Id, Lookface, Hair, Money, EMoney, Experience);
            builder.AppendFormat("{0} {1} {2} {3} {4}\r\n", Unknown1, Unknown2, Unknown3, Unknown4, Unknown5);
            builder.AppendFormat("{0} {1} {2} {3} {4} {5} {6} {7}\r\n", Strength, Agility, Vitality, Spirit, AdditionalPoint, Life, Mana, Pk);
            builder.AppendFormat("{0} {1} {2} {3} {4} {5}\r\n", Level, Profession, Unknown6, Metempsychosis, NamesDisplayed, Unknown6);

            for (byte i = 0; i < StringPacker.Count; i++)
            {
                string str;
                if (StringPacker.GetString(i, out str))
                {
                    builder.AppendLine(string.IsNullOrEmpty(str) ? "null" : str);
                }
            }

            return builder.ToString();
        }
    }

}
This should be correct right? I more or less tried random offsets for the stringpacker but it just refuses to work.
12/22/2011 17:27 CptSky#2
Code:
                    *((Byte*)(p + 66)) = (Byte)0x01; //Show Name
                    *((Byte*)(p + 67)) = (Byte)0x02; //String Count
                    *((Byte*)(p + 68)) = (Byte)User.Name.Length;
                    for (Byte i = 0; i < User.Name.Length; i++)
                        *((Byte*)(p + 69 + i)) = (Byte)User.Name[i];
                    *((Byte*)(p + 69 + (Byte)User.Name.Length)) = (Byte)User.Spouse.Length;
                    for (Byte i = 0; i < User.Spouse.Length; i++)
                        *((Byte*)(p + 70 + (Byte)User.Name.Length + i)) = (Byte)User.Spouse[i];
12/22/2011 17:44 Kiyono#3
Oh, forgot to set the stringcount, well now it works, thanks.