#Introdução
Bom hoje estarei trazendo aqui o sistema de Ping feito pelo Mock, com uma pequena adaptação feita por mim para funcionar em TFS 0.4(talvez podendo funcionar em outras)
Pois o que ele disponibilizou foi apenas para TFS 0.3.6 e nem foi muito utilizado pela comunidade. Muitos servidores daqui para download tem script no talk mas a lib está totalmente errada e não tem o code nas sources.
Esse sistema tem varias utilizades, podendo usar o comando !ping para verificar seu ms ou até mesmo você por para kikar jogadores com ms muito alto...
Se você não sabe o cliente já tem um sistema de ping, e getOtsystime é como os.time () + os.clock (), você tem ano, mês, dia, hora, minutos, segundos, milisegundos...
Enfim chega de enrolação e vamos lá!
Code para TFS 0.4 e OTX:
Em luascript.cpp procure por:
lua_register(m_luaState, "doSetMonsterOutfit"
de baixo dessa função adicione:
//doPlayerSendPing(cid) lua_register(m_luaState, "doPlayerSendPing", LuaInterface::luaDoPlayerSendPing); //getPlayerLastPing(cid) lua_register(m_luaState, "getPlayerLastPing", LuaInterface::luaGetPlayerLastPing); //getPlayerLastPong(cid) lua_register(m_luaState, "getPlayerLastPong", LuaInterface::luaGetPlayerLastPong); //getOtsysTime(cid) lua_register(m_luaState, "getOtsysTime", LuaInterface::luaGetOtsysTime);
Ainda em luascript.cpp, lá no final adicione:
int32_t LuaInterface::luaDoPlayerSendPing(lua_State* L) // Adaptado by Yan Liima(Night for xtibia.com) { //doPlayerSendPing(cid) ScriptEnviroment* env = getEnv(); Player* player = env->getPlayerByUID(popNumber(L)); if(!player) { lua_pushboolean(L, false); return 1; } int64_t timeNow = OTSYS_TIME(); player->lastPing = timeNow; if(player->client) { void sendPing(); lua_pushboolean(L, true); }else{ lua_pushboolean(L, false); } lua_pushboolean(L, true); return 1; } int32_t LuaInterface::luaGetOtsysTime(lua_State* L) { //getOtsysTime() lua_pushnumber(L, OTSYS_TIME()); return 1; } int32_t LuaInterface::luaGetPlayerLastPing(lua_State* L) { //getPlayerLastPing(cid) ScriptEnviroment* env = getEnv(); Player* player = env->getPlayerByUID(popNumber(L)); if(!player) { errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushboolean(L, false); return 1; } lua_pushnumber(L, player->lastPing); return 1; } int32_t LuaInterface::luaGetPlayerLastPong(lua_State* L) { //getPlayerLastPong(cid) ScriptEnviroment* env = getEnv(); Player* player = env->getPlayerByUID(popNumber(L)); if(!player) { errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushboolean(L, false); return 1; } lua_pushnumber(L, player->lastPong); return 1; }
Em luascript.h procure por:
//lua functions
E em cima disso adicione:
//Ping static int32_t luaDoPlayerSendPing(lua_State* L); static int32_t luaGetPlayerLastPing(lua_State* L); static int32_t luaGetPlayerLastPong(lua_State* L); static int32_t luaGetOtsysTime(lua_State* L);
Code para TFS 0.3.6
Em luascript.cpp procure por:
lua_register(m_luaState, "doSetMonsterOutfit"
de baixo dessa função adicione:
//doPlayerSendPing(cid) lua_register(m_luaState, "doPlayerSendPing", LuaScriptInterface::luadoPlayerSendPing); //getPlayerLastPing(cid) lua_register(m_luaState, "getPlayerLastPing", LuaScriptInterface::luagetPlayerLastPing); //getPlayerLastPong(cid) lua_register(m_luaState, "getPlayerLastPong", LuaScriptInterface::luagetPlayerLastPong); //getOtsysTime(cid) lua_register(m_luaState, "getOtsysTime", LuaScriptInterface::luagetOtsysTime);
Ainda em luascript.cpp, lá no final adicione:
int32_t LuaScriptInterface::luadoPlayerSendPing(lua_State* L) { //doPlayerSendPing(cid) ScriptEnviroment* env = getEnv(); Player* player = env->getPlayerByUID(popNumber(L)); if(!player) { lua_pushboolean(L, false); return 1; } int64_t timeNow = OTSYS_TIME(); player->lastPing = timeNow; if(player->client) { player->client->sendPing(); lua_pushboolean(L, true); }else{ lua_pushboolean(L, false); } lua_pushboolean(L, true); return 1; } int32_t LuaScriptInterface::luagetOtsysTime(lua_State* L) { //getOtsysTime() lua_pushnumber(L, OTSYS_TIME()); return 1; } int32_t LuaScriptInterface::luagetPlayerLastPing(lua_State* L) { //getPlayerLastPing(cid) ScriptEnviroment* env = getEnv(); Player* player = env->getPlayerByUID(popNumber(L)); if(!player) { errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushboolean(L, false); return 1; } lua_pushnumber(L, player->lastPing); return 1; } int32_t LuaScriptInterface::luagetPlayerLastPong(lua_State* L) { //getPlayerLastPong(cid) ScriptEnviroment* env = getEnv(); Player* player = env->getPlayerByUID(popNumber(L)); if(!player) { errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushboolean(L, false); return 1; } lua_pushnumber(L, player->lastPong); return 1; }
Em luascript.h procure por:
//lua functions
E em cima disso adicione:
static int32_t luadoPlayerSendPing(lua_State* L); static int32_t luagetPlayerLastPing(lua_State* L); static int32_t luagetPlayerLastPong(lua_State* L); static int32_t luagetOtsysTime(lua_State* L);
LIB:
Na pasta lib do teu servidor em 050-functions.lua adicione:
function getPlayerPing(cid) -- getPlayerPing By mock local c = getPlayerLastPong(cid) local l = getPlayerLastPing(cid) if not c or not l then return 'Disconected' end local ping = math.floor((c-l)/10) if ping < 0 then if ping*-1 > 2000 then return 'Disconected' end return 'Wating response' end return ping end
Para ficar totalmente completo, crie uma arquivo na pasta lib chamado 123-pinglib.lua
---Pinglib by mock the bear ping = { _VERSION = "1.0"; _AUTHOR = "Mock the bear"; test = function() if not getPlayerLastPong then print('Error! Cannot run this lib without source changes.') return false else return true end end, CONST_WATING_RESPONSE = -3, CONST_DISCONECTED = -2, } function ping.CheckPing(cid) -- getPlayerPing By mock local c = getPlayerLastPong(cid) local l = getPlayerLastPing(cid) if not c or not l then return -2 end local ping = math.floor((c-l)/10) if ping < 0 then if ping*-1 > 2000 then return -2 end return -3 end return ping end function ping.loop(cid,storage,f,...) -- check if not isPlayer(cid) then return false end local p_ing = ping.CheckPing(cid) if p_ing ~= CONST_WATING_RESPONSE then if not tonumber(p_ing) then doPlayerSetStorageValue(cid,storage,ping.CONST_DISCONECTED) return else doPlayerSetStorageValue(cid,storage,p_ing) f(cid,storage,p_ing,...) return end end addEvent(ping.loop,100,cid,storage,f,...) end function ping.getPing(cid,storage,f,...) --- This function will send a ping request and wait the response, so then will add an value on a storage. if ping.test() then doPlayerSetStorageValue(cid,storage,ping.CONST_WATING_RESPONSE) doPlayerSendPing(cid) ping.loop(cid,storage,f,...) end end
Prontinho, agora seu servidor está pronto para utilizar as funções de Ping. Seja criativo!
Ahh você é daqueles que quer tudo na mão né? Aqui vai um talkactions para ver o ping.
Em talkactions/scripts crie um arquivo chamado playerping.lua, cole isto dentro:
-- Script by Yan Liima(Night for xtibia.com) function onSay(cid, words, param, channel) local ms = ping.CheckPing(cid) doPlayerSendTextMessage(cid,22,"Ping aproximado --> ["..ms.."].") return true end
Em talkactions.xml
<talkaction words="!ping" event="script" value="playerping.lua"/>