|
You last visited: Today at 10:04
Advertisement
Differing Entity ID's
Discussion on Differing Entity ID's within the CO2 Programming forum part of the Conquer Online 2 category.
02/23/2011, 22:24
|
#1
|
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
|
Differing Entity ID's
I just came to realize that the entity ID in spawn packets and the target ID in action packet.
I am not sure if the ID decode has outdated or what; i qouted prog4never's code for decoding coordinates and targetID
|
|
|
02/23/2011, 23:11
|
#2
|
elite*gold: 0
Join Date: Nov 2006
Posts: 805
Received Thanks: 464
|
People give these identifiers different names obviously but there should be an Entity ID and Entity UID.
The Entity UID is what you use for your target parameter. ID is generic, it's like 1080001 is for a DB but 3923442 might be the UID for that specific ID.
UID is an int starting at byte 8.
|
|
|
02/24/2011, 00:05
|
#3
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
|
Also fyi...
Monster uids are 300k-500k
Player uids are 1million++
Tnps are I THINK 100k-200k but I could be wrong. (been a while since I saw)
But yah. UID identifies the target and is used in almost all packets.
IE: their movement, actions, despawn packet, trade/team stuff, etc.
|
|
|
02/24/2011, 00:21
|
#4
|
elite*gold: 0
Join Date: Jan 2008
Posts: 1,443
Received Thanks: 1,175
|
Can be usefull if you don't want that the client think that your monsters are NPC... From Eudemon Online, but the same on CO2.
Code:
/////////////////////////////////////////////////////////////////////
// ID空间
const OBJID SCENEID_FIRST = 000001; // SCENE的第一个ID
const OBJID SYSNPCID_FIRST = 00001; // SYSNPC的第一个ID
const OBJID SYSNPCID_LAST = 99999; // SYSNPC的最后一个ID
const OBJID DYNANPCID_FIRST = 100001; // DYNANPC的第一个ID
const OBJID DYNANPCID_LAST = 199999; // DYNANPC的最后一个ID
const OBJID SCENEID_LAST = 299999; // SCENE的最后一个ID
const OBJID NPCSERVERID_FIRST = 400001; // NPC的第一个ID
const OBJID MONSTERID_FIRST = 400001; // MONSTER的第一个ID
const OBJID MONSTERID_LAST = 499999; // MONSTER的最后一个ID
const OBJID PETID_FIRST = 500001; // PET的第一个ID
const OBJID PETID_LAST = 599999; // PET的最后一个ID
const OBJID NPCSERVERID_LAST = 899999; // NPC的最后一个ID
const OBJID TRAPID_FIRST = 900001; // 魔法陷阱的第一个ID
const OBJID MAGICTRAPID_FIRST = 900001; // 玩家魔法的第一个ID
const OBJID MAGICTRAPID_LAST = 989999; // 玩家魔法的最后一个ID
const OBJID SYSTRAPID_FIRST = 990001; // 系统陷阱的第一个ID
const OBJID SYSTRAPID_LAST = 999999; // 系统陷阱的最后一个ID
const OBJID TRAPID_LAST = 999999; // 魔法陷阱的最后一个ID
const OBJID PLAYER_ID_FIRST = 1000000; // Player的第一个ID
const OBJID PLAYER_ID_LAST = 1999999999; // Player的最后一个ID
const OBJID CALLPETID_FIRST = 2000000000; // CALLPET的第一个ID
const OBJID CALLPETID_LAST = 3999999999; // CALLPET的最后一个ID
const OBJID CLIENT_ID_FIRST = 4000000000; // 为客户端保留的ID空间
const OBJID MOUSE_PLAYER_ID = 4000000001; // 放NPC时在鼠标上显示
const OBJID _IDMAX_NPC =999999;
|
|
|
02/24/2011, 00:43
|
#5
|
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
|
Quote:
Originally Posted by CptSky
Can be usefull if you don't want that the client think that your monsters are NPC... From Eudemon Online, but the same on CO2.
Code:
const OBJID PETID_FIRST = 500001; // PET的第一个ID
const OBJID PETID_LAST = 599999; // PET的最后一个ID
const OBJID CALLPETID_FIRST = 2000000000; // CALLPET的第一个ID
const OBJID CALLPETID_LAST = 3999999999; // CALLPET的最后一个ID
|
Didn't know about these ids, that's kinda useful
|
|
|
02/24/2011, 02:20
|
#6
|
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
|
ermmm, yes i noticed that UIDs are diffrent from IDs.
While i am storing char/mob spawn list, i did realize that mobs/guards' IDs are less than 999,999 while player IDs are more than 999,999. That is what helped me to build the 2 hashtables.
Anyways, my problem is that, when i look into the target UID in the action packet, Eg, thunder, The UID is a bit off as compared to the UID i have obtained through spawn packet.
|
|
|
02/24/2011, 02:39
|
#7
|
elite*gold: 0
Join Date: Jun 2005
Posts: 692
Received Thanks: 353
|
Quote:
Originally Posted by shitboi
ermmm, yes i noticed that UIDs are diffrent from IDs.
While i am storing char/mob spawn list, i did realize that mobs/guards' IDs are less than 999,999 while player IDs are more than 999,999. That is what helped me to build the 2 hashtables.
Anyways, my problem is that, when i look into the target UID in the action packet, Eg, thunder, The UID is a bit off as compared to the UID i have obtained through spawn packet.
|
Are you decoding the magic attack information properly?
|
|
|
02/24/2011, 02:51
|
#8
|
elite*gold: 0
Join Date: Nov 2006
Posts: 805
Received Thanks: 464
|
Quote:
Originally Posted by shitboi
ermmm, yes i noticed that UIDs are diffrent from IDs.
While i am storing char/mob spawn list, i did realize that mobs/guards' IDs are less than 999,999 while player IDs are more than 999,999. That is what helped me to build the 2 hashtables.
Anyways, my problem is that, when i look into the target UID in the action packet, Eg, thunder, The UID is a bit off as compared to the UID i have obtained through spawn packet.
|
Thunder, and all magic attack packets are encrypted.
Regular melee attacks are not though.
|
|
|
02/24/2011, 03:41
|
#9
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
|
Quote:
Originally Posted by shitboi
ermmm, yes i noticed that UIDs are diffrent from IDs.
While i am storing char/mob spawn list, i did realize that mobs/guards' IDs are less than 999,999 while player IDs are more than 999,999. That is what helped me to build the 2 hashtables.
Anyways, my problem is that, when i look into the target UID in the action packet, Eg, thunder, The UID is a bit off as compared to the UID i have obtained through spawn packet.
|
As mentioned... skill usage is encrypted.
Here's some handy code from my proxy (pulled from tannels proxy)
Code:
#region Encrypting
Target += 0x746F4AE6;
Target ^= User.UID;
Target ^= 0x5F2D2463;
Target = ((Target << 13) | (Target >> 19));
ulong _X = X + 0xffff22ee;
_X -= 0xffff0000;
_X = ((_X << 15) | (_X >> 1));
_X ^= 0x2ed6;
_X ^= User.UID;
X = (ushort)_X;
ulong _Y = Y + 0xffff8922;
_Y -= 0xffff0000;
_Y = ((_Y << 11) | (_Y >> 5));
_Y ^= 0xb99b;
_Y ^= User.UID;
Y = (ushort)_Y;
ushort SkillId = S.ID;
SkillId += 0xeb42;
SkillId = (ushort)(SkillId << 13 | SkillId >> 0x3);
SkillId = (ushort)(SkillId ^ User.UID);
SkillId ^= 0x915d;
#endregion
Simply reverse that for your decryption code.
Also...
Hashtables? Tannel much?
|
|
|
02/24/2011, 11:53
|
#10
|
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
|
I actually reversed that and realized that the values are a bit off.
As for the hashtable part, that is a unsynchronised java direct access collection that do not give me too many exceptions, lol. I picked that only for simplicity's sake.
Anyways, i'll revisit my codes after i am done with my exam later. lol
EDIT:
i guess i'll stick this on before i leave; I do not think there is a problem with the decoding with skill at least. I am getting all the correct values for skills used.
@nTL3fTy: i believe i am decoding them properly.
@Ian : yes, i did realize that and had handled it
Code:
public static class Action {
public int len, packetType, timer, charID, targetID, coordX, coordY, actionType, actionValue; //action value also known as skill ID
byte[] trailer;
byte[] pac; //the packet
public Action(byte[] p) {
pac = p;
len = Utility.getUShort(p, 0);
packetType = Utility.getUShort(p, 2);
timer = Utility.getInt(p, 4);
charID = Utility.getInt(p, 8);
targetID = Utility.getUShort(p, 12);
coordX = Utility.getUShort(p, 16);
coordY = Utility.getUShort(p, 18);
actionType = Utility.getInt(p, 20); //2=meelee, 24=skill/magic
if (actionType != 2) {
//decode skill id
short aValue = (short) (((long) p[24] & 0xFF) | (((long) p[25] & 0xFF) << 8));
aValue ^= (short) (0x915d & 0xffff);
aValue ^= (short) (charID & 0xffff);
aValue = (short) ((aValue << 0x3 | aValue >> 0xd) & 0xffff);
aValue -= 0xeb42;
actionValue = aValue;
targetID = decodeTarget(targetID, charID);
coordX = decodeXCord(coordX, charID);
coordY = decodeYCord(coordY, charID);
} else {
actionValue = Utility.getInt(p, 24);
}
trailer = new byte[p.length - 28];
System.arraycopy(p, 24, trailer, 0, p.length - 28);
}
@Override
public String toString() {
return "Packet Length :" + len + "\ntype :" + packetType + "\nTimer :" + timer + "\nChar ID :" + charID + "\nTarget ID :"
+ targetID + "\nCoordX :" + coordX + "\nCoordY :" + coordY + "\nAction Type :" + actionType + "\nAction Value :"
+ actionValue + "\n";
}
public static int decodeTarget(int target, int id){
//decode target id
target = ((target >> 13) | (target << 19));
target ^= 0x5F2D2463;
target ^= id;
target -= 0x746F4AE6;
return target;
}
public static int decodeXCord( int x, int id){
//decode X coordinate
long X = x;
X ^= (id & 0xffff);
X ^= 0x2ed6;
X = ((X << 1) | ((X & 0x8000) >> 15)) & 0xffff;
X |= 0xffff0000;
X -= 0xffff22ee;
return (int)X;
}
public static int decodeYCord(int y, int id){
//decode Y coordinate
long Y = y;
Y = Y ^ (id & 0xffff) ^ 0xb99b;
Y = ((Y << 5) | ((Y & 0xF800) >> 11)) & 0xffff;
Y |= 0xffff0000;
Y -= 0xffff8922;
return (int)Y;
}
public static int encodeTarget(int Target, int id){
Target += 0x746F4AE6;
Target ^= id;
Target ^= 0x5F2D2463;
Target = ((Target << 13) | (Target >> 19));
return Target;
}
public static int encodeXCord(int xcord, int id){
long _X = xcord + 0xffff22ee;
_X -= 0xffff0000;
_X = ((_X << 15) | (_X >> 1));
_X ^= 0x2ed6;
_X ^= id;
return (int)_X;
}
public static int encodeYCord(int ycord, int id){
long _Y = ycord + 0xffff8922;
_Y -= 0xffff0000;
_Y = ((_Y << 11) | (_Y >> 5));
_Y ^= 0xb99b;
_Y ^= id;
return (int)_Y;
}
public static int encodeSkill(int skill, int id){
short SkillId = (short) (skill & 0xffff);
SkillId += 0xeb42;
SkillId = (short)(SkillId << 13 | SkillId >> 0x3);
SkillId = (short)(SkillId ^ id);
SkillId ^= 0x915d;
return SkillId;
}
public static byte[] buildSkillPacket(int timer, int id, int targetid, int xcord, int ycord, int actionValue){
byte[] packet = new byte[36];
System.arraycopy(Utility.Int16ToBytes(28), 0, packet, 0, 2);
System.arraycopy(Utility.Int16ToBytes(1022), 0, packet, 2, 2);
System.arraycopy(Utility.Int32ToBytes(timer), 0, packet, 4, 4);
System.arraycopy(Utility.Int32ToBytes(id), 0, packet, 8, 4);
System.arraycopy(Utility.Int32ToBytes(targetid), 0, packet, 12, 4);
System.arraycopy(Utility.Int16ToBytes(xcord), 0, packet, 16, 2);
System.arraycopy(Utility.Int16ToBytes(ycord), 0, packet, 18, 2);
System.arraycopy(Utility.Int32ToBytes(24), 0, packet, 20, 4);
//encode actionValue
short skill = (short) actionValue;
skill += 0xeb42;
skill = (short)(skill << 13 | skill >> 0x3);
skill = (short)(skill ^ (id & 0xffff));
skill ^= 0x915d;
System.arraycopy(Utility.Int32ToBytes(skill), 0, packet, 24, 4);
System.arraycopy("TQClient".getBytes(), 0, packet, 28, 8);
return packet;
}
}
|
|
|
02/24/2011, 17:11
|
#11
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
|
Quote:
Originally Posted by shitboi
I actually reversed that and realized that the values are a bit off.
As for the hashtable part, that is a unsynchronised java direct access collection that do not give me too many exceptions, lol. I picked that only for simplicity's sake.
Anyways, i'll revisit my codes after i am done with my exam later. lol
EDIT:
i guess i'll stick this on before i leave; I do not think there is a problem with the decoding with skill at least. I am getting all the correct values for skills used.
@nTL3fTy: i believe i am decoding them properly.
@Ian : yes, i did realize that and had handled it
Code:
public static class Action {
public int len, packetType, timer, charID, targetID, coordX, coordY, actionType, actionValue; //action value also known as skill ID
byte[] trailer;
byte[] pac; //the packet
public Action(byte[] p) {
pac = p;
len = Utility.getUShort(p, 0);
packetType = Utility.getUShort(p, 2);
timer = Utility.getInt(p, 4);
charID = Utility.getInt(p, 8);
targetID = Utility.getUShort(p, 12);
coordX = Utility.getUShort(p, 16);
coordY = Utility.getUShort(p, 18);
actionType = Utility.getInt(p, 20); //2=meelee, 24=skill/magic
if (actionType != 2) {
//decode skill id
short aValue = (short) (((long) p[24] & 0xFF) | (((long) p[25] & 0xFF) << 8));
aValue ^= (short) (0x915d & 0xffff);
aValue ^= (short) (charID & 0xffff);
aValue = (short) ((aValue << 0x3 | aValue >> 0xd) & 0xffff);
aValue -= 0xeb42;
actionValue = aValue;
targetID = decodeTarget(targetID, charID);
coordX = decodeXCord(coordX, charID);
coordY = decodeYCord(coordY, charID);
} else {
actionValue = Utility.getInt(p, 24);
}
trailer = new byte[p.length - 28];
System.arraycopy(p, 24, trailer, 0, p.length - 28);
}
@Override
public String toString() {
return "Packet Length :" + len + "\ntype :" + packetType + "\nTimer :" + timer + "\nChar ID :" + charID + "\nTarget ID :"
+ targetID + "\nCoordX :" + coordX + "\nCoordY :" + coordY + "\nAction Type :" + actionType + "\nAction Value :"
+ actionValue + "\n";
}
public static int decodeTarget(int target, int id){
//decode target id
target = ((target >> 13) | (target << 19));
target ^= 0x5F2D2463;
target ^= id;
target -= 0x746F4AE6;
return target;
}
public static int decodeXCord( int x, int id){
//decode X coordinate
long X = x;
X ^= (id & 0xffff);
X ^= 0x2ed6;
X = ((X << 1) | ((X & 0x8000) >> 15)) & 0xffff;
X |= 0xffff0000;
X -= 0xffff22ee;
return (int)X;
}
public static int decodeYCord(int y, int id){
//decode Y coordinate
long Y = y;
Y = Y ^ (id & 0xffff) ^ 0xb99b;
Y = ((Y << 5) | ((Y & 0xF800) >> 11)) & 0xffff;
Y |= 0xffff0000;
Y -= 0xffff8922;
return (int)Y;
}
public static int encodeTarget(int Target, int id){
Target += 0x746F4AE6;
Target ^= id;
Target ^= 0x5F2D2463;
Target = ((Target << 13) | (Target >> 19));
return Target;
}
public static int encodeXCord(int xcord, int id){
long _X = xcord + 0xffff22ee;
_X -= 0xffff0000;
_X = ((_X << 15) | (_X >> 1));
_X ^= 0x2ed6;
_X ^= id;
return (int)_X;
}
public static int encodeYCord(int ycord, int id){
long _Y = ycord + 0xffff8922;
_Y -= 0xffff0000;
_Y = ((_Y << 11) | (_Y >> 5));
_Y ^= 0xb99b;
_Y ^= id;
return (int)_Y;
}
public static int encodeSkill(int skill, int id){
short SkillId = (short) (skill & 0xffff);
SkillId += 0xeb42;
SkillId = (short)(SkillId << 13 | SkillId >> 0x3);
SkillId = (short)(SkillId ^ id);
SkillId ^= 0x915d;
return SkillId;
}
public static byte[] buildSkillPacket(int timer, int id, int targetid, int xcord, int ycord, int actionValue){
byte[] packet = new byte[36];
System.arraycopy(Utility.Int16ToBytes(28), 0, packet, 0, 2);
System.arraycopy(Utility.Int16ToBytes(1022), 0, packet, 2, 2);
System.arraycopy(Utility.Int32ToBytes(timer), 0, packet, 4, 4);
System.arraycopy(Utility.Int32ToBytes(id), 0, packet, 8, 4);
System.arraycopy(Utility.Int32ToBytes(targetid), 0, packet, 12, 4);
System.arraycopy(Utility.Int16ToBytes(xcord), 0, packet, 16, 2);
System.arraycopy(Utility.Int16ToBytes(ycord), 0, packet, 18, 2);
System.arraycopy(Utility.Int32ToBytes(24), 0, packet, 20, 4);
//encode actionValue
short skill = (short) actionValue;
skill += 0xeb42;
skill = (short)(skill << 13 | skill >> 0x3);
skill = (short)(skill ^ (id & 0xffff));
skill ^= 0x915d;
System.arraycopy(Utility.Int32ToBytes(skill), 0, packet, 24, 4);
System.arraycopy("TQClient".getBytes(), 0, packet, 28, 8);
return packet;
}
}
|
Targets are 4 byte uints, not 2 byte ushorts.
For simplicity sake here's my olllddd decryption code from my packethandler
Code:
ushort SkillId = Convert.ToUInt16(((long)Data[24] & 0xFF) | (((long)Data[25] & 0xFF) << 8));
SkillId ^= (ushort)0x915d;
SkillId ^= (ushort)Client.UID;
SkillId = (ushort)(SkillId << 0x3 | SkillId >> 0xd);
SkillId -= 0xeb42;
if (!Client.Skills.ContainsKey(SkillId))
return;
Target = ((Target >> 13) | (Target << 19));
Target ^= 0x5F2D2463;
Target ^= Client.UID;
Target -= 0x746F4AE6;
ushort TargetX = 0;
ushort TargetY = 0;
long xx = (Data[16] & 0xFF) | ((Data[17] & 0xFF) << 8);
long yy = (Data[18] & 0xFF) | ((Data[19] & 0xFF) << 8);
xx = xx ^ (Client.UID & 0xffff) ^ 0x2ed6;
xx = ((xx << 1) | ((xx & 0x8000) >> 15)) & 0xffff;
xx |= 0xffff0000;
xx -= 0xffff22ee;
yy = yy ^ (Client.UID & 0xffff) ^ 0xb99b;
yy = ((yy << 5) | ((yy & 0xF800) >> 11)) & 0xffff;
yy |= 0xffff0000;
yy -= 0xffff8922;
TargetX = Convert.ToUInt16(xx);
TargetY = Convert.ToUInt16(yy);
Such a complete mess but w/e.
|
|
|
02/24/2011, 20:16
|
#12
|
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
|
Ohh !!!! ... thank you to pointing out my mistake. Now that you mentioned it, it's too obvious . I am too used to auto complete. lol
Will test it out later.
|
|
|
02/24/2011, 20:57
|
#13
|
elite*gold: 0
Join Date: Jun 2009
Posts: 378
Received Thanks: 141
|
Code:
private uint ror32(uint value, int amount)
{
return ((value >> amount) | (value << (32 - amount)));
}
private uint rol32(uint value, int amount)
{
return ((value << amount) | (value >> (32 - amount)));
}
private ushort ror16(ushort value, int amount)
{
return (ushort)((value >> amount) | (value << (16 - amount)));
}
private ushort rol16(ushort value, int amount)
{
return (ushort)((value << amount) | (value >> (16 - amount)));
}
public void Decrypt(uint Seed)
{
uint uID = this.UID;
ushort x = this.X;
ushort y = this.Y;
ushort spellID = this.SpellID;
this.X = (ushort)(this.rol16((ushort)((x ^ 11990) ^ ((ushort)uID)), 1) - 8942);
this.Y = (ushort)(this.rol16((ushort)((y ^ 47515) ^ ((ushort)uID)), 5) - 35106);
this.SpellID = (ushort)(this.rol16((ushort)((spellID ^ 37213) ^ ((ushort)uID)), 3) - 60226);
OpponentUID = (uint)Assembler.RollRight(OpponentUID, 13, 32);
OpponentUID = (OpponentUID ^ 0x5F2D2463 ^ Seed) - 0x746F4AE6;
}
// Assembler Code
public class Assembler
{
public static int RollLeft(uint Value, byte Roll, byte Size)
{
Roll = (byte)(Roll & 0x1F);
return (int)((Value << Roll) | (Value >> (Size - Roll)));
}
public static int RollRight(uint Value, byte Roll, byte Size)
{
Roll = (byte)(Roll & 0x1F);
return (int)((Value << (Size - Roll)) | (Value >> Roll));
}
}
If you change the Rolls from using the ones above you can use them and cut out rol6 and the other never got around to it tho.
One originally from my first proxy thanks to Grabola helped me with it. I have a much more capable neater,cleaner version now but this one will work just as good.
|
|
|
02/25/2011, 18:20
|
#14
|
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
|
Thanks for everyone's help, I realized where my problem lies (besides the one p4n pointed out).
EDIT: problem solved...
need to use right shift unsigned operator >>>
Code:
public static int decodeTarget(int target, int id){
//decode target id
target = ( (target >>> 13) | (target << 19)); //&0xffffffff ;
target ^= 0x5F2D2463;
target ^= (id & 0xffffffff);
target -= 0x746F4AE6;
return target;
}
|
|
|
 |
Similar Threads
|
Read Entity Name from memory
11/07/2009 - Aion - 0 Replies
I can't seem to read a name of an entity.
Using Autoit3 with Nomad mem read. Does anyone have experience with this and what to pass to the memory read and how the data is returned in order to get the string from memory?
Thanks
|
[REQUEST]Full list NPC ID's ITEMS ID's, MAP ID's for 5095 source
06/03/2009 - CO2 Private Server - 1 Replies
Any have a full list? TY in advanced.
|
Ofsets to entity table for Radar
01/06/2009 - General Gaming Discussion - 1 Replies
Hello everyone,
i have big problem to locate offsets for radar. Using CE 5.4 im trying to locate count of entities ( it should follow a pointer on array of entities ) - but its really hard to find well controlled place in game where i can control an amount of entities around me. Probably there are other methods to track this pointer down? Like reverse pointer search from Name of char? Or name of random entity?
Thanks in advance.
|
Special Entity
09/01/2005 - World of Warcraft - 4 Replies
Well, I was doing a stockade gangbang to lvl my mage. I pulled all the mobs to the beginning, and waited in the wall. As I looked on the minimap and point in the "Mob Train" I saw this strange "Jcffb0b" Entity/Player/Mob/Npc/Shit. I was like goddammnitagmigottagetthefuckouttahere.
When I did it again later, there were the same thing... Maybe someone knows what it is? Don't think it's something harmful anymore, just curious about it :P
...
|
All times are GMT +1. The time now is 10:05.
|
|