Gandhi
Active User
- Joined
- Aug 7, 2013
- Messages
- 80
- Reaction score
- 19
1. Autor - Gandhi
2. Oryginalny temat -
http://otibia.pl/globalevents-spells-creatureevents-49/%5Bfix%5D-usuniecie-mozliwosci-lagowania-serwera-za-pomoca-itemow-z-sms-shop-447/
3. Opis - Wiele serwer?w u?ywa oto takiego SMS SHOP, je?li jeste? jednym z nim, to potrzebujesz fixa!
(Dok?adna lokalizacja: data/globalevents/scripts/dalej_nie_wiem_ale_pewnie_cos_jak_shopsystem.lua)
4. Klient - Testowane na 8.50, powinno dzia?a? wsz?dzie.
5. Skrypt
Dla leniwych: gotowy skrypt
Wersja z w?asnym podmienianiem linijek
2. Oryginalny temat -
http://otibia.pl/globalevents-spells-creatureevents-49/%5Bfix%5D-usuniecie-mozliwosci-lagowania-serwera-za-pomoca-itemow-z-sms-shop-447/
3. Opis - Wiele serwer?w u?ywa oto takiego SMS SHOP, je?li jeste? jednym z nim, to potrzebujesz fixa!
(Dok?adna lokalizacja: data/globalevents/scripts/dalej_nie_wiem_ale_pewnie_cos_jak_shopsystem.lua)
Kod Lua:
- -- ### CONFIG ###
- -- message send to player by script "type" (types you can check in "global.lua")
- local SHOP_MSG_TYPE = 19
- -- time (in seconds) between connections to SQL database by shop script
- local SQL_interval = 30
- -- ### END OF CONFIG ###
- function onThink(interval, lastExecution)
- local result_plr = db.getResult("SELECT * FROM z_ots_comunication WHERE `type` = 'login';")
- if(result_plr:getID() ~= -1) then
- while(true) do
- local id = tonumber(result_plr:getDataInt("id"))
- local action = tostring(result_plr:getDataString("action"))
- local delete = tonumber(result_plr:getDataInt("delete_it"))
- local cid = getCreatureByName(tostring(result_plr:getDataString("name")))
- if isPlayer(cid) == TRUE then
- local itemtogive_id = tonumber(result_plr:getDataInt("param1"))
- local itemtogive_count = tonumber(result_plr:getDataInt("param2"))
- local container_id = tonumber(result_plr:getDataInt("param3"))
- local container_count = tonumber(result_plr:getDataInt("param4"))
- local add_item_type = tostring(result_plr:getDataString("param5"))
- local add_item_name = tostring(result_plr:getDataString("param6"))
- local received_item = 0
- local full_weight = 0
- if add_item_type == 'container' then
- container_weight = getItemWeightById(container_id, 1, true)
- if isItemRune(itemtogive_id) == TRUE then
- items_weight = container_count * getItemWeightById(itemtogive_id, 1, true)
- else
- items_weight = container_count * getItemWeightById(itemtogive_id, itemtogive_count, true)
- end
- full_weight = items_weight + container_weight
- else
- full_weight = getItemWeightById(itemtogive_id, itemtogive_count, true)
- if isItemRune(itemtogive_id) == TRUE then
- full_weight = getItemWeightById(itemtogive_id, 1,true)
- else
- full_weight = getItemWeightById(itemtogive_id, itemtogive_count,true)
- end
- end
- local free_cap = getPlayerFreeCap(cid)
- if full_weight <= free_cap then
- if add_item_type == 'container' then
- local new_container = doCreateItemEx(container_id, 1)
- local iter = 0
- while iter ~= container_count do
- doAddContainerItem(new_container, itemtogive_id, itemtogive_count)
- iter = iter + 1
- end
- received_item = doPlayerAddItemEx(cid, new_container)
- else
- local new_item = doCreateItemEx(itemtogive_id, itemtogive_count)
- received_item = doPlayerAddItemEx(cid, new_item)
- end
- if received_item == RETURNVALUE_NOERROR then
- doPlayerSendTextMessage(cid, SHOP_MSG_TYPE, 'You received >> '.. add_item_name ..' << from Tiberia shop.')
- db.executeQuery("DELETE FROM `z_ots_comunication` WHERE `id` = " .. id .. ";")
- db.executeQuery("UPDATE `z_shop_history_item` SET `trans_state`='realized', `trans_real`=" .. os.time() .. " WHERE id = " .. id .. ";")
- doPlayerSave(cid)
- return true
- else
- doPlayerSendTextMessage(cid, SHOP_MSG_TYPE, '>> '.. add_item_name ..' << from Tiberia shop is waiting for you. Please make place for this item in your backpack/hands and wait about '.. SQL_interval ..' seconds to get it.')
- end
- else
- doPlayerSendTextMessage(cid, SHOP_MSG_TYPE, '>> '.. add_item_name ..' << from Tiberia shop is waiting for you. It weight is '.. full_weight ..' oz., you have only '.. free_cap ..' oz. free capacity. Put some items in depot and wait about '.. SQL_interval ..' seconds to get it.')
- end
- end
- if not(result_plr:next()) then
- break
- end
- end
- result_plr:free()
- end
- return TRUE
- end
Za???my, ?e 10 graczy kupi?o po 10 przedmiot?w, a nie zalogowa?o si? do gry. Wychodzi 100 item?w, kt?re s? przy ka?dym wykonaniu tego skryptu pobierane do pami?ci i przetwarzane.
O ile to jeszcze nie jest du?o, to dalej skrypt jedzie po kolei ka?dy z tych stu item?w, pobiera nazw? gracza, do kt?rego item powinien by? oddany, i dalej funkcja getCreatureByName przeszukuje wszystkie stworzenia ?ywe na mapie, dop?ki nie znajdzie kogo? o nazwie takiej, jak adresat itemu. Wi?c je?li wszyscy gracze, na kt?rych czekaj? itemki s? offline, razem czeka 100 itemk?w, a na mapie jest 3000 potwor?w, graczy i npc, to wtedy skrypt robi p?tle 300,000 razy (i to co ka?de xx minut - zale?nie od czasu ustawionego w globalevents.xml)! Du?o za du?o.
Ten fix dzia?a tak, ?e pobiera itemy z sms shopa tylko tych graczy, kt?rzy s? aktualnie online, oraz zast?puje funkcj? getCreatureByName przez getPlayerByNameWildcard, oraz usuwa linijk? odpowiedzialn? za to, ?e na ka?de wywo?anie skryptu jeden gracz dostaje item (wolne dostarczanie przedmiot?w).
W praktyce z tym fixem, przy takich samych warunkach, jak opisa?em wy?ej (300,000 razy), skrypt nie wykona ?adnej p?tli (gracze s? offline - nie ma potrzeby nic robi?). Je?li jednak tych dziesi?ciu si? zaloguje, a wszystkich graczy online jest 100, to wtedy skrypt wykona si? maximum 10,000 razy (30 razy szybciej), i to tylko jeden raz.
O ile to jeszcze nie jest du?o, to dalej skrypt jedzie po kolei ka?dy z tych stu item?w, pobiera nazw? gracza, do kt?rego item powinien by? oddany, i dalej funkcja getCreatureByName przeszukuje wszystkie stworzenia ?ywe na mapie, dop?ki nie znajdzie kogo? o nazwie takiej, jak adresat itemu. Wi?c je?li wszyscy gracze, na kt?rych czekaj? itemki s? offline, razem czeka 100 itemk?w, a na mapie jest 3000 potwor?w, graczy i npc, to wtedy skrypt robi p?tle 300,000 razy (i to co ka?de xx minut - zale?nie od czasu ustawionego w globalevents.xml)! Du?o za du?o.
Ten fix dzia?a tak, ?e pobiera itemy z sms shopa tylko tych graczy, kt?rzy s? aktualnie online, oraz zast?puje funkcj? getCreatureByName przez getPlayerByNameWildcard, oraz usuwa linijk? odpowiedzialn? za to, ?e na ka?de wywo?anie skryptu jeden gracz dostaje item (wolne dostarczanie przedmiot?w).
W praktyce z tym fixem, przy takich samych warunkach, jak opisa?em wy?ej (300,000 razy), skrypt nie wykona ?adnej p?tli (gracze s? offline - nie ma potrzeby nic robi?). Je?li jednak tych dziesi?ciu si? zaloguje, a wszystkich graczy online jest 100, to wtedy skrypt wykona si? maximum 10,000 razy (30 razy szybciej), i to tylko jeden raz.
4. Klient - Testowane na 8.50, powinno dzia?a? wsz?dzie.
5. Skrypt
Dla leniwych: gotowy skrypt
Kod Lua:
- -- ### CONFIG ###
- -- ### FIXED BY GANDHI ( ) ####
- -- message send to player by script "type" (types you can check in "global.lua")
- local SHOP_MSG_TYPE = 19
- -- time (in seconds) between connections to SQL database by shop script
- local SQL_interval = 30
- -- ### END OF CONFIG ###
- function onUse(cid, item, fromPosition, itemEx, toPosition)
- local result_plr = db.getResult("SELECT `z_ots_communication`,* FROM `z_ots_communication` JOIN `players` ON (`z_ots_communication`.`name` = `players`.`name`) WHERE (`players`.`online` = 1 AND `z_ots_communication`.`type` = 'login');")
- if(result_plr:getID() ~= -1) then
- while(true) do
- local id = tonumber(result_plr:getDataInt("id"))
- local action = tostring(result_plr:getDataString("action"))
- local delete = tonumber(result_plr:getDataInt("delete_it"))
- local cid = getPlayerByNameWildcard(tostring(result_plr:getDataString("name")))
- if isPlayer(cid) == TRUE then
- local itemtogive_id = tonumber(result_plr:getDataInt("param1"))
- local itemtogive_count = tonumber(result_plr:getDataInt("param2"))
- local container_id = tonumber(result_plr:getDataInt("param3"))
- local container_count = tonumber(result_plr:getDataInt("param4"))
- local add_item_type = tostring(result_plr:getDataString("param5"))
- local add_item_name = tostring(result_plr:getDataString("param6"))
- local received_item = 0
- local full_weight = 0
- if add_item_type == 'container' then
- container_weight = getItemWeightById(container_id, 1, true)
- if isItemRune(itemtogive_id) == TRUE then
- items_weight = container_count * getItemWeightById(itemtogive_id, 1, true)
- else
- items_weight = container_count * getItemWeightById(itemtogive_id, itemtogive_count, true)
- end
- full_weight = items_weight + container_weight
- else
- full_weight = getItemWeightById(itemtogive_id, itemtogive_count, true)
- if isItemRune(itemtogive_id) == TRUE then
- full_weight = getItemWeightById(itemtogive_id, 1,true)
- else
- full_weight = getItemWeightById(itemtogive_id, itemtogive_count,true)
- end
- end
- local free_cap = getPlayerFreeCap(cid)
- if full_weight <= free_cap then
- if add_item_type == 'container' then
- local new_container = doCreateItemEx(container_id, 1)
- local iter = 0
- while iter ~= container_count do
- doAddContainerItem(new_container, itemtogive_id, itemtogive_count)
- iter = iter + 1
- end
- received_item = doPlayerAddItemEx(cid, new_container)
- else
- local new_item = doCreateItemEx(itemtogive_id, itemtogive_count)
- received_item = doPlayerAddItemEx(cid, new_item)
- end
- if received_item == RETURNVALUE_NOERROR then
- doPlayerSendTextMessage(cid, SHOP_MSG_TYPE, 'You received >> '.. add_item_name ..' << from Tiberia shop.')
- db.executeQuery("DELETE FROM `z_ots_comunication` WHERE `id` = " .. id .. ";")
- db.executeQuery("UPDATE `z_shop_history_item` SET `trans_state`='realized', `trans_real`=" .. os.time() .. " WHERE id = " .. id .. ";")
- doPlayerSave(cid)
- else
- doPlayerSendTextMessage(cid, SHOP_MSG_TYPE, '>> '.. add_item_name ..' << from Tiberia shop is waiting for you. Please make place for this item in your backpack/hands and wait about '.. SQL_interval ..' seconds to get it.')
- end
- else
- doPlayerSendTextMessage(cid, SHOP_MSG_TYPE, '>> '.. add_item_name ..' << from Tiberia shop is waiting for you. It weight is '.. full_weight ..' oz., you have only '.. free_cap ..' oz. free capacity. Put some items in depot and wait about '.. SQL_interval ..' seconds to get it.')
- end
- end
- if not(result_plr:next()) then
- break
- end
- end
- result_plr:free()
- end
- return TRUE
- end
Wersja z w?asnym podmienianiem linijek
W swoim skrypcie zamieniamy:
Kod Lua:
na to
Kod Lua:
zamie? to:
Kod Lua:
na to
Kod Lua:
oraz pod tym:
Kod Lua:
usu? t? linijk?
Kod Lua:
Kod Lua:
- local result_plr = db.getResult("SELECT * FROM z_ots_comunication WHERE `type` = 'login';")
na to
Kod Lua:
- local result_plr = db.getResult("SELECT `z_ots_communication`.* FROM `z_ots_comunication` JOIN `players` ON (`z_ots_communication`.`name` = `players`.`name`) WHERE (`players`.`online` = 1 AND `z_ots_communication`.`type` = 'login');")
zamie? to:
Kod Lua:
- local cid = getCreatureByName(tostring(result_plr:getDataString("name")))
na to
Kod Lua:
- local cid = getPlayerByNameWildcard(tostring(result_plr:getDataString("name")))
oraz pod tym:
Kod Lua:
- doPlayerSave(cid)
usu? t? linijk?
Kod Lua:
- return true