What's new

Globalevents [8.x] [FIX] Usuni?cie mo?liwo?ci lagowania serwera za pomoc? item?w z SMS SHOP.

Status
Not open for further replies.

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)
Kod Lua:


  1. -- ### CONFIG ###
  2. -- message send to player by script "type" (types you can check in "global.lua")
  3. local SHOP_MSG_TYPE = 19
  4. -- time (in seconds) between connections to SQL database by shop script
  5. local SQL_interval = 30
  6. -- ### END OF CONFIG ###
  7. function onThink(interval, lastExecution)
  8. local result_plr = db.getResult("SELECT * FROM z_ots_comunication WHERE `type` = 'login';")
  9. if(result_plr:getID() ~= -1) then
  10. while(true) do
  11. local id = tonumber(result_plr:getDataInt("id"))
  12. local action = tostring(result_plr:getDataString("action"))
  13. local delete = tonumber(result_plr:getDataInt("delete_it"))
  14. local cid = getCreatureByName(tostring(result_plr:getDataString("name")))
  15. if isPlayer(cid) == TRUE then
  16. local itemtogive_id = tonumber(result_plr:getDataInt("param1"))
  17. local itemtogive_count = tonumber(result_plr:getDataInt("param2"))
  18. local container_id = tonumber(result_plr:getDataInt("param3"))
  19. local container_count = tonumber(result_plr:getDataInt("param4"))
  20. local add_item_type = tostring(result_plr:getDataString("param5"))
  21. local add_item_name = tostring(result_plr:getDataString("param6"))
  22. local received_item = 0
  23. local full_weight = 0
  24. if add_item_type == 'container' then
  25. container_weight = getItemWeightById(container_id, 1, true)
  26. if isItemRune(itemtogive_id) == TRUE then
  27. items_weight = container_count * getItemWeightById(itemtogive_id, 1, true)
  28. else
  29. items_weight = container_count * getItemWeightById(itemtogive_id, itemtogive_count, true)
  30. end
  31. full_weight = items_weight + container_weight
  32. else
  33. full_weight = getItemWeightById(itemtogive_id, itemtogive_count, true)
  34. if isItemRune(itemtogive_id) == TRUE then
  35. full_weight = getItemWeightById(itemtogive_id, 1,true)
  36. else
  37. full_weight = getItemWeightById(itemtogive_id, itemtogive_count,true)
  38. end
  39. end
  40. local free_cap = getPlayerFreeCap(cid)
  41. if full_weight <= free_cap then
  42. if add_item_type == 'container' then
  43. local new_container = doCreateItemEx(container_id, 1)
  44. local iter = 0
  45. while iter ~= container_count do
  46. doAddContainerItem(new_container, itemtogive_id, itemtogive_count)
  47. iter = iter + 1
  48. end
  49. received_item = doPlayerAddItemEx(cid, new_container)
  50. else
  51. local new_item = doCreateItemEx(itemtogive_id, itemtogive_count)
  52. received_item = doPlayerAddItemEx(cid, new_item)
  53. end
  54. if received_item == RETURNVALUE_NOERROR then
  55. doPlayerSendTextMessage(cid, SHOP_MSG_TYPE, 'You received >> '.. add_item_name ..' << from Tiberia shop.')
  56. db.executeQuery("DELETE FROM `z_ots_comunication` WHERE `id` = " .. id .. ";")
  57. db.executeQuery("UPDATE `z_shop_history_item` SET `trans_state`='realized', `trans_real`=" .. os.time() .. " WHERE id = " .. id .. ";")
  58. &nbsp;&nbsp;&nbsp;&nbsp;doPlayerSave(cid)
  59. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true
  60. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
  61. 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.')
  62. end
  63. else
  64. 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.')
  65. end
  66. end
  67. if not(result_plr:next()) then
  68. break
  69. end
  70. end
  71. result_plr:free()
  72. end
  73. return TRUE
  74. 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.​

4. Klient - Testowane na 8.50, powinno dzia?a? wsz?dzie.

5. Skrypt

Dla leniwych: gotowy skrypt
Kod Lua:


  1. -- ### CONFIG ###
  2. -- ### FIXED BY GANDHI ( ) ####
  3. -- message send to player by script "type" (types you can check in "global.lua")
  4. local SHOP_MSG_TYPE = 19
  5. -- time (in seconds) between connections to SQL database by shop script
  6. local SQL_interval = 30
  7. -- ### END OF CONFIG ###
  8. function onUse(cid, item, fromPosition, itemEx, toPosition)
  9. 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');")
  10. if(result_plr:getID() ~= -1) then
  11. while(true) do
  12. local id = tonumber(result_plr:getDataInt("id"))
  13. local action = tostring(result_plr:getDataString("action"))
  14. local delete = tonumber(result_plr:getDataInt("delete_it"))
  15. local cid = getPlayerByNameWildcard(tostring(result_plr:getDataString("name")))
  16. if isPlayer(cid) == TRUE then
  17. local itemtogive_id = tonumber(result_plr:getDataInt("param1"))
  18. local itemtogive_count = tonumber(result_plr:getDataInt("param2"))
  19. local container_id = tonumber(result_plr:getDataInt("param3"))
  20. local container_count = tonumber(result_plr:getDataInt("param4"))
  21. local add_item_type = tostring(result_plr:getDataString("param5"))
  22. local add_item_name = tostring(result_plr:getDataString("param6"))
  23. local received_item = 0
  24. local full_weight = 0
  25. if add_item_type == 'container' then
  26. container_weight = getItemWeightById(container_id, 1, true)
  27. if isItemRune(itemtogive_id) == TRUE then
  28. items_weight = container_count * getItemWeightById(itemtogive_id, 1, true)
  29. else
  30. items_weight = container_count * getItemWeightById(itemtogive_id, itemtogive_count, true)
  31. end
  32. full_weight = items_weight + container_weight
  33. else
  34. full_weight = getItemWeightById(itemtogive_id, itemtogive_count, true)
  35. if isItemRune(itemtogive_id) == TRUE then
  36. full_weight = getItemWeightById(itemtogive_id, 1,true)
  37. else
  38. full_weight = getItemWeightById(itemtogive_id, itemtogive_count,true)
  39. end
  40. end
  41. local free_cap = getPlayerFreeCap(cid)
  42. if full_weight <= free_cap then
  43. if add_item_type == 'container' then
  44. local new_container = doCreateItemEx(container_id, 1)
  45. local iter = 0
  46. while iter ~= container_count do
  47. doAddContainerItem(new_container, itemtogive_id, itemtogive_count)
  48. iter = iter + 1
  49. end
  50. received_item = doPlayerAddItemEx(cid, new_container)
  51. else
  52. local new_item = doCreateItemEx(itemtogive_id, itemtogive_count)
  53. received_item = doPlayerAddItemEx(cid, new_item)
  54. end
  55. if received_item == RETURNVALUE_NOERROR then
  56. doPlayerSendTextMessage(cid, SHOP_MSG_TYPE, 'You received >> '.. add_item_name ..' << from Tiberia shop.')
  57. db.executeQuery("DELETE FROM `z_ots_comunication` WHERE `id` = " .. id .. ";")
  58. db.executeQuery("UPDATE `z_shop_history_item` SET `trans_state`='realized', `trans_real`=" .. os.time() .. " WHERE id = " .. id .. ";")
  59. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doPlayerSave(cid)
  60. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
  61. 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.')
  62. end
  63. else
  64. 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.')
  65. end
  66. end
  67. if not(result_plr:next()) then
  68. break
  69. end
  70. end
  71. result_plr:free()
  72. end
  73. return TRUE
  74. end

Wersja z w?asnym podmienianiem linijek
W swoim skrypcie zamieniamy:
Kod Lua:


  1. local result_plr = db.getResult("SELECT * FROM z_ots_comunication WHERE `type` = 'login';")



na to
Kod Lua:


  1. 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:


  1. local cid = getCreatureByName(tostring(result_plr:getDataString("name")))



na to
Kod Lua:


  1. local cid = getPlayerByNameWildcard(tostring(result_plr:getDataString("name")))




oraz pod tym:
Kod Lua:


  1. &nbsp;&nbsp;&nbsp;&nbsp;doPlayerSave(cid)



usu? t? linijk?
Kod Lua:


  1. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true
 
Status
Not open for further replies.
Top