LucasFerraz
Systems Analyst
Hello guys,
I would like to announce that I am working on a system of anti duplication.
Why do I have to work with him if there are any free forum?
I'm trying to do something with highest performance.
How?
Using Trigger and/or Procedure.
As most of you know, I'm not good with advanced things but I'm studying to conclude this project successfully.
I suggest you to join this project and contribute to our community.
I will use Darkhaos' Anti-Dupe as base.
function generateSerial() made by Darkhaos (This function should be rewritten select * sucks.)
This is function onStartup(GlobalEvent) made by Darkhaos and improved by BeniS.
The problem is: The code is bringing all pages of MySQL. This is not the best solution because it will f**k up the network.
The Solution: The correct way to do the procedure is to perform everything in MySQL. Doing this way the network will not be compromised and the connection will be stable/fine/ok.
Tips: The procedure should be as specific as possible to have better performance. A good idea would be to use as the filter itemtypes (pre-defined), so only the items 'vip' would be sought and only the items 'vip' with serial duplicate would be deleted.
The disadvantages of using this filter would be for items not 'vip' duplicate would not be deleted.
In a second stage a second 'scan' could fetch all the duplicate items that are not declared previously (vip items).
As you can see, so far I have all the theory, the practice is missing, if you know how to help, I'm counting on you
and then:
Also, here is a re-improved onStartUp()
I would like to announce that I am working on a system of anti duplication.
Why do I have to work with him if there are any free forum?
I'm trying to do something with highest performance.
How?
Using Trigger and/or Procedure.
As most of you know, I'm not good with advanced things but I'm studying to conclude this project successfully.
I suggest you to join this project and contribute to our community.
I will use Darkhaos' Anti-Dupe as base.
- - - Known Anti-Dupe System - - -
function generateSerial() made by Darkhaos (This function should be rewritten select * sucks.)
LUA:
function generateSerial()
local strings = "AaBbCcDdEeFfGgHhIiJjKkLlMmOoPpQqRrSsTtUuVvWwXxYyZz"
local newSerialStr, newSerialInt = "", 0
local newSerial = ""
local query, query2, query3
repeat
for k = 1, math.random(1, 10) do
local l = math.random(1, string.len(strings))
newSerialStr = newSerialStr .. string.sub(strings, l, l)
end
newSerialInt = math.random(999999)
newSerial = newSerialStr .. "-" .. newSerialInt
query = db.getResult("select * from player_items where substring(convert(attributes using latin1) from 18) = " .. db.escapeString(newSerial))
query2 = db.getResult("select * from player_depotitems where substring(convert(attributes using latin1) from 18) = " .. db.escapeString(newSerial))
query3 = db.getResult("select * from tile_items where substring(convert(attributes using latin1) from 18) = " .. db.escapeString(newSerial))
until query:getID() == -1 and query2:getID() == -1 and query3:getID() == -1
return "!" .. newSerial
end
LUA:
doItemSetAttribute(uid, "serial", generateSerial())
This is function onStartup(GlobalEvent) made by Darkhaos and improved by BeniS.
LUA:
function onStartup()
tablesToCheck = {"player_items", "player_depotitems", "tile_items", {"player_items", {"player_depotitems", "tile_items"}}, {"player_depotitems", "tile_items"}}
local text, final = "", ""
local filex = "data/logs/duplicated.txt"
local f = io.open(filex, "a+")
local delete, delete2, query, query_ = nil, nil, nil, nil
local count, tmpCount = 0, 0
for i = 1, table.maxn(tablesToCheck) do
if type(tablesToCheck[i]) == "string" then
query = db.getResult("SELECT *, SUBSTRING(CONVERT(attributes USING latin1) FROM 18) AS 'track' FROM " .. tablesToCheck[i] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) IN (SELECT SUBSTRING(CONVERT(attributes USING latin1) FROM 18) FROM " .. tablesToCheck[i] .. " WHERE CONVERT(attributes USING latin1) LIKE '%serial%' GROUP BY SUBSTRING(CONVERT(attributes USING latin1) FROM 18) HAVING COUNT(*) > 1)")
if query:getID() ~= -1 then
tmpCount = query:getRows()
while(true) do
delete = db.executeQuery("DELETE FROM " .. tablesToCheck[i] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) = " .. db.escapeString(query:getDataString("track")) .. " LIMIT 1;")
count = (delete and count + 1 or count)
text = "[!] -> Deleting items with duplicated serial from '" .. tablesToCheck[i] .. "': [Player: " .. getPlayerNameByGUID(query:getDataInt("player_id")) .. ", Item: " .. query:getDataInt("itemtype") .. ", Count: " .. query:getDataInt("count") .. ", Serial: " .. query:getDataString("track") .."]... " .. (delete and "Success!" or "Failed!")
final = final .. (final ~= "" and "\n" or "") .. text
tmpCount = tmpCount - 1
if (not query:next() or tmpCount <= 1) then break end
end
query:free()
end
else
if type(tablesToCheck[i][2]) == "string" then
query = db.getResult("SELECT *, SUBSTRING(CONVERT(attributes USING latin1) FROM 18) AS 'track' FROM " .. tablesToCheck[i][1] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) IN (SELECT SUBSTRING(CONVERT(attributes USING latin1) FROM 18) FROM " .. tablesToCheck[i][2] .. " WHERE CONVERT(attributes USING latin1) LIKE '%serial%' GROUP BY SUBSTRING(CONVERT(attributes USING latin1) FROM 18) HAVING COUNT(*) > 0)")
if query:getID() ~= -1 then
tmpCount = query:getRows()
while(true) do
query_ = db.getResult("SELECT *, SUBSTRING(CONVERT(attributes USING latin1) FROM 18) AS 'track' FROM " .. tablesToCheck[i][2] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) IN (SELECT SUBSTRING(CONVERT(attributes USING latin1) FROM 18) FROM " .. tablesToCheck[i][1] .. " WHERE CONVERT(attributes USING latin1) LIKE '%serial%' GROUP BY SUBSTRING(CONVERT(attributes USING latin1) FROM 18) HAVING COUNT(*) > 0)")
delete = db.executeQuery("DELETE FROM" .. tablesToCheck[i][1] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) = " .. db.escapeString(query:getDataString("track")) .. " LIMIT 1;")
count = (delete and count + 1 or count)
delete2 = db.executeQuery("DELETE FROM " .. tablesToCheck[i][2] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) = " .. db.escapeString(query:getDataString("track")) .. " LIMIT 1;")
count = (delete2 and count + 1 or count)
text = "[!] -> Deleting item with duplicated serial from '" .. tablesToCheck[i][1] .. "' [Player: " .. getPlayerNameByGUID(query:getDataInt("player_id")) .. ", Item: " .. query:getDataInt("itemtype") .. ", Count: " .. query:getDataInt("count") .. ", Serial: " .. query:getDataString("track") .."]... " .. (delete and "Success!" or "Failed!") ..
"\n[!] -> Deleting item with duplicated serial from '" .. tablesToCheck[i][2] .. "' [Player: " .. getPlayerNameByGUID(query_:getDataInt("player_id")) .. ", Item: " .. query_:getDataInt("itemtype") .. ", Count: " .. query_:getDataInt("count") .. ", Serial: " .. query_:getDataString("track") .."]... " .. (delete and "Success!" or "Failed!")
final = final .. (final ~= "" and "\n" or "") .. text
tmpCount = tmpCount - 1
if (query_:getID() ~= -1) then query_:free() end
if (not query:next() or tmpCount <= 1) then break end
end
query:free()
end
else
for j = 1, #tablesToCheck[i][2] do
query = db.getResult("SELECT *, SUBSTRING(CONVERT(attributes USING latin1) FROM 18) AS 'track' FROM " .. tablesToCheck[i][1] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) IN (SELECT SUBSTRING(CONVERT(attributes USING latin1) FROM 18) FROM " .. tablesToCheck[i][2][j] .. " WHERE CONVERT(attributes USING latin1) LIKE '%serial%' GROUP BY SUBSTRING(CONVERT(attributes USING latin1) FROM 18) HAVING COUNT(*) > 0)")
if query:getID() ~= -1 then
tmpCount = query:getRows()
while(true) do
query_ = db.getResult("SELECT *, SUBSTRING(CONVERT(attributes USING latin1) FROM 18) AS 'track' FROM " .. tablesToCheck[i][2][j] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) IN (SELECT SUBSTRING(CONVERT(attributes USING latin1) FROM 18) FROM " .. tablesToCheck[i][1] .. " WHERE CONVERT(attributes USING latin1) LIKE '%serial%' GROUP BY SUBSTRING(CONVERT(attributes USING latin1) FROM 18) HAVING COUNT(*) > 0)")
delete = db.executeQuery("DELETE FROM " .. tablesToCheck[i][1] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) = " .. db.escapeString(query:getDataString("track")) .. " LIMIT 1;")
count = (delete and count + 1 or count)
delete2 = db.executeQuery("DELETE FROM " .. tablesToCheck[i][2][j] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) = " .. db.escapeString(query:getDataString("track")) .. " LIMIT 1;")
count = (delete2 and count + 1 or count)
text = "[!] -> Deleting item with duplicated serial from '" .. tablesToCheck[i][1] .. "' [Player: " .. getPlayerNameByGUID(query:getDataInt("player_id")) .. ", Item: " .. query:getDataInt("itemtype") .. ", Count: " .. query:getDataInt("count") .. ", Serial: " .. query:getDataString("track") .."]... " .. (delete and "Success!" or "Failed!") ..
"\n[!] -> Deleting item with duplicated serial from '" .. tablesToCheck[i][2][j] .. "' [Player: " .. getPlayerNameByGUID(query_:getDataInt("player_id")) .. ", Item: " .. query_:getDataInt("itemtype") .. ", Count: " .. query_:getDataInt("count") .. ", Serial: " .. query_:getDataString("track") .."]... " .. (delete and "Success!" or "Failed!")
final = final .. (final ~= "" and "\n" or "") .. text
tmpCount = tmpCount - 1
if (query_:getID() ~= -1) then query_:free() end
if (not query:next() or tmpCount <= 1) then break end
end
query:free()
end
end
end
end
end
if f ~= nil then
print("["..os.date("%X", os.time())..".TMI] >> Item Tracker: " .. count .. " duplicated items have been deleted...")
f:write("[" .. os.date("%d %B %Y %X ", os.time()) .. "] >> [Item Tracker] " .. count .. " duplicated items have been deleted from the database.\n" .. (final == "" and "[!] -> No duplicated item was found in the database" or final) .. "\n\n")
f:close()
else
print("[["..os.date("%X", os.time())..".TMI] >> [Item Tracker] Cannot save info to file!")
end
return true
end
The problem is: The code is bringing all pages of MySQL. This is not the best solution because it will f**k up the network.
The Solution: The correct way to do the procedure is to perform everything in MySQL. Doing this way the network will not be compromised and the connection will be stable/fine/ok.
Tips: The procedure should be as specific as possible to have better performance. A good idea would be to use as the filter itemtypes (pre-defined), so only the items 'vip' would be sought and only the items 'vip' with serial duplicate would be deleted.
The disadvantages of using this filter would be for items not 'vip' duplicate would not be deleted.
In a second stage a second 'scan' could fetch all the duplicate items that are not declared previously (vip items).
As you can see, so far I have all the theory, the practice is missing, if you know how to help, I'm counting on you

- - - New Anti-Dupe System - - -
LUA:
--Removed SELECT * because it sucks
--Added filter in select, ADD YOUR ITEM ID (VIP ITENS) THERE. (Search for itemtype = 2160 or itemtype = 2159)
function generateSerial()
local strings = "AaBbCcDdEeFfGgHhIiJjKkLlMmOoPpQqRrSsTtUuVvWwXxYyZz"
local newSerialStr, newSerialInt = "", 0
local newSerial = ""
local query, query2, query3
repeat
for k = 1, math.random(1, 10) do
local l = math.random(1, string.len(strings))
newSerialStr = newSerialStr .. string.sub(strings, l, l)
end
newSerialInt = math.random(999999)
newSerial = newSerialStr .. "-" .. newSerialInt
query = db.getResult("select attributes from player_items where substring(convert(attributes using latin1) from 18) = " .. db.escapeString(newSerial) .. " and itemtype = 2160 or itemtype = 2159")
query2 = db.getResult("select attributes from player_depotitems where substring(convert(attributes using latin1) from 18) = " .. db.escapeString(newSerial) .. " and itemtype = 2160 or itemtype = 2159")
query3 = db.getResult("select attributes from tile_items where substring(convert(attributes using latin1) from 18) = " .. db.escapeString(newSerial) .. " and itemtype = 2160 or itemtype = 2159")
until query:getID() == -1 and query2:getID() == -1 and query3:getID() == -1
return "!" .. newSerial
end
LUA:
doItemSetAttribute(uid, "serial", generateSerial())
SQL:
DELIMITER $$
DROP PROCEDURE IF EXISTS `anti_dupe` $$
CREATE PROCEDURE `anti_dupe`(IN _id INT)
BEGIN
-- All procedure here --
-- Until now, I don't know how to do that but I'm studying to --
END $$
DELIMITER ;
and then:
LUA:
function onStartup()
db.executeQuery("CALL anti_dupe ();")
return true
end
Also, here is a re-improved onStartUp()
LUA:
-- Removed SELECT *
--Added filter in select, ADD YOUR ITEM ID (VIP ITENS) THERE. (Search for itemtype = 2160 or itemtype = 2159)
function onStartup()
tablesToCheck = {"player_items", "player_depotitems", "tile_items", {"player_items", {"player_depotitems", "tile_items"}}, {"player_depotitems", "tile_items"}}
local text, final = "", ""
local filex = "data/logs/duplicated.txt"
local f = io.open(filex, "a+")
local delete, delete2, query, query_ = nil, nil, nil, nil
local count, tmpCount = 0, 0
for i = 1, table.maxn(tablesToCheck) do
if type(tablesToCheck[i]) == "string" then
query = db.getResult("SELECT attributes, SUBSTRING(CONVERT(attributes USING latin1) FROM 18) AS 'track' FROM " .. tablesToCheck[i] .. " WHERE itemtype = 2160 or itemtype = 2159 and SUBSTRING(CONVERT(attributes USING latin1) FROM 18) IN (SELECT SUBSTRING(CONVERT(attributes USING latin1) FROM 18) FROM " .. tablesToCheck[i] .. " WHERE itemtype = 2160 or itemtype = 2159 and CONVERT(attributes USING latin1) LIKE '%serial%' GROUP BY SUBSTRING(CONVERT(attributes USING latin1) FROM 18) HAVING COUNT(*) > 1)")
if query:getID() ~= -1 then
tmpCount = query:getRows()
while(true) do
delete = db.executeQuery("DELETE FROM " .. tablesToCheck[i] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) = " .. db.escapeString(query:getDataString("track")) .. " LIMIT 1;")
count = (delete and count + 1 or count)
text = "[!] -> Deleting items with duplicated serial from '" .. tablesToCheck[i] .. "': [Player: " .. getPlayerNameByGUID(query:getDataInt("player_id")) .. ", Item: " .. query:getDataInt("itemtype") .. ", Count: " .. query:getDataInt("count") .. ", Serial: " .. query:getDataString("track") .."]... " .. (delete and "Success!" or "Failed!")
final = final .. (final ~= "" and "\n" or "") .. text
tmpCount = tmpCount - 1
if (not query:next() or tmpCount <= 1) then break end
end
query:free()
end
else
if type(tablesToCheck[i][2]) == "string" then
query = db.getResult("SELECT attributes, SUBSTRING(CONVERT(attributes USING latin1) FROM 18) AS 'track' FROM " .. tablesToCheck[i][1] .. " WHERE itemtype = 2160 or itemtype = 2159 and SUBSTRING(CONVERT(attributes USING latin1) FROM 18) IN (SELECT SUBSTRING(CONVERT(attributes USING latin1) FROM 18) FROM " .. tablesToCheck[i][2] .. " WHERE itemtype = 2160 or itemtype = 2159 and CONVERT(attributes USING latin1) LIKE '%serial%' GROUP BY SUBSTRING(CONVERT(attributes USING latin1) FROM 18) HAVING COUNT(*) > 0)")
if query:getID() ~= -1 then
tmpCount = query:getRows()
while(true) do
query_ = db.getResult("SELECT attributes, SUBSTRING(CONVERT(attributes USING latin1) FROM 18) AS 'track' FROM " .. tablesToCheck[i][2] .. " WHERE itemtype = 2160 or itemtype = 2159 and SUBSTRING(CONVERT(attributes USING latin1) FROM 18) IN (SELECT SUBSTRING(CONVERT(attributes USING latin1) FROM 18) FROM " .. tablesToCheck[i][1] .. " WHERE itemtype = 2160 or itemtype = 2159 and CONVERT(attributes USING latin1) LIKE '%serial%' GROUP BY SUBSTRING(CONVERT(attributes USING latin1) FROM 18) HAVING COUNT(*) > 0)")
delete = db.executeQuery("DELETE FROM" .. tablesToCheck[i][1] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) = " .. db.escapeString(query:getDataString("track")) .. " LIMIT 1;")
count = (delete and count + 1 or count)
delete2 = db.executeQuery("DELETE FROM " .. tablesToCheck[i][2] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) = " .. db.escapeString(query:getDataString("track")) .. " LIMIT 1;")
count = (delete2 and count + 1 or count)
text = "[!] -> Deleting item with duplicated serial from '" .. tablesToCheck[i][1] .. "' [Player: " .. getPlayerNameByGUID(query:getDataInt("player_id")) .. ", Item: " .. query:getDataInt("itemtype") .. ", Count: " .. query:getDataInt("count") .. ", Serial: " .. query:getDataString("track") .."]... " .. (delete and "Success!" or "Failed!") ..
"\n[!] -> Deleting item with duplicated serial from '" .. tablesToCheck[i][2] .. "' [Player: " .. getPlayerNameByGUID(query_:getDataInt("player_id")) .. ", Item: " .. query_:getDataInt("itemtype") .. ", Count: " .. query_:getDataInt("count") .. ", Serial: " .. query_:getDataString("track") .."]... " .. (delete and "Success!" or "Failed!")
final = final .. (final ~= "" and "\n" or "") .. text
tmpCount = tmpCount - 1
if (query_:getID() ~= -1) then query_:free() end
if (not query:next() or tmpCount <= 1) then break end
end
query:free()
end
else
for j = 1, #tablesToCheck[i][2] do
query = db.getResult("SELECT attributes, SUBSTRING(CONVERT(attributes USING latin1) FROM 18) AS 'track' FROM " .. tablesToCheck[i][1] .. " WHERE itemtype = 2160 or itemtype = 2159 and SUBSTRING(CONVERT(attributes USING latin1) FROM 18) IN (SELECT SUBSTRING(CONVERT(attributes USING latin1) FROM 18) FROM " .. tablesToCheck[i][2][j] .. " WHERE itemtype = 2160 or itemtype = 2159 and CONVERT(attributes USING latin1) LIKE '%serial%' GROUP BY SUBSTRING(CONVERT(attributes USING latin1) FROM 18) HAVING COUNT(*) > 0)")
if query:getID() ~= -1 then
tmpCount = query:getRows()
while(true) do
query_ = db.getResult("SELECT attributes, SUBSTRING(CONVERT(attributes USING latin1) FROM 18) AS 'track' FROM " .. tablesToCheck[i][2][j] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) IN (SELECT SUBSTRING(CONVERT(attributes USING latin1) FROM 18) FROM " .. tablesToCheck[i][1] .. " WHERE CONVERT(attributes USING latin1) LIKE '%serial%' GROUP BY SUBSTRING(CONVERT(attributes USING latin1) FROM 18) HAVING COUNT(*) > 0)")
delete = db.executeQuery("DELETE FROM " .. tablesToCheck[i][1] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) = " .. db.escapeString(query:getDataString("track")) .. " LIMIT 1;")
count = (delete and count + 1 or count)
delete2 = db.executeQuery("DELETE FROM " .. tablesToCheck[i][2][j] .. " WHERE SUBSTRING(CONVERT(attributes USING latin1) FROM 18) = " .. db.escapeString(query:getDataString("track")) .. " LIMIT 1;")
count = (delete2 and count + 1 or count)
text = "[!] -> Deleting item with duplicated serial from '" .. tablesToCheck[i][1] .. "' [Player: " .. getPlayerNameByGUID(query:getDataInt("player_id")) .. ", Item: " .. query:getDataInt("itemtype") .. ", Count: " .. query:getDataInt("count") .. ", Serial: " .. query:getDataString("track") .."]... " .. (delete and "Success!" or "Failed!") ..
"\n[!] -> Deleting item with duplicated serial from '" .. tablesToCheck[i][2][j] .. "' [Player: " .. getPlayerNameByGUID(query_:getDataInt("player_id")) .. ", Item: " .. query_:getDataInt("itemtype") .. ", Count: " .. query_:getDataInt("count") .. ", Serial: " .. query_:getDataString("track") .."]... " .. (delete and "Success!" or "Failed!")
final = final .. (final ~= "" and "\n" or "") .. text
tmpCount = tmpCount - 1
if (query_:getID() ~= -1) then query_:free() end
if (not query:next() or tmpCount <= 1) then break end
end
query:free()
end
end
end
end
end
if f ~= nil then
print("["..os.date("%X", os.time())..".TMI] >> Item Tracker: " .. count .. " duplicated items have been deleted...")
f:write("[" .. os.date("%d %B %Y %X ", os.time()) .. "] >> [Item Tracker] " .. count .. " duplicated items have been deleted from the database.\n" .. (final == "" and "[!] -> No duplicated item was found in the database" or final) .. "\n\n")
f:close()
else
print("[["..os.date("%X", os.time())..".TMI] >> [Item Tracker] Cannot save info to file!")
end
return true
end
Last edited: