Bom, como todos sabem, existe o shop.lua em servidores 0.4 para receber itens. Muitos deles têm loops infinitos ou fazem uma varredura completa no banco de dados, o que pode deixá-los instáveis. Isso ocorre principalmente quando o script não verifica adequadamente se há itens para processar ou se o banco de dados está sobrecarregado com consultas desnecessárias.
No entanto, com algumas melhorias, podemos otimizar esse processo, garantindo que o servidor se mantenha estável e eficiente. No nosso exemplo, aplicamos algumas mudanças importantes:
Checagem eficiente de itens pendentes: A consulta ao banco de dados foi otimizada para verificar se existem realmente itens pendentes para o jogador. Se não houver itens, o script termina sua execução rapidamente, evitando sobrecarga.
Evitar loops infinitos: O loop foi ajustado para garantir que, se não houver mais itens para processar, o script saia sem continuar verificando o banco de dados, prevenindo loops desnecessários.
Logs: Foi adicionado um sistema de logs, onde cada transação bem sucedida do jogador é registrada com data e hora, além de informações sobre o jogador e os itens recebidos.
Execução controlada com intervalos: Ao invés de fazer consultas contínuas ao banco de dados, o script executa checagens de tempos em tempos, configuráveis pelo parâmetro SQL_interval. Isso distribui as verificações ao longo do tempo e evita que o servidor fique sobrecarregado com solicitações simultâneas.
Segue o scripts:
data/globalevents/scripts/shop.lua
function getCurrentDateTime()
local currentDateTime = os.date("%Y-%m-%d %H:%M:%S")
return currentDateTime
end
function createDirectoryIfNotExists(dir)
local command = "mkdir -p " .. dir
os.execute(command)
end
function saveLog(message)
local logFilePath = "data/logs/shop/shop.txt"
local logDir = "data/logs/shop/"
createDirectoryIfNotExists(logDir)
local currentDateTime = getCurrentDateTime()
local logMessage = string.format("[%s] %s\n", currentDateTime, message)
local file = io.open(logFilePath, "a")
if file then
file:write(logMessage)
file:close()
else
print("Erro ao tentar escrever no arquivo de log.")
end
end
SHOP_MSG_TYPE = 19
SQL_interval = 5
function onThink(interval, lastExecution)
local result_plr = db.getResult("SELECT * FROM z_ots_comunication WHERE `type` = 'login';")
if result_plr:getID() == -1 then
return true
end
local hasMoreItems = false
while true do
local id = tonumber(result_plr:getDataInt("id"))
local cid = getCreatureByName(tostring(result_plr:getDataString("name")))
if isPlayer(cid) then
hasMoreItems = true
local itemtogive_id = tonumber(result_plr:getDataInt("param1"))
local itemtogive_count = tonumber(result_plr:getDataInt("param2"))
local add_item_name = tostring(result_plr:getDataString("param6"))
local received_item = 0
local full_weight = 0
if isItemRune(itemtogive_id) then
full_weight = getItemWeightById(itemtogive_id, 1)
else
full_weight = getItemWeightById(itemtogive_id, itemtogive_count)
end
local free_cap = getPlayerFreeCap(cid)
if full_weight <= free_cap then
local new_item = doCreateItemEx(itemtogive_id, itemtogive_count)
received_item = doPlayerAddItemEx(cid, new_item)
if received_item == RETURNVALUE_NOERROR then
doPlayerSendTextMessage(cid, SHOP_MSG_TYPE, string.format("Você recebeu >> %s << da loja.", add_item_name))
doPlayerSave(cid)
db.executeQuery("DELETE FROM `z_ots_comunication` WHERE `id` = " .. id .. ";")
db.executeQuery("UPDATE `z_shop_history` SET `trans_state`='realized', `trans_real`=" .. os.time() .. " WHERE id = " .. id .. ";")
saveLog(string.format("[%s] %s (ID: %d), Você recebeu >> %s << da loja.", getCurrentDateTime(), tostring(result_plr:getDataString("name")), id, add_item_name))
end
else
doPlayerSendTextMessage(cid, SHOP_MSG_TYPE, string.format("Você não tem capacidade suficiente para >> %s <<. Necessário: %.2f oz. Disponível: %.2f oz.", add_item_name, full_weight, free_cap))
saveLog(string.format("[%s] %s (ID: %d), Tentou comprar >> %s <<, mas não tinha capacidade suficiente. Necessário: %.2f oz. Disponível: %.2f oz.", getCurrentDateTime(), tostring(result_plr:getDataString("name")), id, add_item_name, full_weight, free_cap))
end
end
if not result_plr:next() then
break
end
end
result_plr:free()
if not hasMoreItems then
return false
end
return true
end
data/globalevents/globalevents.xml
<globalevent name="shop" interval="30000" script="shop.lua"/>
*Testado em Myaac
*Testado em OTX2 8.60
*Testado em Ubuntu 20.04
*Não precisa criar pasta, ele mesmo cria.
Com essas melhorias, a performance do servidor foi significativamente melhorada, garantindo que o sistema de loja funcione de forma mais estável e eficiente, sem sobrecarregar o banco de dados ou causar lags. Agora, a transação de itens na loja ocorre de forma mais controlada e com menos chance de erros ou travamentos. by @L3K0T