Home 50 Report post Posted September 16, 2016 (edited) Hi Friends... I made this Anti Dupe method, for teleporting ways, let me explain how it works... EXPLANATION PLAYER teleports from Argent City(GS0) to Shaitan City ( GS1) ... TELEPORTER gives him a GS1 "token"... IF Player arrives to destination GS1 Token is deleted by destination map ELSE if PLAYER tries to DUPE closing the game before teleporting,then when the player enter the map again the source map will check for the GS1 Token if it's there PLAYER will be automaticaly teleported to DESTINATION MAP, no having time to trade the itens or even droping It worked here on my tests... DEMO Resource with this method - ( ONLY BETWEEN Argent Teleporter and Shaitan Teleporter ) -- http://www.mediafire.com/download/p1u26j4a7vtdvo7/resource(2).rar The modifications are in GoToWhere function garner.ctrl magicsea.ctrl variables ... I'll finish it after i take a bath Edited September 16, 2016 by Home 1 Quote Share this post Link to post Share on other sites
MonkeyCode 453 Report post Posted September 16, 2016 This is harder than it should be. And a much better way when dealt with src. If not, use lua. Took almost 1 hour to find this old thing. Spoiler C_dupe = {} C_dupe.root = 'C:/PKO1.38/GameServer/' C_dupe.path = GetResPath('script/extension/antidupe/') C_dupe.hook = { tick = cha_timer } C_dupe.file = 'Gameserver.dat' C_dupe.db = 'PlayerGS.dat' file_exists = file_exists or function(name) local f = io.open(name, 'r') if(f ~= nil)then io.close(f) return true else return false end end split = split or function(str, delim, maxNb) if string.find(str, delim) == nil then return { str } end if maxNb == nil or maxNb < 1 then maxNb = 0 end local result = {} local pat = "(.-)" .. delim .. "()" local nb = 0 local lastPos for part, pos in string.gfind(str, pat) do nb = nb + 1 result[nb] = part lastPos = pos if nb == maxNb then break end end if nb ~= maxNb then result[nb + 1] = string.sub(str, lastPos) end return result end FileToArray = FileToArray or function(file) local f = io.open(file, "r") local arr = {} for line in f:lines() do table.insert(arr, line) end return arr end function GetChaKeyID(c) local hex,name = '', GetChaDefaultName(c) while string.len(name) > 0 do local hb = string.format("%X", string.byte(name, 1, 1)) if string.len(hb) < 2 then hb = '0' .. hb end hex = hex .. hb name = string.sub(name, 2) end return hex end function C_dupe:GetChaKey(c) local n = GetChaKeyID(c); return n end function C_dupe:SortGS(j) local fp = assert(io.open(C_dupe.root..'Gameserver'..tostring(j)..'.cfg')) for line in fp:lines() do local p = string.find(line, 'map = ') if p == 1 then local d = split(line, 'map = ') if file_exists(C_dupe.path..C_dupe.file) == false then local f = io.open(C_dupe.path..C_dupe.file, 'a') table.save({},C_dupe.path..C_dupe.file, 'w') f:close() end local t = table.load(C_dupe.path..C_dupe.file, 'r') local rd = d[2] local q = string.find(d[2], ' ') if q ~= nil then q = q - 1 rd = string.sub(d[2], 1, q) end if j == '' then j = 0 end if t[rd] == nil then t[rd] = j end table.save(t,C_dupe.path..C_dupe.file, 'w') end end end function C_dupe:StoreGS(n) for i = 0, n do local a = i if a == 0 then a = ''; end if file_exists(C_dupe.root..'Gameserver'..tostring(a)..'.cfg') == true then C_dupe:SortGS(a) end end end if file_exists(C_dupe.path..C_dupe.file) == true then os.remove(C_dupe.path..C_dupe.file) end C_dupe:StoreGS(5); function C_dupe:LG(f, text) local file = C_dupe.path..f..'.txt' if file_exists(file) == false then local c = io.open(file, 'a') c:close() end local lf = io.open(file, 'a') lf:write('['..os.date()..']\t'..text..'\n') lf:close() end function C_dupe.Kick(c) local pkt = GetPacket() WriteCmd(pkt,1505) SendPacket(c,pkt) end function C_dupe:GetChaGS(c) local t = table.load(C_dupe.path..C_dupe.file, 'r') return t[GetChaMapName(c)] end function C_dupe:GetChaCount() local t = table.load(C_dupe.path..C_dupe.db, 'r') local a = 0; for i,v in pairs(t) do a = a + 1; end return a end function C_dupe.Enter(i, c, m) if file_exists(C_dupe.path..C_dupe.db) == false then local f = io.open(C_dupe.path..C_dupe.db, 'a') table.save({},C_dupe.path..C_dupe.db, 'w') f:close() end local t = table.load(C_dupe.path..C_dupe.db, 'r') if t[GetChaKeyID(c)] ~= nil then C_dupe:LG('log', 'Player ['..GetChaDefaultName(c)..'] found in Gameserver'..t[GetChaKeyID(c)]..' (Entered map: '..GetChaMapName(c)..')') return -- C_dupe:Kick(c) end t[GetChaKeyID(c)] = C_dupe:GetChaGS(c) table.save(t, C_dupe.path..C_dupe.db, 'w') end function C_dupe.Leave(i, c) local t = table.load(C_dupe.path..C_dupe.db, 'r') t[GetChaKeyID(c)] = nil table.save(t, C_dupe.path..C_dupe.db, 'w') end cha_timer = function(r, f, t) C_dupe.hook['tick'](r, f, t) if IsPlayer(r) == 1 then local j = 'Player' if ChaIsBoat(r) == 1 then j = 'Boat' r = TurnToShip(r) end if file_exists(C_dupe.path..C_dupe.db) ~= false and file_exists(C_dupe.path..C_dupe.file) ~= false then local t = table.load(C_dupe.path..C_dupe.db, 'r') local gs = table.load(C_dupe.path..C_dupe.file, 'r') if t[GetChaKeyID(TurnToCha(r))] == nil then C_dupe:Kick(r) else if t[GetChaKeyID(TurnToCha(r))] ~= gs[GetChaMapName(TurnToCha(r))] then C_dupe:LG('log', ''..j..' ['..GetChaDefaultName(TurnToCha(cha))..'] found in 2 different Gameservers. (Gameserver'..t[GetChaKeyID(TurnToCha(r))]..' and Gameserver'..gs[GetChaMapName(TurnToCha(r))]..').') C_dupe:Kick(r) end end end end end function C_dupe:Initialize() Hook:SetHookPattern("^after_enter_.*$", "POST", C_dupe.Enter, 2) Hook:SetHookPattern("^before_leave_.*$", "POST", C_dupe.Leave, 2) end function C_dupe:SetHook() local gs = table.load(C_dupe.path..C_dupe.file, 'r') for i,v in pairs(gs) do if _G["after_enter_"..i] == nil then _G["after_enter_"..i] = function(role, map_copy) end end if _G["before_leave_"..i] == nil then _G["before_leave_"..i] = function(role) end end end C_dupe:Initialize() end function C_dupe:AddHook(func) local file = GetResPath('/script/help/AddHelpNPC.lua') local index = FileToArray(file) local r = 0 for i = 1, table.getn(index) do if index[i] ~= tostring(func) then r = r + 1; end end if r == table.getn(index) then local lf = io.open(file,'a') lf:write("\n") lf:write(tostring(func)) lf:close() end end C_dupe:AddHook('C_dupe:SetHook()') C_dupe:Initialize() I think this script does the following... > serialize maps and their respective gameserver by reading cfg files > when player enters any map, serialize their map > we can then retrieve their Gameserver by knowing their map > If the player's map is not located in the GameServer they are supposely in, this is consider a clone. This is the only way i can think of when dealing with lua but it was a very long ago. I also remember that there is a logic error in cha_timer. 1 Quote Share this post Link to post Share on other sites
Billy 164 Report post Posted September 16, 2016 A way to easily tell which GS you are on is too rename the system NPC in the .cfg off each GS to be differance (System1, System2 etc), then use local ret, npc = GetEudemon() local GSName = GetChaDefaultName(npc) to get the GS. With your ( @Home ) method, you will have issues with players with a full inv, I had started trying to record a players inv/bank/temp/equips into a file when they leave a map, and then checking this against their current inv/bank/temp/equips when they enter a map, but idk if that would fully work due to order of disconnecting if they enter the same map as their clone. (and web based malls would need to be replaced with IGS) 2 Quote Share this post Link to post Share on other sites
xSeth 51 Report post Posted September 18, 2016 teleporting ... keep trying for bank/mazes/blueprints/etc and btw my method of teleports will broke ur " anti dupe " 1 Quote Share this post Link to post Share on other sites
Home 50 Report post Posted September 18, 2016 xSeth , can you explain how it works? Quote Share this post Link to post Share on other sites
xSeth 51 Report post Posted September 18, 2016 i explained already all my dupes on another thread " Item Dupe " check it ther 2 Quote Share this post Link to post Share on other sites
Home 50 Report post Posted September 18, 2016 tahnks, found it Quote Share this post Link to post Share on other sites
Home 50 Report post Posted September 18, 2016 (edited) @Billy @KONG @V3ct0r @Totoka @xSeth @Treuno86 How can i delete an character instance using lua? Edited September 18, 2016 by Home Quote Share this post Link to post Share on other sites
Totoka 152 Report post Posted September 19, 2016 (edited) 9 hours ago, Home said: @Billy @KONG @V3ct0r @Totoka @xSeth @Treuno86 How can i delete an character instance using lua? Im not sure if you are able to do such stuff from lua. I think an extension could be useful here. (kop 2.4)------------------------------------------------------------------- do some lua handler // some prototypes and stuff to do pointers frowarding struct T { template<typename TMember> static TMember F(unsigned int Ptr) { void *Address = reinterpret_cast<void*>(Ptr); return reinterpret_cast<TMember&>(Address); } }; class CCharacter { public: void *GetPlayer()// a forward to 0x41bb50 which is the function pointer of GetPlayer() { typedef void*(CCharacter::*m)(void); // be careful, didnt check if this is a pointer to a context, or pointer to pointer. must be debuged. return (this->*(T::F<m>(0x0041BB50)))(); } }; class GameServerApp { public: bool DelPlayer(void *player) // another forward. { typedef bool(GameServerApp::*m)(void*); return (this->*(T::F<m>(pDelPlayer)))(player); } }; then register your new lua function would be something like: ////////////////////////////////////////////////////// // LUA POINTER/FUNCTIONS UTIL #define lua_vm (void*)0x006F6768 #define lua_pushstring(S)\ ((void(*)(void *, const char *))0x0062D320)(lua_vm, S) #define lua_pushcclosure(F)\ ((void(*)(void *, void *, int N))0x0062D3F0)(lua_vm, F, 0) #define lua_pushcclosure(F)\ ((void(*)(void *, void *, int N))0x0062D3F0)(lua_vm,F,0) #define lua_settable()\ ((void(*)(void *, int))0x0062D6B0)(lua_vm,0xFFFFD8EF) #define lua_touserdata(L,N)\ ((void*(*)(void*,int))0x0062D1C0)(L,N) int lua_delplayer(void* L) { CCharacter *c = (CCharacter*)lua_touserdata(L, 1); GameServerApp *s = GameServerApp::I(); s->DelPlayer(c->GetPlayer()); return 0; } ////////////////////////////////////////////////////// // Then finally, the one you should hook // in order to get it working. // (it should be after the lua vm has been initialized) extern "C" __declspec(dllexport) void __stdcall lua_extension() { lua_pushstring("delrole"); lua_pushcclosure(lua_delplayer); lua_settable(); } i dont test it, don't have time. hope that helps. Edit: -------------------------------------------------------------- after that whole stuff, call it from lua whenever you want. delrole(role); Edited September 19, 2016 by Totoka code cleaning, macro redefinition, wrong returned type 1 Quote Discord: andresc Share this post Link to post Share on other sites
xSeth 51 Report post Posted September 19, 2016 16 hours ago, Home said: @Billy @KONG @V3ct0r @Totoka @xSeth @Treuno86 How can i delete an character instance using lua? idk man i'm not good at scripting Quote Share this post Link to post Share on other sites
R95 0 Report post Posted October 29, 2020 also im looking for anti dupe Quote Share this post Link to post Share on other sites