Explain how item disapear
I have no idea, but im suspecting the item getting to much attributes which make it "weight" more than 64kib which is max at phpmyadmin. (pokeserver)
Item = Pokemons/pokeballs.
Explain how item disapear
Um? I did calculate it wrong last time, but not thaat badI think that is 8.065817517 x 10^67 = 52!
that is just with letters
with numbers and letters is 62!
idk
Change in mysql (by phpmyadmin) columns 'type of data' ( column `attributes` in `player_items`, `player_depotitems` and `tile_items`) from BLOB to LONGBLOB (or MEDIUMBLOB), for TFS it will be same, but no more problem with 64KB limit. I found that problem loong time ago when developers added `house_data` table, 64KB to store all house tiles+items wasn't enought.I have no idea, but im suspecting the item getting to much attributes which make it "weight" more than 64kib which is max at phpmyadmin. (pokeserver)
Item = Pokemons/pokeballs.
http://dev.mysql.com/doc/refman/5.0/en/blob.html said:BLOB - 65535 bytes - 64KB
MEDIUMBLOB - 16,777,215 bytes (2^24 - 1) - 16MB
LONGBLOB - 4G bytes (2^32 – 1) - 4GB
local lettersUsedToGenerateHash = "AaBbCcDdEeFfGgHhIiJjKkLlMmOoPpQqRrSsTtUuVvWwXxYyZz"
math.randomseed(os.time()) -- required!
function generateSerial()
local newSerial = "!"
for k = 1, 10 do
local l = math.random(1, string.len(lettersUsedToGenerateHash))
newSerial = newSerial .. string.sub(lettersUsedToGenerateHash, l, l)
end
local newSerialInt = math.random(899999) + 100000 -- this will return always same lenght
newSerial = newSerial .. "-" .. os.time() .. "-" .. newSerialInt
-- length: ![10 letters]-[10 numbers (unix date)]-[6 numbers]
-- length = 29 [always!]
return newSerial
end
local function doPlayerAddDepotItems(cid, items, town)
if (not isPlayer(cid)) then
error("Player not found")
end
local town = town or getPlayerTown(cid)
local attritemid = doCreateItemEx(2596, 1)
for item, count in pairs(items) do
if (type(item) == "number") then
local thing = doAddContainerItem(attritemid, item, count)
doItemSetAttribute(thing, "description", "This item belongs to " .. getPlayerName(cid) .. ".")
doItemSetAttribute(thing, "owner", getPlayerGUID(cid))
doItemSetAttribute(thing, "aid", getPlayerGUID(cid)+10000)
doItemSetAttribute(thing, "serial", generateSerial())
elseif (type(item) == "string") then
if getItemIdByName(item) then
local thing = doAddContainerItem(attritemid, item, count)
doItemSetAttribute(thing, "description", "This item belongs to " .. getPlayerName(cid) .. ".")
doItemSetAttribute(thing, "owner", getPlayerGUID(cid))
doItemSetAttribute(thing, "aid", getPlayerGUID(cid)+10000)
doItemSetAttribute(thing, "serial", generateSerial())
end
else
error("Undefinied type of item name")
end
end
return doPlayerSendMailByName(getCreatureName(cid), attritemid, town)
end
function onThink(interval, lastExecution, thinkInterval)
local result = db.getResult("SELECT * FROM shop_history WHERE `processed` = 0;")
if(result:getID() ~= -1) then
while(true) do
cid = getCreatureByName(tostring(result:getDataString("player")))
product = tonumber(result:getDataInt("product"))
itemr = db.getResult("SELECT * FROM shop_offer WHERE `id` = "..product..";")
if isPlayer(cid) then
local id = tonumber(itemr:getDataInt("item"))
local tid = tonumber(result:getDataInt("id"))
local count = tonumber(itemr:getDataInt("count"))
local tipe = tonumber(itemr:getDataInt("type"))
local productn = tostring(itemr:getDataString("name"))
if isInArray({5,8},tipe) then
if isPlayer(cid) then
local received = doPlayerAddDepotItems(cid, {[id]=count})
if received then
doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You received "..productn.." in depot of your hometown.")
db.executeQuery("UPDATE `shop_history` SET `processed`='1' WHERE id = " .. tid .. ";")
doPlayerSave(cid)
else
doPlayerSendTextMessage(cid,19, "Report to a gamemaster..")
end
else
doPlayerSendTextMessage(cid,19, "Report to a gamemaster.")
end
elseif isInArray({6,7},tipe) then
if tipe == 6 then
bcap = 8
bid = 1987
elseif tipe == 7 then
bcap = 20
bid = 1988
end
if isItemRune(id) then
count = 1
end
if isPlayer(cid) then
local bag = doCreateItemEx(bid, 1)
for i = 1,bcap do
doAddContainerItem(bag, id, count)
end
received = doPlayerAddItemEx(cid, bag, true)
if received then
doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You received "..productn.." in depot of your hometown.")
db.executeQuery("UPDATE `shop_history` SET `processed`='1' WHERE id = " .. tid .. ";")
doPlayerSave(cid)
else
doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You need a free slot on container to receive "..productn..".")
end
else
doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You need "..getItemWeightById(id, count).." of free capacity to receive "..productn..".")
end
end
end
itemr:free()
if not(result:next()) then
break
end
end
result:free()
end
return true
end
Um? I did calculate it wrong last time, but not thaat bad
50^10 = 10 letters, each is one of 50 possible (a-zA-Z) = 97.656.250.000.000.000
900.000 = possible numbers 100.000 - 999.999
97.656.250.000.000.000 * 900.000 = 8.7 * 10^22 = MUCH = 87.890.625.000.000.000.000.00
So serial can be one of 87.890.625.000.000.000.000.00 combinations PER SECOND.
Even if you add serial to maany items per second there is no chance to get same serial for 2 of them.
So no more MySQL queries in serial generator!
EDIT:
Change in mysql (by phpmyadmin) columns 'type of data' ( column `attributes` in `player_items`, `player_depotitems` and `tile_items`) from BLOB to LONGBLOB (or MEDIUMBLOB), for TFS it will be same, but no more problem with 64KB limit. I found that problem loong time ago when developers added `house_data` table, 64KB to store all house tiles+items wasn't enought.
What if create a new column in DB and set serial there?
SELECT COUNT(1), substring(CONVERT(`attributes` USING latin1) , LOCATE('serial', CONVERT(`attributes` USING latin1))+11, 29) AS xx FROM `player_items` WHERE LOCATE('serial', CONVERT(`attributes` USING latin1)) != 0 GROUP BY xx HAVING COUNT(1) > 1
(12345 - 5 bytes between attribute name and it's value)serial12345!here-fake-344-serial
15:50 You see a solar axe (Atk:52, Def:29 +3).
It can only be wielded properly by players of level 130 or higher.
It weighs 110.00 oz.
ItemID: [8925].
[COLOR="#FF0000"]Serial: [E3Gh-PS4q9mgWzJ].[/COLOR]
Position: {x = 859, y = 964, z = 7}.
Query to load duplicated serial IDs, from all tables:
SELECT unitedItems.serial, COUNT(1) AS duplicatesCount FROM (SELECT substring(CONVERT(`attributes` USING latin1) , LOCATE('serial', CONVERT(`attributes` USING latin1))+11, 29) AS serial FROM `player_items` WHERE LOCATE('serial', CONVERT(`attributes` USING latin1)) != 0
UNION ALL
SELECT substring(CONVERT(`attributes` USING latin1) , LOCATE('serial', CONVERT(`attributes` USING latin1))+11, 29) AS serial FROM `player_depotitems` WHERE LOCATE('serial', CONVERT(`attributes` USING latin1)) != 0
UNION ALL
SELECT substring(CONVERT(`attributes` USING latin1) , LOCATE('serial', CONVERT(`attributes` USING latin1))+11, 29) AS serial FROM `tile_items` WHERE LOCATE('serial', CONVERT(`attributes` USING latin1)) != 0) unitedItems GROUP BY unitedItems.serial HAVING COUNT(1) > 1;
Returns list of serials that are in attributes of more then one item on server like:
![]()
Then you must make a string (in LUA) of all these selected 'serials' and put them into query (in right place: '... IN (HERE)').
Then run query 3 times for 3 tables:
DELETE FROM `player_items` WHERE LOCATE('serial', CONVERT(`attributes` USING latin1)) != 0 AND substring(CONVERT(`attributes` USING latin1) , LOCATE('serial', CONVERT(`attributes` USING latin1))+11, 29) IN ('first selected serial', 'second selected serial', 'and more', 'more');
DELETE FROM `player_depotitems` WHERE LOCATE('serial', CONVERT(`attributes` USING latin1)) != 0 AND substring(CONVERT(`attributes` USING latin1) , LOCATE('serial', CONVERT(`attributes` USING latin1))+11, 29) IN ('first selected serial', 'second selected serial', 'and more', 'more');
DELETE FROM `tile_items` WHERE LOCATE('serial', CONVERT(`attributes` USING latin1)) != 0 AND substring(CONVERT(`attributes` USING latin1) , LOCATE('serial', CONVERT(`attributes` USING latin1))+11, 29) IN ('first selected serial', 'second selected serial', 'and more', 'more');