|
You last visited: Today at 13:13
Advertisement
[request/help] Correct way of sending EntityMove/Jump packets?
Discussion on [request/help] Correct way of sending EntityMove/Jump packets? within the CO2 Programming forum part of the Conquer Online 2 category.
09/02/2013, 22:56
|
#1
|
elite*gold: 0
Join Date: Nov 2009
Posts: 19
Received Thanks: 4
|
[request/help] Correct way of sending EntityMove/Jump packets?
this have been bothered me for a while and i know that i am not the only one who struggles to break this tough nut. The methodology of sending the Jump packets to clients is a pain in the ass as there are many things to be considered in order to implement a bug-free method of doing it.
Let's say that player X jumps(distance between them > max_view_distance before jump) near player Y(distance between them <= max_view_distance after jump), both packets for entity information are sent(
Code:
X->Send((EntityPacket)Y); Y->Send((EntityPacket)X);
), however, it happens sometimes that either player X does not see player Y or viceversa/
Any thoughts how to fix this?
the method i am using right now is the one from the HybridCo source for client 5017:
Code:
void PlayerJump(CGameClient *Client, DataPacket *Ptr)
{
WORD X = LOWORD(Ptr->dwParam);
WORD Y = HIWORD(Ptr->dwParam);
if (Distance(X, Y, Client->Entity->X, Client->Entity->Y) > MAX_SCREEN_WIDTH)
{
Client->Socket->Disconnect();
return;
}
Client->Entity->X = X;
Client->Entity->Y = Y;
SendRangePacket(Ptr, Client->Entity, true);
LoadScreen(Client, NULL);
}
void SendRangePacket(void* Packet, IMapObject* mapObj, bool SendSelf, StdConquerCallback Callback, bool Delete)
{
CGameClient* Client;
CDatabaseRoot::Core->Clients->ObtainSyncHandle();
for (int i = 0; i < CDatabaseRoot::Core->Clients->Count; i++)
{
Client = CDatabaseRoot::Core->Clients->Elements[i];
if (Client->Entity->Map == mapObj->Map)
{
if (Distance(Client->Entity->X, Client->Entity->Y, mapObj->X, mapObj->Y) <= MAX_VIEW_DISTANCE)
{
if (Client->ID == mapObj->UID)
{
if (SendSelf)
{
Client->Send(Packet);
if (Callback != NULL)
Callback(mapObj, Client->Entity, NULL);
}
}
else
{
Client->Send(Packet);
if (Callback != NULL)
Callback(mapObj, Client->Entity, NULL);
}
}
}
}
CDatabaseRoot::Core->Clients->FreeSyncHandle();
if (Delete)
{
delete[] Packet;
}
}
void LoadScreen(CGameClient *Client, DataPacket *Ptr)
{
if (Ptr != NULL) // LoadScreen() Standerd
{
Client->Screen->Wipe();
Ptr->ID = DATA_ID_SET_MAP_COLOR;
Ptr->dwParam = 0xFFFFFFFF;
Client->Send(Ptr);
// <todo = weather>
// </todo>
}
else
{
Client->Screen->Cleanup();
}
// <Clients>
CDatabaseRoot::Core->Clients->ObtainSyncHandle();
for (int i = 0; i < CDatabaseRoot::Core->Clients->Count; i++)
{
CGameClient* iClient = CDatabaseRoot::Core->Clients->Elements[i];
if (iClient->Entity->Map == Client->Entity->Map &&
iClient->ID != Client->ID)
{
if (Distance(Client->Entity->X, Client->Entity->Y,
iClient->Entity->X, iClient->Entity->Y) <= MAX_SCREEN_WIDTH)
{
if (Client->Screen->Add(iClient->Entity))
{
Client->Send(iClient->Entity->Data);
if (Ptr != NULL) // LoadScreen() Standerd
{
iClient->Screen->Add(Client->Entity);
iClient->Send(Client->Entity->Data);
}
}
}
}
}
CDatabaseRoot::Core->Clients->FreeSyncHandle();
// </Clients>
}
|
|
|
09/02/2013, 23:00
|
#2
|
elite*gold: 0
Join Date: Dec 2012
Posts: 1,761
Received Thanks: 950
|
however, it happens sometimes that either player X does not see player Y or viceversa/
Any thoughts how to fix this?
Screen problem, not the way jump is handled.
Also you shouldn't clear the whole screen for every jump (Ex. reloading the whole screen.)
You should first check existing entities in the screen whether they're outside of the screen and then check for new entities that has to be added to it.
|
|
|
09/02/2013, 23:49
|
#3
|
elite*gold: 0
Join Date: Nov 2009
Posts: 19
Received Thanks: 4
|
Quote:
Originally Posted by Super Aids
[I]
Also you shouldn't clear the whole screen for every jump (Ex. reloading the whole screen.)
You should first check existing entities in the screen whether they're outside of the screen and then check for new entities that has to be added to it.
|
yes i know, this is the original HybridCO code(i've done lots of changed to it), but i posted this code for showing the method i use.
i really doubt that the problem is not in the code tho as this happens way too often to be a client bug or whatever and i don't recall this happening on the TQ servers either. Anyway, i know a friend who is having the same problem on a 5165 client although he reduced the distance from which he sends the spawn entity packet(by using the mathematical formula for distance between 2 points rather than max(x1-x2, y1-y2)). it might be that the server computes the coordinates instantly when the jump request is send ignoring the mid-air time and this might differ from the client?
thx for the fast response.
PS: if anyone got a way around this problem i would greatly appreciate your insight. Thx in advance
EDIT: or by screen problem you mean the way UserScreen is updated and not a client bug?
|
|
|
09/04/2013, 00:35
|
#4
|
elite*gold: 0
Join Date: Nov 2009
Posts: 19
Received Thanks: 4
|
found the problem; it figures that you have to send the jump packet to the client that request the Jump FIRST so he can acknowledge the coordinates before trying to spawn entities in his screen(otherwise the client computes the distance between you and the entity requested and sees it as being to far away);
EDIT: #can be closed
Will post here for anybody who is wondering/struggling with this too
Code:
void PlayerJump(CGameClient *Client, DataPacket *Ptr)
{
WORD X = LOWORD(Ptr->dwParam);
WORD Y = HIWORD(Ptr->dwParam);
if(Distance(X, Y, Client->X, Client->Y) > MAX_SCREEN_WIDTH)
{
Client->Socket->Disconnect( );
return;
}
Client->SetCoords(X, Y);
Client->Send(Ptr); // VERY IMPORTANT! SEND THE PACKET TO THE REQUESTING PLAYER FIRST
// So he can acknowledge the new location before trying to spawn chars into he's screen
CDatabaseRoot::Core->Clients->ObtainSyncHandle( );
for(int i = 0; i < CDatabaseRoot::Core->Clients->Count; i++)
{
CGameClient *C = CDatabaseRoot::Core->Clients->Elements[i];
if(C->Map != Client->Map || C->ID == Client->ID)
continue;
if(Distance(Client->PrevX, Client->PrevY, C->X, C->Y) <= MAX_VIEW_DISTANCE)
{
// distance dintre between characters BEFORE jump <= MAX_VIEW_DISTANCE
C->Send(Ptr);
if(Distance(Client->X, Client->Y, C->X, C->Y) > MAX_VIEW_DISTANCE)
{
// distance between characters AFTER jump > MAX_VIEW_DISTANCE
// we DO NOT need to take care of sending EntityRemovePacket here
// as the client automatically removes the entity if it goes out of range
Client->ScreenObjects->Remove(C);
C->ScreenObjects->Remove(Client);
}
}
else
{
// distance between the characters BEFORE jump > MAX_VIEW_DISTANCE
// TODO: spawn at the T point and then send the jump packet so the char appears
// to be jumping into the screen rather than magically spawning
if(Distance(Client->X, Client->Y, C->X, C->Y) <= MAX_VIEW_DISTANCE)
{
// distance between characters AFTER jump <= MAX_VIEW_DISTANCE
Client->ScreenObjects->Add(C);
Client->Send(C->Data);
C->ScreenObjects->Add(Client);
C->Send(Client->Data);
}
}
}
CDatabaseRoot::Core->Clients->FreeSyncHandle( );
// TODO: monsters, items, NPCs and other Objects needed to be handled
}
|
|
|
 |
Similar Threads
|
Sending Packets
11/29/2012 - AutoIt - 6 Replies
Hey,
so I'm trying to send packets to a game called Pokemon World Online, I've been using WPE in order to sniff the packets, using WPE sending the packets its ridiculously easy so I've been trying to do the same with autoit script.
After a lot of research I know that TCP function should do it but I've always failed to use the same socket as the same or even to listen to the right ports or something, I'm completely lost here.
I know this can be done and I'm not asking for someone to...
|
Help sending packets
06/27/2012 - SRO Coding Corner - 2 Replies
well i knew that i need to put the packet in a byte array
so i defined it BYTE pack = {
0x01, 0x00,
0x4F, 0x70,
0x20, 0x00,
0x04
};
and when i send it using the send through a socket like this
|
Help for sending packets
05/11/2012 - PW Hacks, Bots, Cheats, Exploits - 1 Replies
Hello Dear programmers, botovody!
I am a novice programmer, and started programming in the language of Delphi!
there is a couple of my works Каталог файлов - PwRuf - уникальный бот для Perfect World!
But another question!
I would like to implement the sending of packages to craft nirvana clothing, weapons. But I have a problem with traffic light emitted from the fact that the package that I send a very large ie 256 characters!
Please help or point me where to...
|
are these packets correct?
12/16/2010 - SRO Coding Corner - 16 Replies
I've been busy creating my own packet sniffer for silkroad. But I don't know if the packets are oke. because I use winPcap to sniff the packets and it has all those headers init so I had to strip them but I don't know if I got them all.
These are the first few packets which I got after I started the launcher.
http://img522.imageshack.us/img522/9574/packetsni ffer.png
Thank you:)
|
Sending Packets !!!
09/07/2008 - Kal Online - 14 Replies
now i know how to sniff / analyse packets ... but what then ? :)
how can i send packets ?? to pimp or mix weapon for example
i just need the way to send , and then i can depend on myself :D
|
All times are GMT +1. The time now is 13:15.
|
|