I got my answer, remove this thread.
Sure there is. You do it like he did it and like how I did it in C++. There will obviously be a function call required to "construct" the packet but it would indeed work very well.Quote:
I use packets like this for my proxy, except that in C# theres no physical way of using structs for packets which contain dynamic length strings, unfortunately. So these work well for everything except for ChatPacket(1004) and CharInfo(1006).
They are really handy for unions, makes life alot easier.
char * CXSPackets::BuildPacket(int type)
{
switch (type)
{
case 0x03E9:
CreateCharacterPacket.type = type;
CreateCharacterPacket.size = sizeof(CreateCharacterPacket);
return (char *)&CreateCharacterPacket;
case 0x03EC:
ZeroMemory(&buffer, sizeof(buffer));
*(WORD*)(buffer) = size;
*(WORD*)(buffer+2) = packetid;
*(int*)(buffer+4) = ChatPacket.color;
*(int*)(buffer+8) = ChatPacket.chattype;
memcpy(buffer+12, ChatPacket.time, 4);
*(int*)(buffer+16) = ChatPacket.unknown1;
*(int*)(buffer+20) = ChatPacket.display;
*(char*)(buffer+24) = ChatPacket.unknown2;
*(char*)(buffer+25) = ChatPacket.fromcount;
memcpy(buffer+26, ChatPacket.from, ChatPacket.fromcount);
*(char*)(buffer+26+ChatPacket.fromcount) = ChatPacket.tocount;
memcpy(buffer+27+ChatPacket.fromcount, ChatPacket.to, ChatPacket.tocount);
*(char*)(buffer+28+ChatPacket.fromcount+ChatPacket.tocount) = ChatPacket.stringcount;
memcpy(buffer+29+ChatPacket.fromcount+ChatPacket.tocount, ChatPacket.string, ChatPacket.stringcount);
*(WORD*)(buffer) = size = 29 + ChatPacket.fromcount + ChatPacket.tocount + ChatPacket.stringcount;
return (char *)buffer;
case 0x03ED:
MovePacket.type = type;
MovePacket.size = sizeof(MovePacket);
return (char *)&MovePacket;
case 0x041B:
LoginPacket.type = type;
LoginPacket.size = sizeof(LoginPacket);
return (char *)&LoginPacket;
case 0x041C:
LanguagePacket.type = type;
LanguagePacket.size = sizeof(LanguagePacket);
return (char *)&LanguagePacket;
case 0x03EE:
ZeroMemory(&buffer, sizeof(buffer));
CharacterDataPacket.type = type;
CharacterDataPacket.size = sizeof(CharacterDataPacket);
memcpy(buffer, &CharacterDataPacket, 68);
*(char*)(buffer+68) = CharacterDataPacket.charnamecount;
memcpy(buffer+69, CharacterDataPacket.charactername, CharacterDataPacket.charnamecount);
*(char*)(buffer+69+CharacterDataPacket.charnamecount) = CharacterDataPacket.spousenamecount;
memcpy(buffer+70+CharacterDataPacket.charnamecount, CharacterDataPacket.spousename, CharacterDataPacket.spousenamecount);
*(WORD*)(buffer) = size = 67 + CharacterDataPacket.spousenamecount + CharacterDataPacket.charnamecount + 4;
return (char *)buffer;
CharacterInfo* Packet = (CharacterInfo*)Pointer;
Error 1 Cannot take the address of, get the size of, or declare a pointer to a managed type ('MiningBot.Networking.Packets.CharacterInfo') C:\Users\Jack\Documents\Visual Studio 2010\Projects\MiningBot\MiningBot\Networking\PacketHandler.cs 60 25 MiningBot
If you're asking me, ask Basser. He seems to have gotten it to work. As for your attitude of "impossible!", that is not the attitude of a true developer/programmer. Nothing is impossible. While I know it is not impossible to do it in C# entirely, if you absolutely desired to, you could even import these functions from a DLL of another language to accomplish it. It is not impossible to get the desired results in C#.Quote:
Using a dynamic char[] in the struct for CharInfo, and then trying to do this:
Returns this compiler error:Code:CharacterInfo* Packet = (CharacterInfo*)Pointer;
So tell me again how i could get around that issue using a struct?Code:Error 1 Cannot take the address of, get the size of, or declare a pointer to a managed type ('MiningBot.Networking.Packets.CharacterInfo') C:\Users\Jack\Documents\Visual Studio 2010\Projects\MiningBot\MiningBot\Networking\PacketHandler.cs 60 25 MiningBot
ItemDataPacket* Packet = (ItemDataPacket*)Pointer;
Quote:
My attitude isnt "Impossible!", my attitude is, ive spent months looking into this and ive found that you just cannot do it with dynamic values in a fixed struct, Basser has created a packet with no dynamic values, which i have also done:
Compiles with no issues. However you cannot have a dynamic value in a fixed struct, you just cant do it.Code:ItemDataPacket* Packet = (ItemDataPacket*)Pointer;
Google it, research it, contact microsoft about it, it cant be done in C#.
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct MessagePacket
{
public PacketHeader Header;//0-4
public UInt32 Msg_Color;//4-8
public UInt32 Msg_Type;//8-12
public UInt32 Msg_ID;//12-16
public UInt64 Unknown;//16-24
public Byte String_Count;//24-25
public Byte String_From_Length;//25-26
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public String String_From;//26-27 + pos
public Byte String_To_Length;//27 + pos - 28 + pos
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public String String_To;//28 + pos - 29 + pos
public Byte Blank;//29 + pos - 30 + pos
public Byte String_Message_Length;//30 + pos - 31 + pos
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public String String_Message;//31 + pos - 32 + pos
}
//Get the size; Marshal.SizeOf(Instance);
//Set the length of each string to 16.
Ok Mr Hostility. My first reply was explaining in general that it was possible. You came back with a "it's not possible to do X, tell me how to do it!" trying to pick a fight as if I said you could do it the way you're trying lol.Quote:
My attitude isnt "Impossible!", my attitude is, ive spent months looking into this and ive found that you just cannot do it with dynamic values in a fixed struct, Basser has created a packet with no dynamic values, which i have also done:
Compiles with no issues. However you cannot have a dynamic value in a fixed struct, you just cant do it.Code:ItemDataPacket* Packet = (ItemDataPacket*)Pointer;
Google it, research it, contact microsoft about it, it cant be done in C#.
Again, that doesnt work for dynamic length strings, i explored that but what your doing there is assigning the string a fixed length in memory, so if the string is say 4 bytes long, then when you assign the data from the pointer to the struct you read a further 12 bytes into invalid memory, because the packet you assigned only have 4 bytes of data at that location.Quote:
You gotta thank Nullable for the constant length fix though, I personally thought the client would not trim these.Code:[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] struct MessagePacket { public PacketHeader Header;//0-4 public UInt32 Msg_Color;//4-8 public UInt32 Msg_Type;//8-12 public UInt32 Msg_ID;//12-16 public UInt64 Unknown;//16-24 public Byte String_Count;//24-25 public Byte String_From_Length;//25-26 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public String String_From;//26-27 + pos public Byte String_To_Length;//27 + pos - 28 + pos [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public String String_To;//28 + pos - 29 + pos public Byte Blank;//29 + pos - 30 + pos public Byte String_Message_Length;//30 + pos - 31 + pos [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public String String_Message;//31 + pos - 32 + pos } //Get the size; Marshal.SizeOf(Instance); //Set the length of each string to 16.