[CoEmu Question] Status Problem

07/31/2010 05:37 -Fáng-#1
Hey Everyone!

I've been working on a source that's similar to CoEmu. It unfortunately has the same status problem too that I'm not sure how to fix. The status window only updates itself once you log on and you can't equip new weapons until you log in again so that it updates your character's info from the database.

The person that helps will be thanked on my server's website. Not much of a reward but it's still fame for the people that want to play my game so they know who to appreciate.

Sincerely,
Fang
07/31/2010 07:13 _tao4229_#2
Send the 3f9 packet for all the stats that need updating?

How are stats being updated (via command, manually leveling, npc, etc)?
07/31/2010 09:46 -Fáng-#3
Quote:
Originally Posted by _tao4229_ View Post
Send the 3f9 packet for all the stats that need updating?

How are stats being updated (via command, manually leveling, npc, etc)?
I'm honestly not sure. It's being updated only when I log in. All stats are being saved to the database immediately, they just don't show up on the status window until you re-login.
07/31/2010 16:16 Basser#4
so send entity update packet (or whatever you call it)
Connection.Send(new EntityStatus(Entity.UID, StatusEnum.Vitality, Entity.Vitality);
example =)
07/31/2010 17:23 CptSky#5
As Tao and Basser said, you need to send the MsgUserAttrib (0x3f9) packet if you want to update the informations of the character.
07/31/2010 18:40 -Fáng-#6
Well I'm still not sure what to do.
My source isn't exactly like CoEmu I guess...
It uses a really weird why of doing it.

The only place that I see 0x3f9 is here:
Code:
public unsafe class BigUpdatePacket
            {
                private byte[] Buffer;
                private struct internalUpdate
                {
                    public ushort Size;
                    public ushort Type;
                    public uint UID;
                    public uint UpdateCount;
                }

                const int SizeOf_Data = 12;
                [StructLayout(LayoutKind.Explicit, Size = SizeOf_Data)]
                public struct Data
                {
                    [FieldOffset(0)]
                    public UpdateID ID;
                    [FieldOffset(4)]
                    public uint Value;
                    [FieldOffset(8)]
                    public uint Footer;
                    [FieldOffset(4)]
                    public ulong qwValue;

                    public static Data Create(UpdateID _ID, ulong _Value)
                    {
                        Data retn = new Data();
                        retn.ID = _ID;
                        retn.qwValue = _Value;
                        return retn;
                    }
                    public static Data Create(UpdateID _ID, uint _Value)
                    {
                        Data retn = new Data();
                        retn.ID = _ID;
                        retn.Value = _Value;
                        return retn;
                    }
                    public static Data Create(UpdateID _ID, int _Value)
                    {
                        Data retn = new Data();
                        retn.ID = _ID;
                        retn.Value = (uint)_Value;
                        return retn;
                    }
                    public static Data Create(UpdateID _ID, ushort _Value)
                    {
                        Data retn = new Data();
                        retn.ID = _ID;
                        retn.Value = _Value;
                        return retn;
                    }
                    public static Data Create(UpdateID _ID, byte _Value)
                    {
                        Data retn = new Data();
                        retn.ID = _ID;
                        retn.Value = _Value;
                        return retn;
                    }
                }

                public BigUpdatePacket(uint TotalUpdates)
                {
                    Buffer = new byte[12 + (TotalUpdates * SizeOf_Data) + 8];
                    fixed (byte* _iUpdate = Buffer)
                    {
                        internalUpdate* iUpdate = (internalUpdate*)_iUpdate;
                        iUpdate->Size = (ushort)(Buffer.Length - 8);
                        iUpdate->Type = 0x3f9;
                        iUpdate->UpdateCount = TotalUpdates;
                    }
                    COPacket o = new COPacket(Buffer);
                    o.WriteTQServer();
                    Buffer = o.Packet;
                }
                public uint UID
                {
                    get
                    {
                        fixed (byte* iUpdate = Buffer)
                            return ((internalUpdate*)iUpdate)->UID;
                    }
                    set
                    {
                        fixed (byte* iUpdate = Buffer)
                            ((internalUpdate*)iUpdate)->UID = value;
                    }
                }
                public static implicit operator byte[](BigUpdatePacket big)
                {
                    return big.Buffer;
                }

                public void Append(int UpdateNumber, UpdateID ID, ulong Value)
                {
                    fixed (byte* iUpdate = Buffer)
                    {
                        *((BigUpdatePacket.Data*)(iUpdate + 12 + (UpdateNumber * SizeOf_Data))) =
                            BigUpdatePacket.Data.Create(ID, Value);
                    }
                }
                public void Append(int UpdateNumber, UpdateID ID, uint Value)
                {
                    fixed (byte* iUpdate = Buffer)
                    {
                        *((BigUpdatePacket.Data*)(iUpdate + 12 + (UpdateNumber * SizeOf_Data))) =
                            BigUpdatePacket.Data.Create(ID, Value);
                    }
                }
                public void Append(int UpdateNumber, UpdateID ID, ushort Value)
                {
                    fixed (byte* iUpdate = Buffer)
                    {
                        *((BigUpdatePacket.Data*)(iUpdate + 12 + (UpdateNumber * SizeOf_Data))) =
                            BigUpdatePacket.Data.Create(ID, Value);
                    }
                }
                public void Append(int UpdateNumber, UpdateID ID, int Value)
                {
                    fixed (byte* iUpdate = Buffer)
                    {
                        *((BigUpdatePacket.Data*)(iUpdate + 12 + (UpdateNumber * SizeOf_Data))) =
                            BigUpdatePacket.Data.Create(ID, Value);
                    }
                }
                public void Append(int UpdateNumber, UpdateID ID, byte Value)
                {
                    fixed (byte* iUpdate = Buffer)
                    {
                        *((BigUpdatePacket.Data*)(iUpdate + 12 + (UpdateNumber * SizeOf_Data))) =
                            BigUpdatePacket.Data.Create(ID, Value);
                    }
                }
            }
and the Status packet sends information to it seen at the bottom of this code:
Code:
public static byte[] Status(ClientSocket CSocket, int Switch, int Value, Struct.StatusTypes Type)
        {
            Handler.BigUpdatePacket p = new Handler.BigUpdatePacket(1);
            p.UID = (uint)CSocket.Client.ID;


            if (Type == Struct.StatusTypes.StatusEffect)
            {
                ulong Status = 0;
                if (CSocket.Client.PkPoints >= 100)
                    Status += 0x8000;
                else if (CSocket.Client.PkPoints >= 30 && CSocket.Client.PkPoints < 100)
                    Status += 0x4000;
                if (CSocket.Client.Flashing)
                    Status += 0x1;
                if (CSocket.Client.Stigged)
                    Status += 0x200;
                if (CSocket.Client.Dead)
                    Status += 0x400;
                if (CSocket.Client.Dead)
                    Status += 0x20;
                if (CSocket.Client.Accuracy || CSocket.Client.Dodged)
                    Status += 0x80;
                if (CSocket.Client.TeamLeader)
                    Status += 0x40;
                if (CSocket.Client.Stigged)
                    Status += 0x0;
                if (CSocket.Client.Invisible)
                    Status += 0x400000;
                if (CSocket.Client.Shield)
                    Status += 0x100;
                if (CSocket.Client.Poisoned)
                    Status += 0x2;
                if (CSocket.Client.SuperMan)
                    Status += 0x40000;
                if (CSocket.Client.Cyclone)
                    Status += 0x800000;
                if (CSocket.Client.XPSkillList)
                    Status += 0x10;
                if (CSocket.Client.Flying)
                    Status += 0x8000000;
                if (CSocket.Client.CastingPray)
                    Status += 0x40000000;
                if (CSocket.Client.Praying)
                    Status += 0x80000000;
                if (CSocket.Client.Reflect)
                    Status += 0x20000;
                int id = CSocket.Client.ID;

                if (CSocket.Client.TopHalo == 1)
                {
                    Struct.TopHalos.Trojan = id;
                    Status += 0x8000000000;
                }
                else if (CSocket.Client.TopHalo == 2)
                {
                    Struct.TopHalos.Warrior = id;
                    Status += 0x4000000000;
                }
                else if (CSocket.Client.TopHalo == 3)
                {
                    Struct.TopHalos.Archer = id;
                    Status += 0x10000000000;
                }
                else if (CSocket.Client.TopHalo == 4)
                {
                    Struct.TopHalos.Ninja = id;
                    Status += 0x80000000000;
                }
                else if (CSocket.Client.TopHalo == 5)
                {
                    Struct.TopHalos.Water = id;
                    Status += 0x20000000000;
                }
                else if (CSocket.Client.TopHalo == 6)
                {
                    Struct.TopHalos.Fire = id;
                    Status += 0x40000000000;
                }
                else if (CSocket.Client.TopHalo == 7)
                {
                    Struct.TopHalos.PkWeek = id;
                    Status += 0x2000000000;
                }
                else if (CSocket.Client.TopHalo == 8)
                {
                    Struct.TopHalos.PkMonth = id;
                    Status += 0x1000000000;
                }
                else if (CSocket.Client.TopHalo == 9)
                {
                    Struct.TopHalos.GuildLeader = id;
                    Status += 0x400000000;
                }
                else if (CSocket.Client.TopHalo == 10)
                {
                    Status += 0x800000000;
                }

                if (CSocket.Client.Vortex)
                    Status += 0x400000000000;
                if (CSocket.Client.FatalStrike)
                    Status += 0x800000000000;
                p.Append(0, (Handlers.Handler.UpdateID)Type, Status);
            }
            else
                p.Append(0, (Handlers.Handler.UpdateID)Type, Value);
            return p;
        }
and when you login, it uses the following codes:
Code:
CSocket.AccountName = World.AuthenticatedLogins[Keys].Account;
                Program.WriteLine("[WorldServer] Authenticated Login.");
                ConnectionRequest User = World.AuthenticatedLogins[Keys];
                User.Expire(false);
                CSocket.Client = Database.GetCharacter(User.Account);
                if (CSocket.Client == null)
                {
                    CSocket.Send(CoPacket.Chat(0, "SYSTEM", "ALLUSERS", "NEW_ROLE", Struct.ChatType.LoginInformation));
                    return;
                }
                Calculation.Vitals(CSocket, true);
                if (CSocket.Client.First)
                {
                    CSocket.Client.CurrentMP = CSocket.Client.MaxMP;
                    CSocket.Client.CurrentHP = CSocket.Client.MaxHP;
                }

                if (World.ClientPool.ContainsKey(CSocket.Client.ID))
                {
                    ClientSocket C = World.ClientPool[CSocket.Client.ID];
                    C.Send(CoPacket.Chat(0, "SYSTEM", C.Client.Name, " Your character has logged in from another location, you're being booted.", Struct.ChatType.Talk));
                    C.Disconnect();
                }
                try
                {
                    Monitor.Enter(World.ClientPool);
                    World.ClientPool.Add(CSocket.Client.ID, CSocket);
                }
                catch (Exception Exc)
                {
                    Program.WriteLine(Exc);
                }
                finally
                {
                    Monitor.Exit(World.ClientPool);
                }
                CSocket.Send(CoPacket.Chat(0, "SYSTEM", "ALLUSERS", "ANSWER_OK", Struct.ChatType.LoginInformation));

                if (CSocket.Client.GuildID != 0)
                {
                    Handlers.Guilds.SendCharGuild(CSocket);
                    //Handlers.Guilds.SendGuildScreen(CSocket);
                }
                if (CSocket.Client.CurrentHP < 1)
                {
                    Struct.ReviveLocations r = World.ReviveLocations[(int)CSocket.Client.Loc.Map];
                    Handler.Teleport((int)CSocket.Client.Loc.Map, CSocket.Client.Loc.X, CSocket.Client.Loc.Y, 0, CSocket);
                    CSocket.Client.Dead = false;
                    CSocket.Client.CurrentHP = 1;
                    CSocket.Send(CoPacket.Status(CSocket, 2, CSocket.Client.CurrentHP, Struct.StatusTypes.Hp));
                }
                Database.CheckForSashes(CSocket);
                CSocket.Send(CoPacket.Status(CSocket, 512, CSocket.Client.HeavenBlessing, Struct.StatusTypes.BlessTime));
                CSocket.Send(CoPacket.CharacterInfo(CSocket));
                CSocket.Send(CoPacket.Status(CSocket, 2, CSocket.Client.NobleDonate, Struct.StatusTypes.NobilityDonation));
                CSocket.Send(CoPacket.Nobility(CSocket.Client.ID));
                CSocket.Send(CoPacket.Status(CSocket, 2, CSocket.Client.VipLevel, Struct.StatusTypes.VIPLevel));
I know what you guys are talking about, I just can't recognize any entity status packet in the source =\ I'm so used to the 5165 source... and I just want to learn more about this source I'm working on. If someone wants to help me over team viewer or something, that'd be awesome.
08/02/2010 00:02 Korvacs#7
This:

Code:
CSocket.Send(CoPacket.Status(CSocket, 512, CSocket.Client.HeavenBlessing, Struct.StatusTypes.BlessTime));
Is the server updating a stat on the client, it needs sending everytime there is a change, the reason that things are only updating when you login is because you are being sent the updated char info packet.
08/02/2010 09:26 -Fáng-#8
_tao4229_ really helped me out so thank you _tao4229_! There's still a problem though with the packet. It doesn't show HP updating. I've confirmed after testing that the problem is inside the Status Packet.

These are now my status packets:
Code:
public static byte[] Status(ClientSocket CSocket, int Switch, int Value, Struct.StatusTypes Type)
{
PacketBuilder Packet = null;
if (Switch == 1 || Switch == 3 || Switch == 501)
Packet = new PacketBuilder(10017, 36);
else if (Switch == 2 || Switch == 4 || Switch == 512)
Packet = new PacketBuilder(10017, 48);
Packet.Long((ulong)(CSocket.Client.ID));
if (Switch == 1)
{
Packet.Long(Switch);
Packet.Long(Value);
Packet.Long(0);
Packet.Long((int)Type);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
else if (Switch == 2)
{
Packet.Long(Switch);//Unknown Var
Packet.Short(65535);
Packet.Short(65535);
Packet.Long(0);
Packet.Long(0);
Packet.Long((int)(Type));
if (Type == Struct.StatusTypes.StatusEffect)
{
uint Status = 0;
if (Value != 1024 && !CSocket.Client.Dead)//Dead
{
if (CSocket.Client.PkPoints >= 100)
Status += 0x8000;
else if (CSocket.Client.PkPoints >= 30 && CSocket.Client.PkPoints < 100)
Status += 0x4000;
if (CSocket.Client.Flashing)
Status += 0x1;
if (CSocket.Client.Stigged)
Status += 0x200;
if (CSocket.Client.SuperMan)
Status += 0x40000;
if (CSocket.Client.Cyclone)
Status += 0x800000;
if (CSocket.Client.Team != null)
{
if (CSocket.Client.Team.LeaderID == CSocket.Client.ID)
Status += 0x40;
}
if (CSocket.Client.Flying)
Status += 0x8000000;
if (CSocket.Client.CastingPray)
Status += 0x40000000;
if (CSocket.Client.Praying)
Status += 0x80000000;
if (CSocket.Client.Stigged)
Status += 0x200;
if (CSocket.Client.Dead)
Status += 0x400;
if (CSocket.Client.Dead)
Status += 0x20;
if (CSocket.Client.Accuracy || CSocket.Client.Dodged)
Status += 0x80;
if (CSocket.Client.Stigged)
Status += 0x0;
if (CSocket.Client.Invisible)
Status += 0x400000;
if (CSocket.Client.Shield)
Status += 0x100;
if (CSocket.Client.Poisoned)
Status += 0x2;
if (CSocket.Client.XPSkillList)
Status += 0x10;
if (CSocket.Client.Reflect)
Status += 0x20000;
int id = CSocket.Client.ID;

if (CSocket.Client.TopHalo == 1)
{
Struct.TopHalos.Trojan = id;
Status += 0x80000;
}
else if (CSocket.Client.TopHalo == 2)
{
Struct.TopHalos.Warrior = id;
Status += 0x40000;
}
else if (CSocket.Client.TopHalo == 3)
{
Struct.TopHalos.Archer = id;
Status += 0x10000;
}
else if (CSocket.Client.TopHalo == 4)
{
Struct.TopHalos.Ninja = id;
Status += 0x80000;
}
else if (CSocket.Client.TopHalo == 5)
{
Struct.TopHalos.Water = id;
Status += 0x20000;
}
else if (CSocket.Client.TopHalo == 6)
{
Struct.TopHalos.Fire = id;
Status += 0x40000;
}
else if (CSocket.Client.TopHalo == 7)
{
Struct.TopHalos.PkWeek = id;
Status += 0x20000;
}
else if (CSocket.Client.TopHalo == 8)
{
Struct.TopHalos.PkMonth = id;
Status += 0x10000;
}
else if (CSocket.Client.TopHalo == 9)
{
Struct.TopHalos.GuildLeader = id;
Status += 0x40000;
}
else if (CSocket.Client.TopHalo == 10)
{
Status += 0x80000;
}

if (CSocket.Client.Vortex)
Status += 0x40000;
if (CSocket.Client.FatalStrike)
Status += 0x80000;

}
else
Status = 1024;
Packet.Long(Status);
}
else
Packet.Long(Value);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
else if (Switch == 3)
{
Packet.Long(Value);//Unknown Var
Packet.Long(26);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
else if (Switch == 4)
{
Packet.Long(2);//Unknown Var
Packet.Long(4294967295); //(FF FF FF FF)
Packet.Long(0);
Packet.Long(0);
Packet.Long(9);
Packet.Long(3);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
return Packet.getFinal();
}
Code:
public static byte[] Status(ClientSocket CSocket, int Switch, ulong Value, Struct.StatusTypes Type)
{
PacketBuilder Packet = null;
if (Switch == 1 || Switch == 3 || Switch == 501)
Packet = new PacketBuilder(10017, 36);
else if (Switch == 2 || Switch == 4 || Switch == 512)
Packet = new PacketBuilder(10017, 48);
Packet.Long(CSocket.Client.ID);
if (Switch == 1)
{
Packet.Long(Switch);
//Packet.Long(Value);
//Packet.Long(0);
Packet.ULong(Value);
Packet.Long((int)Type);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
else if (Switch == 2)
{
Packet.Long(Switch);//Unknown Var
Packet.Short(65535);
Packet.Short(65535);
Packet.Long(0);
Packet.Long(0);
Packet.Long((int)(Type));
Packet.Long(Value);
Packet.Long(0);
// Packet.ULong(Value);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
else if (Switch == 3)
{
//Packet.Long(Value);//Unknown Var
//Packet.Long(26);
Packet.ULong(Value);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
else if (Switch == 4)
{
Packet.Long(2);//Unknown Var
Packet.Long(4294967295); //(FF FF FF FF)
Packet.Long(0);
Packet.Long(0);
Packet.Long(9);
Packet.Long(3);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
return Packet.getFinal();
}
Code:
public static byte[] Status(int ID, int Switch, ulong Value, Struct.StatusTypes Type)
{
PacketBuilder Packet = null;
if (Switch == 1 || Switch == 3 || Switch == 501)
Packet = new PacketBuilder(10017, 36);
else if (Switch == 2 || Switch == 4 || Switch == 512)
Packet = new PacketBuilder(10017, 48);
Packet.Long((ulong)ID);
if (Switch == 1)
{
Packet.Long(Switch);
//Packet.Long(Value);
//Packet.Long(0);
Packet.ULong(Value);
Packet.Long((int)Type);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
else if (Switch == 2)
{
Packet.Long(Switch);//Unknown Var
Packet.Short(65535);
Packet.Short(65535);
Packet.Long(0);
Packet.Long(0);
Packet.Long((int)(Type));
Packet.Long(Value);
Packet.Long(0);
// Packet.ULong(Value);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
else if (Switch == 3)
{
//Packet.Long(Value);//Unknown Var
//Packet.Long(26);
Packet.ULong(Value);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
else if (Switch == 4)
{
Packet.Long(2);//Unknown Var
Packet.Long(4294967295); //(FF FF FF FF)
Packet.Long(0);
Packet.Long(0);
Packet.Long(9);
Packet.Long(3);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
Packet.Long(0);
}
return Packet.getFinal();
}

used this as a reference:
[Only registered and activated users can see links. Click Here To Register...]
08/02/2010 10:48 Korvacs#9
Code:
        public static byte[] Status(ClientSocket CSocket, int Switch, int Value, Struct.StatusTypes Type)
        {
            PacketBuilder Packet = new PacketBuilder(10017, 32 + (Switch * 20));
            Packet.Long((ulong)ID);
            Packet.Long((int)Type);
            Packet.ULong(Value);
            return Packet.getFinal();
        }
Since your not using the status packet the way it was intended this looks like all you need, however im confused about your method names, does Long = Int, and Ulong = long?
08/02/2010 18:09 -Fáng-#10
Quote:
Originally Posted by Korvacs View Post
Code:
        public static byte[] Status(ClientSocket CSocket, int Switch, int Value, Struct.StatusTypes Type)
        {
            PacketBuilder Packet = new PacketBuilder(10017, 32 + (Switch * 20));
            Packet.Long((ulong)ID);
            Packet.Long((int)Type);
            Packet.ULong(Value);
            return Packet.getFinal();
        }
Since your not using the status packet the way it was intended this looks like all you need, however im confused about your method names, does Long = Int, and Ulong = long?
That status packet makes no sense... it doesn't add up.
I got mine from CoEmu... and my source best represents that.

ULong = 8
Long = 4
Short = 2
Int = 1
Byte = 1


EDIT: I fixed it!
I'm so happy =]
This was the fix: I used the one that I wrote that was based off of Impluse's source!
I just changed the 0x3ee --> 10017
xP

#request close =]
08/02/2010 21:32 Korvacs#11
It may not appear to add up but thats because after those initial values there is 12 bytes of empty space, and then a further 16 bytes of filler.

So although it doesnt appear to be correct it is.
08/02/2010 23:21 InfamousGeek#12
Quote:
Originally Posted by -Fáng- View Post
I just changed the 0x3ee --> 10017
xP

#request close =]
I don't see how the 0x3ee/1006 packet is even coming close to the hero update packet? Also you should of said that you upgraded your CoEmu version to 5165.
08/03/2010 00:08 -Fáng-#13
Quote:
Originally Posted by InfamousGeek View Post
I don't see how the 0x3ee/1006 packet is even coming close to the hero update packet? Also you should of said that you upgraded your CoEmu version to 5165.
Well I didn't say that because I'm not =o
I'm taking parts of CoEmu and Impulse's source ... #00 << if you know what that is in Conquer online then congrats =]