Weird spawning problem

02/04/2012 12:54 Kiyono#1
I downgraded Albetros to 5017 but I have this weird problem with spawning players. I can see mobs and NPCs just fine but when I log in a second client, the first client sees the character on the second client a shadow, name is there and I can click on it with the view gear thing. I know the mesh is correct (tried some breakpointing) but it simply doesn't spawn =/
02/04/2012 13:25 Korvacs#2
The spawn entity packet layout is correct for a character right?
02/04/2012 15:02 Kiyono#3
I copied it from my 5017 version of Project Manifest so it should work.
//edit
Code:
public unsafe struct SpawnPlayerPacket
    {
        public uint Id; //4
        public uint Lookface; //8
        public ulong Effect1; //12
        public ushort GuildId; //20
        public byte Unknown1; //22
        public GuildRank GuildRank; //23
        public uint GarmentType; //24
        public uint HelmetType; //28
        public uint ArmorType; //32
        public uint WeaponLType; //36
        public uint WeaponRType; //40
        public uint Unknown2; //44
        public ushort Life; //48
        public ushort MobLevel; //50
        public ushort PositionX; //52
        public ushort PositionY; //54
        public ushort Hair; //56
        public byte Direction; //58
        public byte Action; //59
        public byte Rebirth; //60
        public byte Unknown3; //61
        public ushort Level; //62
        public byte Unknown4; //64
        public uint Nobility; //65
        public byte Unknown5; //69
        public uint Unknown6; //70
        public uint Unknown7; //74
        public ushort Unknown8; //78
        public NetStringPacker Strings; //80

        public static SpawnPlayerPacket Create(Monster entity)
        {
            var packet = new SpawnPlayerPacket();
            packet.Strings = new NetStringPacker();
            packet.Lookface = entity.BaseMonster.Mesh;
            packet.Id = entity.UID;
            packet.PositionX = entity.X;
            packet.PositionY = entity.Y;
            packet.Direction = entity.Direction;
            packet.MobLevel  = entity.BaseMonster.Level;         
            packet.Life = (ushort) entity.Health;          
            packet.Effect1 = entity._stateff1;
            packet.Strings.AddString(entity.BaseMonster.Name);
            packet.Strings.AddString(string.Empty);
            return packet;
        }
        public static SpawnPlayerPacket Create(AI entity)
        {
            var packet = new SpawnPlayerPacket();
            packet.Lookface = entity.Mesh;
            packet.Id = entity.UID;
            packet.Effect1 = entity.StatusEffect1;
            if (entity.HeadGear != null)
            {
                packet.HelmetType = entity.HeadGear.StaticID;
            }
            if (entity.Armor != null)
            {
                packet.ArmorType = entity.Armor.StaticID;
            }
            if (entity.WeaponL != null)
            {
                packet.WeaponLType = entity.WeaponL.StaticID;
            }
            if (entity.WeaponR != null)
            {
                packet.WeaponRType = entity.WeaponR.StaticID;
            }
            if (entity.Garment != null)
            {
                packet.GarmentType = entity.Garment.StaticID;
            }
            packet.Life = (ushort)entity.Health;
            packet.Hair = entity.Hair;
            packet.PositionX = entity.X;
            packet.PositionY = entity.Y;
            packet.Direction = entity.Direction;
            packet.Action = (byte)entity.Action;
            packet.Rebirth = entity.Reborn;
            packet.Level = entity.Level;
            packet.Strings = new NetStringPacker();
            packet.Strings.AddString(entity.Name);
            packet.Strings.AddString(string.Empty);
            return packet;
        }
        public static SpawnPlayerPacket Create(Player entity)
        {
            var packet = new SpawnPlayerPacket();
            packet.Lookface = entity.Mesh;
            packet.Id = entity.UID;
            packet.GuildId = (ushort)entity.GuildId;
            packet.GuildRank = entity.GuildRank;
            packet.Effect1 = entity.StatusEffect1;
            if (entity.Equipment.Headgear != null)
            {
                packet.HelmetType = entity.Equipment.Headgear.StaticID;
            }
            if (entity.Equipment.Armor != null)
            {
                packet.ArmorType = entity.Equipment.Armor.StaticID;
            }
            if (entity.Equipment.WeaponL != null)
            {
                packet.WeaponLType = entity.Equipment.WeaponL.StaticID;
            }
            if (entity.Equipment.WeaponR != null)
            {
                packet.WeaponRType = entity.Equipment.WeaponR.StaticID;
            }
            if (entity._disguiseGarment != null)
                packet.GarmentType = entity._disguiseGarment.StaticID;
            else if (entity.Equipment.Garment != null)
                packet.GarmentType = entity.Equipment.Garment.StaticID;

            packet.Life = (ushort)entity.Health;
            packet.Hair = entity.Hair;
            packet.PositionX = entity.X;
            packet.PositionY = entity.Y;
            packet.Direction = entity.Direction;
            packet.Action = (byte)entity.Action;
            packet.Rebirth = entity.Reborn;
            packet.Level = entity.Level;
            packet.Strings = new NetStringPacker();
            packet.Strings.AddString(entity.Name);
            packet.Strings.AddString(string.Empty);
            return packet;
        }

        public static implicit operator byte[](SpawnPlayerPacket packet)
        {//216
            var buffer = new byte[220 + packet.Strings.Length];
            fixed (byte* ptr = buffer)
            {
                PacketBuilder.AppendHeader(ptr, buffer.Length, 1014);
                *((uint*)(ptr + 4)) = packet.Id;
                *((uint*) (ptr + 8)) = packet.Lookface;
                *((ulong*)(ptr + 12)) = packet.Effect1;
                *((ushort*) (ptr + 20)) = packet.GuildId;
                *(ptr + 22) = packet.Unknown1;
                *((GuildRank*) (ptr + 23)) = packet.GuildRank;
                *((uint*)(ptr + 24)) = packet.GarmentType;
                *((uint*)(ptr + 28)) = packet.HelmetType;
                *((uint*) (ptr + 32)) = packet.ArmorType;
                *((uint*) (ptr + 36)) = packet.WeaponLType;
                *((uint*) (ptr + 40)) = packet.WeaponRType;
                *((uint*)(ptr + 44)) = packet.Unknown2;
                *((ushort*)(ptr + 48)) = packet.Life;
                *((ushort*)(ptr + 50)) = packet.MobLevel;
                *((ushort*)(ptr + 52)) = packet.PositionX;
                *((ushort*)(ptr + 54)) = packet.PositionY;
                *((ushort*)(ptr + 56)) = packet.Hair;
                *(ptr + 58) = packet.Direction;
                *(ptr + 59) = packet.Action;
                *(ptr + 60) = packet.Rebirth;
                *(ptr + 61) = packet.Unknown3;
                *((ushort*) (ptr + 62)) = packet.Level;
                *(ptr + 64) = packet.Unknown4;
                *(ptr + 65) = (byte) packet.Nobility;
                *(ptr + 69) = packet.Unknown5;
                *((uint*)(ptr + 70)) = packet.Unknown6;
                *((uint*)(ptr + 74)) = packet.Unknown7;
                *((ushort*)(ptr + 78)) = packet.Unknown8;
                PacketBuilder.AppendNetStringPacker(ptr + 80, packet.Strings);
            }
            return buffer;
        }
    }
02/04/2012 22:38 InfamousNoone#4
Structures that are large may get packed slightly differently than you expect.
For instance, fields that are marked ushort, might actually be treated as ints for a better performance gain.

tl;dr of me going on how a compiler figures how the best packing, use StructLayout Explicit, and define a FieldOffset for every individual field.

-- nvm ignore this post, I thought you were using the same method as I often used as just making a pointer to the structure then copying it out of memory; I didn't notice you had an explicit constructor for the byte[]
02/04/2012 23:43 Spirited#5
The mesh could be showing as missing if an item equipped is nonexistant. Are you naked when testing the spawn packet?
02/05/2012 10:42 Kiyono#6
Quote:
Originally Posted by Fаng View Post
The mesh could be showing as missing if an item equipped is nonexistant. Are you naked when testing the spawn packet?
I thought that they were naked but it seemed that pro made newly created chars auto-equip a coat which was obviously the wrong item ID so they were wearing non-existing items which caused the problem. Thanks.