Justice smells good, doesn't it?
PacketType CXSPackets::ParsePacket(char * packet)
{
packetid = *((WORD*)(packet+2));
size = *((WORD*)(packet));
switch (*((WORD*)(packet+2)))
{
case 0x03E9:
ZeroMemory(&CreateCharacterPacket, sizeof(CreateCharacterPacket));
memcpy(&CreateCharacterPacket, packet, size);
return PacketType(packetid);
case 0x03EC:
ZeroMemory(&ChatPacket, sizeof(ChatPacket));
ChatPacket.size = *(WORD*)(packet);
ChatPacket.type = *((WORD*)(packet+2));
ChatPacket.color = *((int*)(packet+4));
ChatPacket.chattype = *((int*)(packet+8));
memcpy(ChatPacket.time, packet+12, 4);
ChatPacket.unknown1 = *((int*)(packet+16));
ChatPacket.display = *((int*)(packet+20));
ChatPacket.unknown2 = *((char*)(packet+24));
ChatPacket.fromcount = *((char*)(packet+25));
memcpy(ChatPacket.from, packet+26, ChatPacket.fromcount);
ChatPacket.tocount = *((char*)(packet+26+ChatPacket.fromcount));
memcpy(ChatPacket.to, packet+27+ChatPacket.fromcount, ChatPacket.tocount);
ChatPacket.stringcount = *((char*)(packet+28+ChatPacket.fromcount+ChatPacket.tocount));
memcpy(ChatPacket.string, packet+29+ChatPacket.fromcount+ChatPacket.tocount, ChatPacket.stringcount);
return PacketType(packetid);
case 0x03ED:
ZeroMemory(&MovePacket, sizeof(MovePacket));
memcpy(&MovePacket, packet, size);
return PacketType(packetid);
case 0x041B:
ZeroMemory(&LoginPacket, sizeof(LoginPacket));
memcpy(&LoginPacket, packet, size);
return PacketType(packetid);
Thats my point, you cannot just define a fixed array for strings, therefore dynamic arrays are required and therefore you cannot use a struct in that way (Sadly) in C# for anything that requires a dynamic length string.Quote:
It is because you are assuming the names will always be 16 bytes long. There is no effective way to just throw it into a struct. You have to build it into one manually.
You cannot do what you were trying to do which was point to a managed struct with a dynamic var IN the struct. You CAN on the other hand use a DYNAMIC sized struct to COPY the data into effectively achieving the same result which is what I was saying this entire time lol. The same process would go for constructing the packet when trying to send data. You'd copy FROM the dynamic sized struct into a buffer instead of using the struct itself as one.Quote:
Thats my point, you cannot just define a fixed array for strings, therefore dynamic arrays are required and therefore you cannot use a struct in that way (Sadly) in C# for anything that requires a dynamic length string.
I think that just about clears up everything =x
Write method:Quote:
Just decided to have a go with your packet and this:
Does not compile, go figure.Code:MessagePacket* Packet = (MessagePacket*)Pointer;
So i went ahead and modified it so that it would atleast compile using fixed sbyte buffers:
And then i sent a chat packet and used this method to demonstrate the issues with it, its not exactly clean but its a valid way of doing it:Code:[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public unsafe struct MessagePacket { public ushort Lenght; public ushort Type;//0-4 public uint Msg_Color;//4-8 public uint Msg_Type;//8-12 public uint Msg_ID;//12-16 public ulong Unknown;//16-24 public byte String_Count;//24-25 public byte String_From_Length;//25-26 public fixed sbyte String_From[16];//26-27 + pos public byte String_To_Length;//27 + pos - 28 + pos public fixed sbyte String_To[16];//28 + pos - 29 + pos public byte Blank;//29 + pos - 30 + pos public byte String_Message_Length;//30 + pos - 31 + pos public fixed sbyte String_Message[16];//31 + pos - 32 + pos }
And this is the outcome:Code:MessagePacket* Packet = (MessagePacket*)Pointer; Console.WriteLine("[ChatPacket] From {0} To {1} : {2}", new string(Packet->String_From), new string(Packet->String_To), new string(Packet->String_Message));
[Only registered and activated users can see links. Click Here To Register...]
Now honestly, i dont pretend to be an expert, but that doesnt work does it. As far as i can tell theres nothing especially wrong with my implementation of it unless someone else can suggest a more appropriate method?
IntPtr Ptr = Marshal.AllocHGlobal(Packet.Length);
Marshal.StructureToPtr(Struct, Ptr, false);
fixed (byte* pckt = this.Packet)
{
Native.memcpy(pckt, Ptr.ToPointer(), Packet.Length);
}
public void Deserialize(IConquerPacket ConquerPacket)
{
fixed (byte* Packet = ConquerPacket.ToArray())
{
MsgPacket = *((MessagePacket*)(Packet));
fixed (MessagePacket* Msg = &MsgPacket)
{
this.Msg_From = new string(Msg->String_From);
this.Msg_To = new string(Msg->String_To);
this.Msg_Data = new string(Msg->String_Message);
}
}
}
He was using fixed sbyte in his struct, that's why I showed him that method. And it works perfectly fine if you just trim the string.Quote:
You guys are doing it wrong. Don't assume TQ will send null terminators.
ie: new string ((sbyte*)addr->Offset, offset, addr->Length);
Just saying.