|
You last visited: Today at 11:49
Advertisement
StringPacket
Discussion on StringPacket within the CO2 Programming forum part of the Conquer Online 2 category.
07/30/2011, 12:12
|
#1
|
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
|
StringPacket
Code:
case StringType.WhisperDetails:
{
foreach (var m in world.Entities.DB.Heros)
{
if ((m as Hero).name == str.StringTexts[0])
{
if (m.Notifier != null)
{
string otherstring = "";
otherstring += (m as Hero).id + " ";
otherstring += (m as Hero).level + " ";
otherstring += (m as Hero).BattlePower + " #";
if ((m as Hero).syndicate_id != 0)
{
//otherstring += Guild.Name + " fNone#";
otherstring += " fNone#";
}
else
{
otherstring += "None fNone# ";
}
otherstring += (m as Hero).mate + " ";
otherstring += /*(byte)(NobilityRank) +*/ " ";
if ((m as Hero).lookface % 10 < 3) otherstring += "1";
else otherstring += "0";
str.StringTexts.Add(otherstring);
str.TextsCount = 1;
m.Notifier.SendString(e, str.Buffer);
}
}
}
break;
}
Code:
1A 00 F7 03 00 00 00 00 1A 01 0D 50 72 6F 66 65 73 73 6F 72 5B 50 4D 5D 00 00
17 00 F7 03 00 00 00 00 1A 01 0A 4D 72 5F 50 6F 50 5B 50 4D 5D 00 00
the client sends me 2 StringPackets am adding the info to it but it seems not accepting my info ! as u can see it didn't add the info inside it
so what am doing wrong here!
|
|
|
07/30/2011, 14:02
|
#2
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
|
Don't set TextsCount manually... There SHOULD be an .Add method which handles this all for you.
That and the string count would be TWO now seeing as there was one element in there (at index zero) and now there are two.
I think when you try to read it back out it's using the stringcount to determine the length of the packet and such. Look inside your string packer and look for an add method that handles all the under the hood work (or write a new one)
|
|
|
07/31/2011, 04:05
|
#3
|
elite*gold: 0
Join Date: May 2005
Posts: 1,892
Received Thanks: 920
|
Speaking of the string packet, does anyone have any information about these subtypes? I'm using a 4267 client, but I don't think they've changed.
// unknown = 0x01, (server->client)
// unknown = 0x08, (server->client)
// unknown = 0x09, (server->client)
// unknown = 0x0D, (client->server)
// unknown = 0x0E, (client->server)
// unknown = 0x0F, (server->client)
// unknown = 0x11, (client->server)
// unknown = 0x12, (client->server)
// unknown = 0x13, (server->client)
// unknown = 0x17, (server->client)
|
|
|
07/31/2011, 06:06
|
#4
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
|
Not sure where all these are ripped from but it's what I have in my current source.
Code:
public enum StringAction : byte
{
None = 0,
Fireworks,
CreateGuild,
Guild,
ChangeTitle,
DeleteRole = 5,
Mate,
QueryNpc,
Wanted,
MapEffect,
RoleEffect = 10,
MemberList,
KickoutGuildMember,
QueryWanted,
QueryPoliceWanted,
PoliceWanted = 15,
QueryMate,
AddDicePlayer,
DeleteDicePlayer,
DiceBonus,
PlayerWave = 20,
SetAlly,
SetEnemy,
WhisperWindowInfo = 26
}
Many of our enums are ripped from the eudemons official tq client and server source codes so many do not fully relate to conquer but these are mostly/all correct I feel.
|
|
|
07/31/2011, 11:16
|
#5
|
elite*gold: 0
Join Date: May 2005
Posts: 1,892
Received Thanks: 920
|
Quote:
Originally Posted by pro4never
Not sure where all these are ripped from but it's what I have in my current source.
Code:
public enum StringAction : byte
{
None = 0,
Fireworks,
CreateGuild,
Guild,
ChangeTitle,
DeleteRole = 5,
Mate,
QueryNpc,
Wanted,
MapEffect,
RoleEffect = 10,
MemberList,
KickoutGuildMember,
QueryWanted,
QueryPoliceWanted,
PoliceWanted = 15,
QueryMate,
AddDicePlayer,
DeleteDicePlayer,
DiceBonus,
PlayerWave = 20,
SetAlly,
SetEnemy,
WhisperWindowInfo = 26
}
Many of our enums are ripped from the eudemons official tq client and server source codes so many do not fully relate to conquer but these are mostly/all correct I feel.
|
Thank you! These seem correct.
|
|
|
07/31/2011, 16:03
|
#6
|
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
|
the packet structure is:
Code:
private List<string> Texts;
public StringPacket(string str)
: base(0x3F7, 11)
{
Texts = new List<string>() { str };
WriteStringList(9, Texts);
}
public UInt32 EntityID
{
get
{
return ReadUInt32(4);
}
set
{
WriteUInt32(4, value);
}
}
public StringType strType
{
get
{
return (StringType)ReadUInt8(8);
}
set
{
WriteUInt8(8, (byte)value);
}
}
public List<string> StringTexts
{
get
{
return Texts;
}
}
the padding been added in the Send method so no need to keep add the padding for each packet.
Packet Usage.
Code:
foreach (var m in world.Entities.DB.Heros)
{
if ((m as Hero).name == str.StringTexts[0])
{
if (m.Notifier != null)
{
string otherstring = "";
otherstring += (m as Hero).id + " ";
otherstring += (m as Hero).level + " ";
otherstring += (m as Hero).BattlePower + " #";
if ((m as Hero).syndicate_id != 0)
{
//otherstring += Guild.Name + " fNone#";
otherstring += " fNone#";
}
else
{
otherstring += "None fNone# ";
}
otherstring += (m as Hero).mate + " ";
otherstring += /*(byte)(NobilityRank) +*/ " ";
if ((m as Hero).lookface % 10 < 3) otherstring += "1";
else otherstring += "0";
//str.StringTexts.Add(otherstring);
//str.TextsCount = 2;
StringPacket stri = new StringPacket(str.StringTexts[0] + otherstring);
stri.EntityID = (uint)(m as Hero).id;
stri.strType = str.strType;
m.Notifier.SendString(e, stri.Buffer);
}
}
}
the output is :
Code:
0B 00 F7 03 70 42 0F 00 1A 01 2F 50 72 6F 66 65 73 73 6F 72 5B 50 4D 5D 31 30 30
30 30 34 38 20 31 34 30 20 30 20 23 4E 6F 6E 65 20 66 4E 6F 6E 65 23 20 4E 6F 6
E 65 20 20 30
the problem is :
once i send this packet to the other Hero the other Hero is DISCONNECTING so what am missing here!?
|
|
|
07/31/2011, 16:30
|
#7
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
|
As I said... the strings are COUNTED. It's not a matter of simply saying "make this string longer".
Instead of
01 2F 50 72 6F 66 65.....
02 (string count)
Length of first string
String content
Length of second string
String content
The reason you are dcing is the system you are using is making the packet structure wrong.
It's expecting a maximum length of 16 for name and instead it receives this big long mess of a string.
StringPacket stri = new StringPacket(str.StringTexts[0] + otherstring);
Try doing..
StringPacket stri = new StringPacket(str.StringTexts[0]);
stri.Texts.Add(otherstring;
THEN send.
|
|
|
07/31/2011, 17:01
|
#8
|
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
|
Quote:
Originally Posted by pro4never
As I said... the strings are COUNTED. It's not a matter of simply saying "make this string longer".
Instead of
01 2F 50 72 6F 66 65.....
02 (string count)
Length of first string
String content
Length of second string
String content
The reason you are dcing is the system you are using is making the packet structure wrong.
It's expecting a maximum length of 16 for name and instead it receives this big long mess of a string.
StringPacket stri = new StringPacket(str.StringTexts[0] + otherstring);
Try doing..
StringPacket stri = new StringPacket(str.StringTexts[0]);
stri.Texts.Add(otherstring);
THEN send.
|
stri.Texts.Add(otherstring); is not adding otherstring to it
so the result is
Code:
0B 00 F7 03 43 42 0F 00 1A 01 0A 4D 72 5F 50 6F 50 5B 50 4D 5D
meaning it's not adding otherstring
i tried
Code:
public StringPacket(string str)
: base(0x3F7, (ushort)(11+str.Length))
{
Texts = new List<string>() { str };
WriteStringList(9, Texts);
}
i didn't dc but, it didn't work, i didn't see the details in the whisper window
Code:
3B 00 F7 03 43 42 0F 00 1A 01 30 4D 72 5F 50 6F 50 5B 50 4D 5D 31 30 30 30 30 30
33 20 31 34 30 20 30 20 23 4E 6F 6E 65 20 66 4E 6F 6E 65 23 20 57 69 66 65 4C 6
D 61 6F 20 20 30
|
|
|
07/31/2011, 17:51
|
#9
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
|
You're still counting one string...
You're string packet is wrong. You need to write ALL the strings inside that list by using...
byte string count
foreach string
byte string
string data
look into
WriteStringList(9, Texts);
That's where your issue is. WriteStringList is not writing all the strings correctly.
|
|
|
07/31/2011, 19:24
|
#10
|
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
|
Quote:
Originally Posted by pro4never
You're still counting one string...
You're string packet is wrong. You need to write ALL the strings inside that list by using...
byte string count
foreach string
byte string
string data
look into
WriteStringList(9, Texts);
That's where your issue is. WriteStringList is not writing all the strings correctly.
|
i don't understand what's wrong my packets seems to be right!!
MyPacket
Code:
41 00 F7 03 00 00 00 00 1A 02 0D 50 72 6F 66 65 73 73 6F 72 5B 50 4D 5D 26 31 30
30 30 30 30 33 20 31 34 30 20 30 20 23 4E 6F 6E 65 20 66 4E 6F 6E 65 23 20 57 6
9 66 65 4C 6D 61 6F 20 20 30 00 00
TQ's Packet
Code:
3F 00 F7 03 00 00 00 00 1A 02 0B 5E 73 75 70 65 72 5E 6D 61 6E 5E 26 31 33 39 36 30
39 36 20 31 33 33 20 32 34 36 20 23 4C 49 47 48 54 20 23 20 61 6D 6F 72 67 61 6
D 65 73 20 30 20 31 00 00
it's still not showing the details
|
|
|
07/31/2011, 20:01
|
#11
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
|
Well you seem to have the string count correct now. Not sure why it wouldn't be displaying :S
I tried manually reading through the packet. Seems you may be off like 1 byte count.. I could have made a mistake but the final 30 was not part of the string count.
The two blank bytes at the end ARE intentional though. I have it in my structure as well.
|
|
|
08/01/2011, 03:25
|
#12
|
elite*gold: 0
Join Date: Jan 2008
Posts: 1,443
Received Thanks: 1,175
|
If it can help, here my MsgName packet.
Code:
using System;
using System.Runtime.InteropServices;
using COServer.Entities;
namespace COServer.Network
{
public unsafe class MsgName : Msg
{
public const Int16 Id = _MSG_NAME;
public enum Action
{
None = 0,
Fireworks = 1,
CreateSyn = 2,
Syndicate = 3,
ChangeTitle = 4,
DelRole = 5,
Spouse = 6,
QueryNPC = 7, //To client, To Server
Wanted = 8, //To client
MapEffect = 9, //To client
RoleEffect = 10, //To client
MemberList = 11, //To client, To Server, dwData is index
KickOut_SynMem = 12,
QueryWanted = 13,
QueryPoliceWanted = 14,
PoliceWanted = 15,
QuerySpouse = 16,
AddDice_Player = 17, //BcastClient(INCLUDE_SELF) Ôö¼Ó÷»×ÓÍæ¼Ò// dwDataΪ÷»×Ó̯ID // To Server ¼ÓÈë ÐèÒªÔ*ÏûÏ¢·µ»Ø
DelDice_Player = 18, //BcastClient(INCLUDE_SELF) ɾ³ý÷»×ÓÍæ¼Ò// dwDataΪ÷»×Ó̯ID // To Server À뿪 ÐèÒªÔ*ÏûÏ¢·µ»Ø
DiceBonus = 19, //dwDataΪMoney
Sound = 20,
SynEnemie = 21,
SynAlly = 22,
Bavarder = 26,
};
public struct MsgInfo
{
public MsgHeader Header;
public Int32 Data;
public Byte Action;
public Byte Count;
public String[] Params;
};
public static Byte[] Create(Int32 Data, String Param, Action Action)
{
try
{
if (Param == null || Param.Length > _MAX_WORDSSIZE)
return null;
Byte[] Out = new Byte[13 + Param.Length];
fixed (Byte* p = Out)
{
*((Int16*)(p + 0)) = (Int16)Out.Length;
*((Int16*)(p + 2)) = (Int16)Id;
*((Int32*)(p + 4)) = (Int32)Data;
*((Byte*)(p + 8)) = (Byte)Action;
*((Byte*)(p + 9)) = (Byte)0x01;
*((Byte*)(p + 10)) = (Byte)Param.Length;
for (Byte i = 0; i < (Byte)Param.Length; i++)
*((Byte*)(p + 11 + i)) = (Byte)Param[i];
}
return Out;
}
catch (Exception Exc) { Program.WriteLine(Exc); return null; }
}
public static Byte[] Create(Int32 Data, String[] Params, Action Action)
{
try
{
if (Params == null || Params.Length < 1)
return null;
Int32 StrLength = 0;
for (Int32 i = 0; i < Params.Length; i++)
{
if (Params[i] == null || Params[i].Length > _MAX_WORDSSIZE)
return null;
StrLength += Params[i].Length + 1;
}
Byte[] Out = new Byte[12 + StrLength];
fixed (Byte* p = Out)
{
*((Int16*)(p + 0)) = (Int16)Out.Length;
*((Int16*)(p + 2)) = (Int16)Id;
*((Int32*)(p + 4)) = (Int32)Data;
*((Byte*)(p + 8)) = (Byte)Action;
*((Byte*)(p + 9)) = (Byte)Params.Length;
Int32 Pos = 10;
for (Int32 x = 0; x < Params.Length; x++)
{
*((Byte*)(p + Pos)) = (Byte)Params[x].Length;
for (Byte i = 0; i < (Byte)Params[x].Length; i++)
*((Byte*)(p + Pos + 1 + i)) = (Byte)Params[x][i];
Pos += Params[x].Length + 1;
}
}
return Out;
}
catch (Exception Exc) { Program.WriteLine(Exc); return null; }
}
public static void Process(Client Client, Byte[] Buffer)
{
try
{
Int16 MsgLength = (Int16)((Buffer[0x01] << 8) + Buffer[0x00]);
Int16 MsgId = (Int16)((Buffer[0x03] << 8) + Buffer[0x02]);
Int32 Data = (Int32)((Buffer[0x07] << 24) + (Buffer[0x06] << 16) + (Buffer[0x05] << 8) + Buffer[0x04]);
Action Action = (Action)Buffer[0x08];
Byte Count = Buffer[0x09];
String[] Params = new String[Count];
Int32 Pos = 10;
for (Int32 i = 0; i < Count; i++)
{
Params[i] = Program.Encoding.GetString(Buffer, Pos + 1, Buffer[Pos]);
Pos = Params[i].Length + 1;
}
switch (Action)
{
case Action.MemberList:
{
Player Player = Client.User;
if (Player == null)
return;
Console.WriteLine(Program.Dump(Buffer));
break;
}
case Action.QuerySpouse:
{
Player Player = Client.User;
if (Player == null)
return;
Player Target = null;
if (!World.AllPlayers.TryGetValue(Data, out Target))
return;
Player.Send(MsgName.Create(Target.UniqId, Target.Spouse, Action.QuerySpouse));
break;
}
case Action.Bavarder:
{
Player Target = null;
foreach (Player Player in World.AllPlayers.Values)
{
if (Player.Name == Params[0])
{
Target = Player;
break;
}
}
if (Target == null)
return;
String TargetInfo =
Target.UniqId + " " +
Target.Level + " " +
Target.Potency + " #" +
"GuildName" + " #" +
"FamilyName" + " " +
Target.Spouse + " " +
Target.Nobility.Rank + " " +
(Target.IsMan() ? (Byte)1 : (Byte)0);
Client.Send(MsgName.Create(0, new String[] { Target.Name, TargetInfo }, Action.Bavarder));
break;
}
default:
{
Console.WriteLine("Msg[{0}], Action[{1}] not implemented yet!", MsgId, (Int16)Action);
break;
}
}
}
catch (Exception Exc) { Program.WriteLine(Exc); }
}
}
}
|
|
|
08/01/2011, 18:15
|
#13
|
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
|
Quote:
Originally Posted by pro4never
Well you seem to have the string count correct now. Not sure why it wouldn't be displaying :S
I tried manually reading through the packet. Seems you may be off like 1 byte count.. I could have made a mistake but the final 30 was not part of the string count.
The two blank bytes at the end ARE intentional though. I have it in my structure as well.
|
yeah i will try to work on it again and i will tell you the result
Quote:
Originally Posted by CptSky
If it can help, here my MsgName packet.
Code:
using System;
using System.Runtime.InteropServices;
using COServer.Entities;
namespace COServer.Network
{
public unsafe class MsgName : Msg
{
public const Int16 Id = _MSG_NAME;
public enum Action
{
None = 0,
Fireworks = 1,
CreateSyn = 2,
Syndicate = 3,
ChangeTitle = 4,
DelRole = 5,
Spouse = 6,
QueryNPC = 7, //To client, To Server
Wanted = 8, //To client
MapEffect = 9, //To client
RoleEffect = 10, //To client
MemberList = 11, //To client, To Server, dwData is index
KickOut_SynMem = 12,
QueryWanted = 13,
QueryPoliceWanted = 14,
PoliceWanted = 15,
QuerySpouse = 16,
AddDice_Player = 17, //BcastClient(INCLUDE_SELF) Ôö¼Ó÷»×ÓÍæ¼Ò// dwDataΪ÷»×Ó̯ID // To Server ¼ÓÈë ÐèÒªÔ*ÏûÏ¢·µ»Ø
DelDice_Player = 18, //BcastClient(INCLUDE_SELF) ɾ³ý÷»×ÓÍæ¼Ò// dwDataΪ÷»×Ó̯ID // To Server À뿪 ÐèÒªÔ*ÏûÏ¢·µ»Ø
DiceBonus = 19, //dwDataΪMoney
Sound = 20,
SynEnemie = 21,
SynAlly = 22,
Bavarder = 26,
};
public struct MsgInfo
{
public MsgHeader Header;
public Int32 Data;
public Byte Action;
public Byte Count;
public String[] Params;
};
public static Byte[] Create(Int32 Data, String Param, Action Action)
{
try
{
if (Param == null || Param.Length > _MAX_WORDSSIZE)
return null;
Byte[] Out = new Byte[13 + Param.Length];
fixed (Byte* p = Out)
{
*((Int16*)(p + 0)) = (Int16)Out.Length;
*((Int16*)(p + 2)) = (Int16)Id;
*((Int32*)(p + 4)) = (Int32)Data;
*((Byte*)(p + 8)) = (Byte)Action;
*((Byte*)(p + 9)) = (Byte)0x01;
*((Byte*)(p + 10)) = (Byte)Param.Length;
for (Byte i = 0; i < (Byte)Param.Length; i++)
*((Byte*)(p + 11 + i)) = (Byte)Param[i];
}
return Out;
}
catch (Exception Exc) { Program.WriteLine(Exc); return null; }
}
public static Byte[] Create(Int32 Data, String[] Params, Action Action)
{
try
{
if (Params == null || Params.Length < 1)
return null;
Int32 StrLength = 0;
for (Int32 i = 0; i < Params.Length; i++)
{
if (Params[i] == null || Params[i].Length > _MAX_WORDSSIZE)
return null;
StrLength += Params[i].Length + 1;
}
Byte[] Out = new Byte[12 + StrLength];
fixed (Byte* p = Out)
{
*((Int16*)(p + 0)) = (Int16)Out.Length;
*((Int16*)(p + 2)) = (Int16)Id;
*((Int32*)(p + 4)) = (Int32)Data;
*((Byte*)(p + 8)) = (Byte)Action;
*((Byte*)(p + 9)) = (Byte)Params.Length;
Int32 Pos = 10;
for (Int32 x = 0; x < Params.Length; x++)
{
*((Byte*)(p + Pos)) = (Byte)Params[x].Length;
for (Byte i = 0; i < (Byte)Params[x].Length; i++)
*((Byte*)(p + Pos + 1 + i)) = (Byte)Params[x][i];
Pos += Params[x].Length + 1;
}
}
return Out;
}
catch (Exception Exc) { Program.WriteLine(Exc); return null; }
}
public static void Process(Client Client, Byte[] Buffer)
{
try
{
Int16 MsgLength = (Int16)((Buffer[0x01] << 8) + Buffer[0x00]);
Int16 MsgId = (Int16)((Buffer[0x03] << 8) + Buffer[0x02]);
Int32 Data = (Int32)((Buffer[0x07] << 24) + (Buffer[0x06] << 16) + (Buffer[0x05] << 8) + Buffer[0x04]);
Action Action = (Action)Buffer[0x08];
Byte Count = Buffer[0x09];
String[] Params = new String[Count];
Int32 Pos = 10;
for (Int32 i = 0; i < Count; i++)
{
Params[i] = Program.Encoding.GetString(Buffer, Pos + 1, Buffer[Pos]);
Pos = Params[i].Length + 1;
}
switch (Action)
{
case Action.MemberList:
{
Player Player = Client.User;
if (Player == null)
return;
Console.WriteLine(Program.Dump(Buffer));
break;
}
case Action.QuerySpouse:
{
Player Player = Client.User;
if (Player == null)
return;
Player Target = null;
if (!World.AllPlayers.TryGetValue(Data, out Target))
return;
Player.Send(MsgName.Create(Target.UniqId, Target.Spouse, Action.QuerySpouse));
break;
}
case Action.Bavarder:
{
Player Target = null;
foreach (Player Player in World.AllPlayers.Values)
{
if (Player.Name == Params[0])
{
Target = Player;
break;
}
}
if (Target == null)
return;
String TargetInfo =
Target.UniqId + " " +
Target.Level + " " +
Target.Potency + " #" +
"GuildName" + " #" +
"FamilyName" + " " +
Target.Spouse + " " +
Target.Nobility.Rank + " " +
(Target.IsMan() ? (Byte)1 : (Byte)0);
Client.Send(MsgName.Create(0, new String[] { Target.Name, TargetInfo }, Action.Bavarder));
break;
}
default:
{
Console.WriteLine("Msg[{0}], Action[{1}] not implemented yet!", MsgId, (Int16)Action);
break;
}
}
}
catch (Exception Exc) { Program.WriteLine(Exc); }
}
}
}
|
thnx mate i will test it and tell you if it works  "i like ur style ur remembering me of C++  "
---------------------------------------------------------------------------
EDIT:
okey well i fixed it :P
how!
Code:
public StringPacket(string str, string other)
: base(0x3F7, (ushort)(14 + str.Length + other.Length))
{
Texts = new List<string>() { str, other };
WriteStringList(9, Texts);
}
because add isn't really a good way plus , it's not right to Pass Texts as A public field :P
Thanks:
pro4never
&
CptSky
for trying to help me i appreciate it
|
|
|
All times are GMT +1. The time now is 11:49.
|
|