Ping System (OTHire)

Vantoria

www.ClassicOT.us
Joined
Jun 6, 2014
Messages
110
Reaction score
10
Location
USA
Hello i have an otclient compiled with ping system but i cant get it work in OTHire, i tryed the ping system with tibianic client sources and it Works perfectly so what is the problem between othire and otclient?
 

secondlife

Intermediate OT User
Joined
Aug 1, 2009
Messages
248
Reaction score
18
you need to add the respective functions for this system works (ServerSide)

The default sources from othire dont support this feature.
 

Gesior.pl

Mega Noob&LOL 2012
Premium User
Joined
Sep 18, 2007
Messages
1,973
Reaction score
870
Location
PLand
OTHire from Github is for protocol 7.72.

In Tibia there was 2 versions of 'ping'. One called 'ping' and second 'ping back'.

One was only to check if connection to client work.
Other did measure ping between server and client.

'ping' was added in Tibia 9.53:
edubart/otclient

and OTClient make it work/show result only when you set version 9.53+.

If you added it to server, you can try to force it in OTClient.
AFTER you load list of characters (in this moment client enables features based on selected client version). Open 'Terminal' and type:
PHP:
g_game.enableFeature(GameClientPing)
Then login to game and check if it shows ping.
 
OP
Vantoria

Vantoria

www.ClassicOT.us
Joined
Jun 6, 2014
Messages
110
Reaction score
10
Location
USA
the problema is that i'm using a custom otc so it dont have Terminal window but i was wondering why the ping system Works on Tibianic client? because othire already have implemented the ping system so there is no way to edit the functions in otclient to fetch more o less to othire?
 

Madzix

Member
Joined
Sep 8, 2016
Messages
56
Reaction score
61
Tibianic DLL sources use ICMP to check ping which is different than client-server ping-pong. ICMP will not show you the extra latency caused by cpu usage of client/server but rather the minimal ping you can have to the server.
 
OP
Vantoria

Vantoria

www.ClassicOT.us
Joined
Jun 6, 2014
Messages
110
Reaction score
10
Location
USA
Tibianic DLL sources use ICMP to check ping which is different than client-server ping-pong. ICMP will not show you the extra latency caused by cpu usage of client/server but rather the minimal ping you can have to the server.
well i just wanted to make my client look like more helpful but its alright man thank you right, i Will use my client like it is without the ping system :D
 
OP
Vantoria

Vantoria

www.ClassicOT.us
Joined
Jun 6, 2014
Messages
110
Reaction score
10
Location
USA

Felipe93

Ghost Member
Joined
Mar 21, 2015
Messages
1,203
Reaction score
154
Location
Chile
thanks @ruth i have one personal question how i can pack or compress the otclient? i have been looking in Google any program similar to molebox but i cant add the folder Modules i just can add the libs i really want to compress it like you do with yours i mean if it is posible ofcourse
did u fix the ping issue?
if you did. can u share the fix please?
 

4drik

Active Member
Joined
Jun 30, 2014
Messages
177
Reaction score
122
I have implemented a ping system from TFS to YurOTS today.
It works perfectly.

All you have to do is copy, paste & adapt the code to your engine.
otland/forgottenserver
otland/forgottenserver
And then go to
Code:
OTClient\modules\game_things\things.lua
and in function load() add
Code:
g_game.enableFeature(GameClientPing)
And that's it :)
 
OP
Vantoria

Vantoria

www.ClassicOT.us
Joined
Jun 6, 2014
Messages
110
Reaction score
10
Location
USA
I have implemented a ping system from TFS to YurOTS today.
It works perfectly.

All you have to do is copy, paste & adapt the code to your engine.
otland/forgottenserver
otland/forgottenserver
And then go to
Code:
OTClient\modules\game_things\things.lua
and in function load() add
Code:
g_game.enableFeature(GameClientPing)
And that's it :)
YurOTS its based in tfs? because i did try to add that last week to othire but without successfull and othire is based in OTServ as i know
 

Felipe93

Ghost Member
Joined
Mar 21, 2015
Messages
1,203
Reaction score
154
Location
Chile
YurOTS its based in tfs? because i did try to add that last week to othire but without successfull and othire is based in OTServ as i know
you'll have to edit the code you cant copy paste everything i'll try to add it after i finish to add new creature events to OTH and mods handler folder to OTH src
to be able to use ctf, zombie event etc
[OTHIRE 1.0]With cast system (buggy yet) and others features
cast sys is not bugged solved by olddies but those src aint updated
i'll create a new thread in a near future
 
Last edited:

4drik

Active Member
Joined
Jun 30, 2014
Messages
177
Reaction score
122
YurOTS its based in tfs? because i did try to add that last week to othire but without successfull and othire is based in OTServ as i know
YurOTS is not based on TFS. YurOTS is based on CVS from 2005-12-28. It is the oldest still used engine.
Without modifying the ping code, of course, it would not work, but these changes were small. It's probably even smaller for OTHire.
 
OP
Vantoria

Vantoria

www.ClassicOT.us
Joined
Jun 6, 2014
Messages
110
Reaction score
10
Location
USA
ok thanks to @Olddies who send me the edited files and for now it seems to work, right now the problem is i get disconnected from the game after 1 minute if i dont move i get disconnected if i keep moving myself it dont disconnect me so i think now i'm more closer to it… by the way @Olddies i hope you could help me tomorrow again please :)

 

Olddies

www.tibianas.com
Joined
Nov 21, 2009
Messages
858
Reaction score
157
Location
Rep.Dom
here you go guys the code is working and tested by me i make the tutorial easy for you guys so follow it and you wont have any problems

Player.h around line 900
Code:
    void sendPing();
    void sendPingBack() const {
        if (client) {
            client->sendPingBack();
        }
    }

Protocolgame.h look for this
Code:
void parseReceivePing(NetworkMessage& msg);
and add this below
Code:
    void parseReceivePingBack(NetworkMessage& msg);

Protocolgame.h around line 192
Code:
    void sendPing();
    void sendPingBack();

Game.h around line 505
Code:
    bool playerReceivePing(uint32_t playerId);
    bool playerReceivePingBack(uint32_t playerId);

Protocolgame.cpp around line 516
Code:
        case 0x1D:
            addGameTask(&Game::playerReceivePingBack, player->getID());
            break;

Protocolgame.cpp around line 553
Code:
        case 0x1D: // keep alive / ping response
            parseReceivePingBack(msg);
            break;

Protocolgame.cpp around line 1090
Code:
void ProtocolGame::parseReceivePingBack(NetworkMessage& msg)
{
  addGameTask(&Game::playerReceivePingBack, player->getID());
}

Protocolgame.cpp around line 1905
Code:
void ProtocolGame::sendPing()
{
    NetworkMessage_ptr msg = getOutputBuffer();
    if(msg){
        TRACK_MESSAGE(msg);
        msg->AddByte(0x1E);
    }
}

void ProtocolGame::sendPingBack()
{
    NetworkMessage_ptr msg = getOutputBuffer();
    if(msg){
        TRACK_MESSAGE(msg);
        msg->AddByte(0x1D);
    }
}

Game.cpp around line 2250
Code:
bool Game::playerReceivePing(uint32_t playerId)
{
    Player* player = getPlayerByID(playerId);
    if(!player || player->isRemoved())
        return false;

    player->receivePing();
    return true;
}

bool Game::playerReceivePingBack(uint32_t playerId)
{
    Player* player = getPlayerByID(playerId);
    if(!player || player->isRemoved())
        return false;

    player->sendPingBack();
    return true;
}

Otclient/modules/game_things/things.lua
Code:
g_game.enableFeature(GameClientPing)

Otclient/modules/game_interface/interface.lua
Code:
function onGameStart()
  show()
  g_game.setPingDelay(4000)
end

In case you want the ping system only in the client side only you can edit this files in otclient sources... Thanks to @ruth or Anastacia from github for this code of otclient

add this to Luafunctions.cpp
Code:
g_lua.bindSingletonFunction("g_game", "getNewPing", &Game::getNewPing, &g_game);

in game.cpp after this
Code:
#include <framework/platform/platformwindow.h>
we add this
Code:
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include <stdio.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
int Game::getNewPing(const std::string& ip)
{
    HANDLE hIcmpFile;
    unsigned long ipaddr = inet_addr(ip.c_str());
    DWORD dwRetVal = 0;
    char SendData[32] = "Data Buffer";
    LPVOID ReplyBuffer = NULL;
    DWORD ReplySize = 0;
    // Validate the parameters
    if (ipaddr == INADDR_NONE) {
        return 0;
    }
    hIcmpFile = IcmpCreateFile();
    if (hIcmpFile == INVALID_HANDLE_VALUE) {
        g_logger.info(stdext::format("\tUnable to open handle.\n"));
        g_logger.info(stdext::format("IcmpCreatefile returned error: %ld\n", GetLastError()));
        return 0;
    }
    ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
    ReplyBuffer = (VOID*)malloc(ReplySize);
    if (ReplyBuffer == NULL) {
        g_logger.info(stdext::format("\tUnable to allocate memory\n"));
        return 0;
    }
    dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData),
        NULL, ReplyBuffer, ReplySize, 5000);
    if (dwRetVal != 0) {
        PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
        struct in_addr ReplyAddr;
        ReplyAddr.S_un.S_addr = pEchoReply->Address;
        return pEchoReply->RoundTripTime;
    }
    else {
        g_logger.info(stdext::format("\tCall to IcmpSendEcho failed.\n"));
        g_logger.info(stdext::format("\tIcmpSendEcho returned error: %ld\n", GetLastError()));
        return 0;
    }
    return 0;
}

in game.h we should add this somewhere before Protected
Code:
int getNewPing(const std::string& ip);


Otclient/modules/game_things/things.lua
Code:
print(g_game.getNewPing("YOUR_NUMERIC_IP"))

Otclient/modules/game_interface/interface.lua
Code:
function onGameStart()
  show()
  g_game.setPingDelay(4000)
end
 
Last edited:
OP
Vantoria

Vantoria

www.ClassicOT.us
Joined
Jun 6, 2014
Messages
110
Reaction score
10
Location
USA
here you go guys the code is working and tested by me i make the tutorial easy for you guys so follow it and you wont have any problems

Player.h around line 900
Code:
    void sendPing();
    void sendPingBack() const {
        if (client) {
            client->sendPingBack();
        }
    }

Player.h add or replace around line 985
Code:
    void receivePing() {
        lastPong = OTSYS_TIME();
    }

Player.h around line 1108
Code:
    int64_t lastPing;
    int64_t lastPong;

Protocolgame.h look for this
Code:
void parseReceivePing(NetworkMessage& msg);
and add this below
Code:
    void parseReceivePingBack(NetworkMessage& msg);

Protocolgame.h around line 192
Code:
    void sendPing();
    void sendPingBack();

Game.h around line 505
Code:
    bool playerReceivePing(uint32_t playerId);
    bool playerReceivePingBack(uint32_t playerId);

Protocolgame.cpp around line 516
Code:
        case 0x1D:
            addGameTask(&Game::playerReceivePingBack, player->getID());
            break;

Protocolgame.cpp around line 553
Code:
        case 0x1D: // keep alive / ping response
            parseReceivePingBack(msg);
            break;

Protocolgame.cpp around line 1090
Code:
void ProtocolGame::parseReceivePingBack(NetworkMessage& msg)
{ 
  addGameTask(&Game::playerReceivePingBack, player->getID());
}

Protocolgame.cpp around line 1905
Code:
void ProtocolGame::sendPing()
{
    NetworkMessage_ptr msg = getOutputBuffer();
    if(msg){
        TRACK_MESSAGE(msg);
        msg->AddByte(0x1E);
    }
}

void ProtocolGame::sendPingBack()
{
    NetworkMessage_ptr msg = getOutputBuffer();
    if(msg){
        TRACK_MESSAGE(msg);
        msg->AddByte(0x1D);
    }
}

Game.cpp around line 2250
Code:
bool Game::playerReceivePing(uint32_t playerId)
{
    Player* player = getPlayerByID(playerId);
    if(!player || player->isRemoved())
        return false;

    player->receivePing();
    return true;
}

bool Game::playerReceivePingBack(uint32_t playerId)
{
    Player* player = getPlayerByID(playerId);
    if(!player || player->isRemoved())
        return false;

    player->sendPingBack();
    return true;
}

Player.cpp look for this and remove it
Code:
    lastping = OTSYS_TIME();
    lastpong = OTSYS_TIME();

Player.cpp add after this
Code:
Player::Player(const std::string& _name, ProtocolGame* p) :
add this
Code:
Creature(), lastPing(OTSYS_TIME()), lastPong(lastPing)


Player.cpp after this
Code:
void Player::sendStats()
{
    if(client){
        client->sendStats();
    }
}
add this
Code:
void Player::sendPing()
{
    int64_t timeNow = OTSYS_TIME();

    bool hasLostConnection = false;
    if ((timeNow - lastPing) >= 5000){
        lastPing = timeNow;
        if (client) {
            client->sendPing();
        } else {
            hasLostConnection = true;
        }
    }

    int64_t noPongTime = timeNow - lastPong;
    if ((hasLostConnection || noPongTime >= 7000) && attackedCreature && attackedCreature->getPlayer()) {
        setAttackedCreature(nullptr);
    }

    if (noPongTime >= 60000) {
        if(canLogout()){
            if (client) {
                client->logout(true);
            } else {
                g_game.removeCreature(this, true);
            }
        }
    }
}

Otclient/modules/game_things/things.lua
Code:
g_game.enableFeature(GameClientPing)

if you have any issue with it post here i will try to help when i can
:D :D thank you so much @Olddies :O i dont see the best answer option i wish give it to you :)
 
Top