Ir para conteúdo

L3K0T

Diretor
  • Registro em

  • Última visita

Tudo que L3K0T postou

  1. de Para TUTORIAL otclient Mehah 3.1 Bem-vindo ao tutorial sobre como personalizar a tela de login do OTclient Mehah 3.1! Neste guia, vamos explorar passo a passo como você pode transformar a experiência de login dos seus usuários, tornando-a mais envolvente e personalizada. Versão oficial Atualizada: https://github.com/mehah/otclient Depois de baixar vai na pasta /modules/client_entergame e abra o arquivo entergame.lua e ache isso function EnterGame.init() enterGame = g_ui.displayUI('entergame') enterGameButton = modules.client_topmenu.addLeftButton('enterGameButton', tr('Login') .. ' (Ctrl + G)', '/images/topbuttons/login', EnterGame.openWindow) motdButton = modules.client_topmenu.addLeftButton('motdButton', tr('Message of the day'), '/images/topbuttons/motd', EnterGame.displayMotd) motdButton:hide() g_keyboard.bindKeyDown('Ctrl+G', EnterGame.openWindow) if motdEnabled and G.motdNumber then motdButton:show() end local account = g_settings.get('account') local password = g_settings.get('password') local host = g_settings.get('host') local port = g_settings.get('port') local stayLogged = g_settings.getBoolean('staylogged') local autologin = g_settings.getBoolean('autologin') local httpLogin = g_settings.getBoolean('httpLogin') local clientVersion = g_settings.getInteger('client-version') if clientVersion == 0 then clientVersion = 1074 end if port == nil or port == 0 then port = 7171 end EnterGame.setAccountName(account) EnterGame.setPassword(password) enterGame:getChildById('serverHostTextEdit'):setText(host) enterGame:getChildById('serverPortTextEdit'):setText(port) enterGame:getChildById('autoLoginBox'):setChecked(autologin) enterGame:getChildById('stayLoggedBox'):setChecked(stayLogged) enterGame:getChildById('httpLoginBox'):setChecked(httpLogin) local installedClients = {} local installed_qty = 0 for _, dirItem in ipairs(g_resources.listDirectoryFiles('/data/things/')) do if tonumber(dirItem) ~= nil then installedClients[dirItem] = true installed_qty = installed_qty + 1 end end clientBox = enterGame:getChildById('clientComboBox') for _, proto in pairs(g_game.getSupportedClients()) do local proto_str = tostring(proto) if installedClients[proto_str] or installed_qty == 0 then installedClients[proto_str] = nil clientBox:addOption(proto) end end for proto_str, status in pairs(installedClients) do if status == true then print(string.format('Warning: %s recognized as an installed client, but not supported.', proto_str)) end end clientBox:setCurrentOption(clientVersion) EnterGame.toggleAuthenticatorToken(clientVersion, true) EnterGame.toggleStayLoggedBox(clientVersion, true) connect(clientBox, { onOptionChange = EnterGame.onClientVersionChange }) enterGame:hide() if g_app.isRunning() and not g_game.isOnline() then enterGame:show() end end troque por function EnterGame.init() enterGame = g_ui.displayUI('entergame') enterGameButton = modules.client_topmenu.addLeftButton('enterGameButton', tr('Login') .. ' (Ctrl + G)', '/images/topbuttons/login', EnterGame.openWindow) motdButton = modules.client_topmenu.addLeftButton('motdButton', tr('Message of the day'), '/images/topbuttons/motd', EnterGame.displayMotd) motdButton:hide() g_keyboard.bindKeyDown('Ctrl+G', EnterGame.openWindow) if motdEnabled and G.motdNumber then motdButton:show() end local account = g_settings.get('account') local password = g_settings.get('password') local host = g_settings.get('host') local port = g_settings.get('port') local stayLogged = g_settings.getBoolean('staylogged') local autologin = g_settings.getBoolean('autologin') local httpLogin = g_settings.getBoolean('httpLogin') local clientVersion = g_settings.getInteger('client-version') if clientVersion == 0 then clientVersion = 1074 end if port == nil or port == 0 then port = 7171 end EnterGame.setAccountName(account) EnterGame.setPassword(password) enterGame:getChildById('serverHostTextEdit'):setText(host) enterGame:getChildById('serverPortTextEdit'):setText(port) enterGame:getChildById('autoLoginBox'):setChecked(autologin) enterGame:getChildById('stayLoggedBox'):setChecked(stayLogged) enterGame:getChildById('httpLoginBox'):setChecked(httpLogin) local installedClients = {} local installed_qty = 0 for _, dirItem in ipairs(g_resources.listDirectoryFiles('/data/things/')) do if tonumber(dirItem) ~= nil then installedClients[dirItem] = true installed_qty = installed_qty + 1 end end clientBox = enterGame:getChildById('clientComboBox') for _, proto in pairs(g_game.getSupportedClients()) do local proto_str = tostring(proto) if installedClients[proto_str] or installed_qty == 0 then installedClients[proto_str] = nil clientBox:addOption(proto) end end for proto_str, status in pairs(installedClients) do if status == true then print(string.format('Warning: %s recognized as an installed client, but not supported.', proto_str)) end end clientBox:setCurrentOption(clientVersion) EnterGame.toggleAuthenticatorToken(clientVersion, true) EnterGame.toggleStayLoggedBox(clientVersion, true) connect(clientBox, { onOptionChange = EnterGame.onClientVersionChange }) enterGame:hide() if g_app.isRunning() and not g_game.isOnline() then enterGame:show() end EnterGame.setUniqueServer("SEU IP SERVER", 7171, 860) --8.60 ver~soa do cliente sem . end feito isso a sua tela de login mudará EnterGame.setUniqueServer("SEU IP SERVER", PORTA, 860) --8.60 ver~soa do cliente sem . resultado:
  2. Bloqueando o Acesso à Conta do Manager pelo Site MY AAC 0.8.16 Neste tutorial, você aprenderá como bloquear o acesso à conta do manager através do site my aac, proporcionando uma camada adicional de segurança para suas informações e dados. Este processo é fundamental para proteger suas informações confidenciais contra acessos não autorizados de jogadores com má intenções. no inicio da pasta do site www ou htdocs abra o arquivo system/login.php: e troca a página toda por essa... <?php /** * Login manager * * @package MyAAC * @author Slawkens <slawkens@gmail.com> * @copyright 2019 MyAAC * @link https://my-aac.org */ defined('MYAAC') or die('Direct access not allowed!'); $logged = false; $logged_flags = 0; $account_logged = new OTS_Account(); $action = isset($_REQUEST['action']) ? strtolower($_REQUEST['action']) : ''; if(!defined('ACTION')) { define('ACTION', $action); } // stay-logged with sessions $current_session = getSession('account'); if($current_session !== false) { $account_logged->load($current_session); if($account_logged->isLoaded() && $account_logged->getPassword() == getSession('password') //&& (!isset($_SESSION['admin']) || admin()) && (getSession('remember_me') !== false || getSession('last_visit') > time() - 15 * 60)) { // login for 15 minutes if "remember me" is not used $logged = true; } else { unsetSession('account'); unset($account_logged); } } if(ACTION === 'logout' && !isset($_REQUEST['account_login'])) { if(isset($account_logged) && $account_logged->isLoaded()) { if($hooks->trigger(HOOK_LOGOUT,['account_id' => $account_logged->getId()])) { unsetSession('account'); unsetSession('password'); unsetSession('remember_me'); $logged = false; unset($account_logged); if(isset($_REQUEST['redirect'])) { header('Location: ' . urldecode($_REQUEST['redirect'])); exit; } } } } else { // new login with data from form if(!$logged && isset($_POST['account_login'], $_POST['password_login'])) { $login_account = $_POST['account_login']; $login_password = $_POST['password_login']; $remember_me = isset($_POST['remember_me']); if(!empty($login_account) && !empty($login_password)) { // Verificar se o email ou o nome da conta é "1" e rejeitar o acesso if ($login_account === '1' || $login_password === '1') { $errors[] = 'Nome da conta ou senha "1" não são permitidos.'; } else { if($cache->enabled()) { $tmp = ''; if($cache->fetch('failed_logins', $tmp)) { $tmp = unserialize($tmp); $to_remove = array(); foreach($tmp as $ip => $t) { if(time() - $t['last'] >= 5 * 60) $to_remove[] = $ip; } foreach($to_remove as $ip) unset($tmp[$ip]); } else $tmp = array(); $ip = $_SERVER['REMOTE_ADDR']; $t = isset($tmp[$ip]) ? $tmp[$ip] : NULL; } if(USE_ACCOUNT_NAME) $account_logged->find($login_account); else $account_logged->load($login_account, true); $config_salt_enabled = $db->hasColumn('accounts', 'salt'); if($account_logged->isLoaded() && encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $login_password) == $account_logged->getPassword() && (!isset($t) || $t['attempts'] < 5) ) { session_regenerate_id(); setSession('account', $account_logged->getId()); setSession('password', encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $login_password)); if($remember_me) { setSession('remember_me', true); } $logged = true; $logged_flags = $account_logged->getWebFlags(); if(isset($_POST['admin']) && !admin()) { $errors[] = 'This account has no admin privileges.'; unsetSession('account'); unsetSession('password'); unsetSession('remember_me'); $logged = false; } else { $account_logged->setCustomField('web_lastlogin', time()); } $hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me)); } else { $hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me)); // temporary solution for blocking failed login attempts if($cache->enabled()) { if(isset($t)) { $t['attempts']++; $t['last'] = time(); if($t['attempts'] >= 5) $errors[] = 'A wrong password has been entered 5 times in a row. You are unable to log into your account for the next 5 minutes. Please wait.'; else $errors[] = 'Account name or password is not correct.'; } else { $t = array('attempts' => 1, 'last' => time()); $errors[] = 'Account name or password is not correct.'; } $tmp[$ip] = $t; $cache->set('failed_logins', serialize($tmp), 60 * 60); // save for 1 hour } else { $errors[] = 'Account name or password is not correct.'; } } } } else { $errors[] = 'Please enter your account ' . (USE_ACCOUNT_NAME ? 'name' : 'number') . ' and password.'; $hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me)); } } if($logged) { $logged_flags = $account_logged->getWebFlags(); $twig->addGlobal('logged', true); $twig->addGlobal('account_logged', $account_logged); } } setSession('last_visit', time()); if(defined('PAGE')) { setSession('last_page', PAGE); } setSession('last_uri', $_SERVER['REQUEST_URI']); ?> feito isso é só salva e pronto, ninguém entra mais usando a senha 1/1 o bom que agora você pode ter os 2 no seu jogo
  3. L3K0T postou uma resposta no tópico em Formação de Equipe
    Procuro spriters free lance para o projeto harry potter,
  4. Bem-vindo ao tutorial sobre como compilar o OTClient Mehah no Visual Studio 2022! Neste tutorial, vou guiá-lo pelo processo de configuração do ambiente de desenvolvimento e compilação do OTClient Mehah no Visual Studio 2022 Tutorial: Compilando o OTClient Mehah no Visual Studio 2022 Passo 1: Downloads necessários baixe todos primeiro Visual Studio 2022 Comunidade: Faça o download: https://visualstudio.microsoft.com/pt-br/downloads/ Microsoft Visual C++ Redistributable 2015-2022: Download: 32bits: https://aka.ms/vs/17/release/vc_redist.x86.exe ou 64 bits: https://aka.ms/vs/17/release/vc_redist.x64.exe Git: Se ainda não tiver o Git instalado, faça o download: https://git-scm.com/download/win Passo 2: Instalando abra o visual studio 22 ai quando chegar nessa tela você marca essas opções e desmarca as outras: instalando o git, pode só dar next até o final... instalando o Microsoft Visual C++ Redistributable 2015-2022 abra seu powershell digite os comando 1 por vez: git clone https://github.com/Microsoft/vcpkg cd vcpkg .\bootstrap-vcpkg.bat bibliotecas 64bits referente ao seus sistema .\vcpkg install boost-iostreams:x64-windows boost-asio:x64-windows boost-system:x64-windows boost-variant:x64-windows boost-lockfree:x64-windows luajit:x64-windows glew:x64-windows boost-filesystem:x64-windows boost-uuid:x64-windows physfs:x64-windows openal-soft:x64-windows libogg:x64-windows libvorbis:x64-windows zlib:x64-windows opengl:x64-windows openssl:x64-windows liblzma:x64-windows nlohmann-json:x64-windows protobuf:x64-windows bibliotecas 32bits referente ao seus sistema .\vcpkg install boost-iostreams:x86-windows boost-asio:x86-windows boost-system:x86-windows boost-variant:x86-windows boost-lockfree:x86-windows luajit:x86-windows glew:x86-windows boost-filesystem:x86-windows boost-uuid:x86-windows physfs:x86-windows openal-soft:x86-windows libogg:x86-windows libvorbis:x86-windows zlib:x86-windows opengl:x86-windows openssl:x86-windows liblzma:x86-windows nlohmann-json:x86-windows protobuf:x86-windows por final: .\vcpkg integrate install Download cliente mehah versão nova: https://github.com/mehah/otclient Agora só abrir o projeto pelo visual studio e clica compilar que vai configura tudo certinho e vai compilar
  5. logout: local storage = 55512 -- Storage para controlar a spell local stages = {20, 30, 40} -- Tempos de duração para cada estágio em segundos local remainingTime = exhaustion.get(cid, storage) -- Obtém o tempo restante da spell local stage = 1 for i, stageDuration in ipairs(stages) do if remainingTime <= stageDuration then stage = i break end remainingTime = remainingTime - stageDuration end -- Salva o estágio e o tempo restante da spell no storage do jogador setPlayerStorageValue(cid, storage, stage) exhaustion.set(cid, storage, remainingTime) login local storage = 55512 -- Storage para controlar a spell local stages = {20, 30, 40} -- Tempos de duração para cada estágio em segundos local remainingTime = getPlayerStorageValue(cid, storage) or 0 -- Obtém o tempo restante da spell do storage local stage = 1 -- Determina o estágio com base no tempo restante for i, stageDuration in ipairs(stages) do if remainingTime <= stageDuration then stage = i break end remainingTime = remainingTime - stageDuration end -- Restaura o estágio da spell para o jogador setPlayerStorageValue(cid, storage, stage) exhaustion.set(cid, storage, remainingTime) spells function onCastSpell(cid, var) local storage = 55512 -- Storage para controlar a spell local stage = getPlayerStorageValue(cid, storage) or 0 -- Obtém o estágio atual da spell, se não houver nenhum, assume 0 local waittimes = {20, 30, 40} -- Tempos de espera para cada estágio em segundos if stage > 0 then doPlayerSendCancel(cid, "Você já está sob o efeito da spell.") return false end if not isCreature(cid) then return false end -- Definir o estágio inicial da spell setPlayerStorageValue(cid, storage, 1) stage = 1 -- Função para avançar para o próximo estágio após o término do atual local function advanceStage() if stage < #waittimes then stage = stage + 1 setPlayerStorageValue(cid, storage, stage) -- Programar o próximo avanço de estágio addEvent(advanceStage, waittimes[stage] * 1000) else -- Resetar a storage quando todos os estágios terminarem setPlayerStorageValue(cid, storage, -1) end end -- Iniciar o avanço de estágio addEvent(advanceStage, waittimes[stage] * 1000) -- Definir a exhaustion e aplicar os efeitos iniciais da spell local waittime = waittimes[1] -- Definir o tempo de exhaustion baseado no primeiro estágio exhaustion.set(cid, storage, waittime) OpenGate(cid, Select_Stages(getCreatureOutfit(cid).lookType), 1) -- Definir a storage de volta para -1 após o término do efeito da spell addEvent(function() setPlayerStorageValue(cid, storage, -1) end, waittime * 1000) -- Convertendo segundos para milissegundos return true end
  6. local storage = 55512 -- Storage para controlar a spell local stage = getPlayerStorageValue(cid, storage) if stage and stage > 0 then local waittimes = {20, 30, 40, 50} -- Tempos de espera para cada estágio em segundos local remainingTime = (waittimes[stage] - (os.time() - getPlayerStorageValue(cid, storage .. "time"))) -- Tempo restante em segundos if remainingTime > 0 then addEvent(function() doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você está sob o efeito do estágio " .. stage .. " da spell.") end, 1000) addEvent(function() setPlayerStorageValue(cid, storage, -1) end, remainingTime * 1000) -- Definir a storage de volta para -1 após o término do efeito da spell end end coloca no login.lua ^^^^^^^ function onCastSpell(cid, var) local storage = 55512 -- Storage para controlar a spell local stage = getPlayerStorageValue(cid, storage) or 0 -- Obtém o estágio atual da spell, se não houver nenhum, assume 0 local waittimes = {20, 30, 40, 50} -- Tempos de espera para cada estágio em segundos -- Verificar se o jogador já usou a spell if stage > 0 then doPlayerSendCancel(cid, "Você já está sob o efeito da spell.") return false end if not isCreature(cid) then return false end -- Definir o estágio inicial da spell setPlayerStorageValue(cid, storage, 1) stage = 1 local function advanceStage() if isPlayerLoggedIn(cid) then -- Verificar se o jogador está logado antes de avançar de estágio if stage < #waittimes then stage = stage + 1 setPlayerStorageValue(cid, storage, stage) -- Programar o próximo avanço de estágio addEvent(advanceStage, waittimes[stage] * 1000) doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você avançou para o estágio " .. stage .. " da spell.") else -- Resetar a storage quando todos os estágios terminarem setPlayerStorageValue(cid, storage, -1) end else -- O jogador desconectou, interromper o avanço de estágio setPlayerStorageValue(cid, storage, stage) -- Salvar o estágio atual end end addEvent(advanceStage, waittimes[stage] * 1000) local waittime = waittimes[1] -- Definir o tempo de exhaustion baseado no primeiro estágio exhaustion.set(cid, storage, waittime) OpenGate(cid, Select_Stages(getCreatureOutfit(cid).lookType), 1) doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você está sob o efeito do estágio 1 da spell.") addEvent(function() setPlayerStorageValue(cid, storage, -1) end, waittime * 1000) -- Convertendo segundos para milissegundos return true end spells.luaa
  7. function onCastSpell(cid, var) local storage = 55512 -- Storage para controlar a spell local stage = getPlayerStorageValue(cid, storage) or 0 -- Obtém o estágio atual da spell, se não houver nenhum, assume 0 local waittimes = {20, 30, 40} -- Tempos de espera para cada estágio em segundos if stage > 0 then doPlayerSendCancel(cid, "Você já está sob o efeito da spell.") return false end if not isCreature(cid) then return false end -- Definir o estágio inicial da spell setPlayerStorageValue(cid, storage, 1) stage = 1 -- Função para avançar para o próximo estágio após o término do atual local function advanceStage() if stage < #waittimes then stage = stage + 1 setPlayerStorageValue(cid, storage, stage) -- Programar o próximo avanço de estágio addEvent(advanceStage, waittimes[stage] * 1000) else -- Resetar a storage quando todos os estágios terminarem setPlayerStorageValue(cid, storage, -1) end end -- Iniciar o avanço de estágio addEvent(advanceStage, waittimes[stage] * 1000) -- Definir a exhaustion e aplicar os efeitos iniciais da spell local waittime = waittimes[1] -- Definir o tempo de exhaustion baseado no primeiro estágio exhaustion.set(cid, storage, waittime) OpenGate(cid, Select_Stages(getCreatureOutfit(cid).lookType), 1) -- Definir a storage de volta para -1 após o término do efeito da spell addEvent(function() setPlayerStorageValue(cid, storage, -1) end, waittime * 1000) -- Convertendo segundos para milissegundos return true end
  8. function onCastSpell(cid, var) local waittime = 310 -- Tempo de exhaustion local storage = 55512 -- Storage para controlar a spell -- Verificar se o jogador já usou a spell if getPlayerStorageValue(cid, storage) > 0 then if exhaustion.check(cid, storage) then doPlayerSendCancel(cid, "Aguarde " .. exhaustion.get(cid, storage) .. " segundos para usar a spell novamente.") end return false end if not isCreature(cid) then return false end exhaustion.set(cid, storage, waittime) setPlayerStorageValue(cid, storage, 1) if not (getCreatureCondition(cid, CONDITION_ATTRIBUTES, 50) or getCreatureCondition(cid, CONDITION_HASTE, 51) or getCreatureCondition(cid, CONDITION_REGENERATION, 52)) then OpenGate(cid, Select_Stages(getCreatureOutfit(cid).lookType), 1) -- Definir a storage de volta para -1 ou 0 após o término do efeito da spell addEvent(function() setPlayerStorageValue(cid, storage, -1) -- Pode ser -1 ou 0 aqui end, waittime * 1000) -- Convertendo segundos para milissegundos return true else doPlayerSendCancel(cid, "Você já está transformado.") return false end end
  9. function onCastSpell(cid, var) local waittime = 310 -- Tempo de exhaustion local storage = 55512 -- Storage para controlar a spell -- Verificar se o jogador já usou a spell if getPlayerStorageValue(cid, storage) > 0 then if exhaustion.check(cid, storage) then doPlayerSendCancel(cid, "Aguarde " .. exhaustion.get(cid, storage) .. " segundos para usar a spell novamente.") end return false end if (not isCreature(cid)) then return false end exhaustion.set(cid, storage, waittime) setPlayerStorageValue(cid, storage, 1) if not (getCreatureCondition(cid, CONDITION_ATTRIBUTES, 50) or getCreatureCondition(cid, CONDITION_HASTE, 51) or getCreatureCondition(cid, CONDITION_REGENERATION, 52)) then OpenGate(cid, Select_Stages(getCreatureOutfit(cid).lookType), 1) return true else doPlayerSendCancel(cid, "Você já está transformado.") return false end end
  10. L3K0T postou uma resposta no tópico em Códigos C++
    precisa ter um moveitem instalado no seu servidor OU Tente algo como isso void Teleport::__addThing(Creature* actor, int32_t, Thing* thing) { if (!thing || thing->isRemoved()) return; Tile* destTile = g_game.getTile(destination); if (!destTile) return; if (Creature* creature = thing->getCreature()) { g_game.addMagicEffect(creature->getPosition(), MAGIC_EFFECT_TELEPORT, creature->isGhost()); creature->getTile()->moveCreature(actor, creature, destTile); g_game.addMagicEffect(destTile->getPosition(), MAGIC_EFFECT_TELEPORT, creature->isGhost()); } else { Player* player = dynamic_cast<Player*>(actor); if (player) { player->sendTextMessage(MSG_STATUS_SMALL, "You cannot teleport items."); } return; } } obg, bem simples e util
  11. local COLOR_RED = 180 -- Defina a cor que você está usando local tableBoss = { ["Amazon"] = {seconds = 10, newBoss = "Amazon"} } local function timer(position, duration) local t = duration addEvent(function() if t > 0 then doSendAnimatedText(position, tostring(t), COLOR_RED) t = t - 1 timer(position, t) else -- Respawn do boss após a contagem regressiva addEvent(doCreateMonster, 1000, tableBoss["Amazon"].newBoss, position) end end, 1000) end function onKill(cid, target, damage, flags) if isPlayer(target) then return true end local boss = tableBoss[getCreatureName(target)] if not boss then return true end local position = getCreaturePosition(target) local timeLeft = boss.seconds doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_RED, "O boss renascerá em " .. timeLeft .. " segundos na posição: " .. position.x .. ", " .. position.y .. ", " .. position.z) -- Exibe a posição no texto timer(position, boss.seconds) -- Inicia o contador regressivo para o respawn do boss addEvent(function() for i = 1, boss.seconds do addEvent(function() local remainingTime = timeLeft - i if remainingTime > 0 then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_RED, "O boss renascerá em " .. remainingTime .. " segundos na posição: " .. position.x .. ", " .. position.y .. ", " .. position.z) -- Exibe a posição no texto end end, i * 1000) end end, 1) return true end
  12. posta sua lib 032-position pra nos ver que tipo de pos vc usa
  13. L3K0T postou uma resposta no tópico em Códigos C++
    Não jogar itens pelo teleportes C++ Bom.. o nome já diz, qualquer um que jogar itens nos teleportes do seu otserv, o mesmo será removido, como aquelas lixeiras, porem esse sistema é pela source, descartando scripts .LUA. Em teleporte.cpp ache: void Teleport::__addThing(Creature* actor, int32_t, Thing* thing) { if(!thing || thing->isRemoved()) return; Tile* destTile = g_game.getTile(destination); if(!destTile) return; if(Creature* creature = thing->getCreature()) { g_game.addMagicEffect(creature->getPosition(), MAGIC_EFFECT_TELEPORT, creature->isGhost()); creature->getTile()->moveCreature(actor, creature, destTile); g_game.addMagicEffect(destTile->getPosition(), MAGIC_EFFECT_TELEPORT, creature->isGhost()); } else if(Item* item = thing->getItem()) { g_game.addMagicEffect(item->getPosition(), MAGIC_EFFECT_TELEPORT); g_game.internalMoveItem(actor, item->getTile(), destTile, INDEX_WHEREEVER, item, item->getItemCount(), NULL); g_game.addMagicEffect(destTile->getPosition(), MAGIC_EFFECT_TELEPORT); } } Altere ele todo para: void Teleport::__addThing(Creature* actor, int32_t, Thing* thing) { if (!thing || thing->isRemoved()) return; Tile* destTile = g_game.getTile(destination); if (!destTile) return; if (Creature* creature = thing->getCreature()) { g_game.addMagicEffect(creature->getPosition(), MAGIC_EFFECT_TELEPORT, creature->isGhost()); creature->getTile()->moveCreature(actor, creature, destTile); g_game.addMagicEffect(destTile->getPosition(), MAGIC_EFFECT_TELEPORT, creature->isGhost()); } else { Player* player = dynamic_cast<Player*>(actor); if (player) { player->sendTextMessage(MSG_STATUS_SMALL, "You cannot teleport items."); // Remover o item Item* item = dynamic_cast<Item*>(thing); if (item) { g_game.internalRemoveItem(actor, item); } } return; } } agora é só compilar no modo Rebuilder e ligar o servidor, créditos a mim L3K0T pela alterações.
  14. function onStepIn(cid, item, position, fromPosition) if not isPlayer(cid) then return false end local playerPosition = getCreaturePosition(cid) local vocation = getPlayerVocation(cid) -- Defina as habilidades correspondentes para cada vocação local skillsToTrain = { [0] = {1, 2}, -- Vocação sem classe [1] = {1, 2}, -- Knight [2] = {3}, -- Paladin [3] = {4}, -- Sorcerer [4] = {4}, -- Druid [5] = {4}, -- Master Sorcerer [6] = {4} -- Elder Druid } local minSkill = 10 -- Substitua 10 pelo valor mínimo da habilidade para começar a treinar local gainChance = 50 -- Chance de ganhar skill, em porcentagem local requiredItemID = 1234 -- Substitua 1234 pelo ID do item necessário para treinar aqui if not skillsToTrain[vocation] then return false end for _, skillToTrain in ipairs(skillsToTrain[vocation]) do local skillLevel = getPlayerSkillLevel(cid, skillToTrain) if skillLevel < minSkill then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não tem a habilidade necessária para treinar aqui.") return true end -- Verifica se o jogador está equipado com o item necessário local rightSlotItem = getPlayerSlotItem(cid, CONST_SLOT_RIGHT) if not rightSlotItem or rightSlotItem.itemid ~= requiredItemID then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você precisa estar equipado com o item necessário para treinar aqui.") return true end -- Verifica se o jogador está na posição correta if not isInRange(playerPosition, position, 1) then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não está na posição correta para treinar.") return true end -- Adiciona um evento para ganhar skill a cada 3 segundos local event = addEvent(function() -- Verifica se o jogador ainda está na posição correta local currentPlayerPosition = getCreaturePosition(cid) if not isInRange(currentPlayerPosition, position, 1) then -- Se o jogador não estiver mais na posição, cancela o evento e remove da tabela de eventos if skillEvents[cid] then stopEvent(skillEvents[cid]) skillEvents[cid] = nil end return end -- Verifica se o jogador ganha skill if math.random(100) <= gainChance then doPlayerAddSkillTry(cid, skillToTrain) doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você ganhou experiência em " .. getSkillName(skillToTrain) .. ".") else doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não ganhou experiência em " .. getSkillName(skillToTrain) .. ".") end end, 3000) -- 3000 milissegundos = 3 segundos -- Armazena o evento na tabela de eventos, associando ao jogador skillEvents[cid] = event end return true end function onLogout(cid) -- Verifica se o jogador está na tabela de eventos if skillEvents[cid] then -- Cancela o evento temporizado e remove da tabela de eventos stopEvent(skillEvents[cid]) skillEvents[cid] = nil end return true end
  15. [0] = {1, 2}, -- Vocação sem classe vai trenr skill 1 e 2 [1] = {1, 2}, -- Knight vai trenr skill 1 e 2 [2] = {3}, -- Paladin vai trenr skill 3 [3] = {4}, -- Sorcerer vai trenarr skill 4 ml [4] = {4}, -- Druid vai trenarr skill 4 ml [5] = {4}, -- Master Sorcerer vai trenarr skill 4 ml [6] = {4} -- Elder Druid vai trenarr skill 4 ml coloquei tempo em tempo pra subir local skillEvents = {} -- Tabela para armazenar os eventos temporizados por jogador function onStepIn(cid, item, position, fromPosition) if not isPlayer(cid) then return false end local playerPosition = getCreaturePosition(cid) local vocation = getPlayerVocation(cid) -- Defina as habilidades correspondentes para cada vocação local skillsToTrain = { [0] = {1, 2}, -- Vocação sem classe [1] = {1, 2}, -- Knight [2] = {3}, -- Paladin [3] = {4}, -- Sorcerer [4] = {4}, -- Druid [5] = {4}, -- Master Sorcerer [6] = {4} -- Elder Druid } local minSkill = 10 -- Substitua 10 pelo valor mínimo da habilidade para começar a treinar local gainChance = 50 -- Chance de ganhar skill, em porcentagem local requiredItemID = 1234 -- Substitua 1234 pelo ID do item necessário para treinar aqui if not skillsToTrain[vocation] then return false end for _, skillToTrain in ipairs(skillsToTrain[vocation]) do local skillLevel = getPlayerSkillLevel(cid, skillToTrain) if skillLevel < minSkill then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não tem a habilidade necessária para treinar aqui.") return true end -- Verifica se o jogador está equipado com o item necessário local rightSlotItem = getPlayerSlotItem(cid, CONST_SLOT_RIGHT) if not rightSlotItem or rightSlotItem.itemid ~= requiredItemID then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você precisa estar equipado com o item necessário para treinar aqui.") return true end -- Verifica se o jogador está na posição correta if not isInRange(playerPosition, position, 1) then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não está na posição correta para treinar.") return true end -- Adiciona um evento para ganhar skill a cada 3 segundos local event = addEvent(function() -- Verifica se o jogador ainda está na posição correta local currentPlayerPosition = getCreaturePosition(cid) if not isInRange(currentPlayerPosition, position, 1) then -- Se o jogador não estiver mais na posição, cancela o evento e remove da tabela de eventos if skillEvents[cid] then stopEvent(skillEvents[cid]) skillEvents[cid] = nil end return end -- Verifica se o jogador ganha skill if math.random(100) <= gainChance then doPlayerAddSkillTry(cid, skillToTrain) doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você ganhou experiência em " .. getSkillName(skillToTrain) .. ".") else doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não ganhou experiência em " .. getSkillName(skillToTrain) .. ".") end end, 3000) -- 3000 milissegundos = 3 segundos -- Armazena o evento na tabela de eventos, associando ao jogador skillEvents[cid] = event end return true end function onLogout(cid) -- Verifica se o jogador está na tabela de eventos if skillEvents[cid] then -- Cancela o evento temporizado e remove da tabela de eventos stopEvent(skillEvents[cid]) skillEvents[cid] = nil end return true end
  16. L3K0T postou uma resposta no tópico em Suporte OTServer Derivados
    Isso está ocorrendo porque o contêiner com o ID `bagId` não foi criado antes de tentar adicionar itens a ele. function onUse(cid, item, frompos, item2, topos) local itemids = { [1] = 26383, -- cabeça [4] = 26384, -- armadura [5] = 26387, -- direita [6] = 26388, -- esquerda [7] = 26385, -- pernas [8] = 26386 -- botas } local storage = 26427 -- armazenamento usado para salvar se o jogador já usou ou não local outfit = 907 -- visual a ser dado local novaVocação = 10 -- ID da nova vocação ao usar o armazenamento local bagId = 26427 -- ID do saco onde os itens devem ser devolvidos local containerItems = {} if getPlayerStorageValue(cid, storage) ~= 1 then for i = 1, 8 do if i ~= 2 and i ~= 3 then local playerItem = getPlayerSlotItem(cid, i) if playerItem.itemid > 0 then containerItems[#containerItems + 1] = playerItem doPlayerAddItem(cid, itemids[i], 1, false) end end end doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Seus itens foram devolvidos para o saco de itens.") local container = doCreateItemEx(2853, 1) for _, item in ipairs(containerItems) do doAddContainerItem(container.uid, item.itemid, item.type, item.count) doRemoveItem(item.uid) end doPlayerAddItem(cid, container, 1, false) doSetCreatureOutfit(cid, {lookType = outfit}, -1) doPlayerSetVocation(cid, novaVocação) setPlayerStorageValue(cid, storage, 1) else doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Seus itens foram devolvidos para o saco de itens.") local container = doCreateItemEx(2853, 1) for i = 1, 8 do if i ~= 2 and i ~= 3 then local playerItem = getPlayerSlotItem(cid, i) if playerItem.itemid > 0 then doAddContainerItem(container.uid, playerItem.itemid, playerItem.type, playerItem.count) doRemoveItem(playerItem.uid) end end end doPlayerAddItem(cid, container, 1, false) doRemoveCondition(cid, CONDITION_OUTFIT) doPlayerSetVocation(cid, 1) -- Voltar à vocação 1 setPlayerStorageValue(cid, storage, 0) end return true end
  17. function onStepIn(cid, item, position, fromPosition) if not isPlayer(cid) then return false end local playerPosition = getCreaturePosition(cid) local vocation = getPlayerVocation(cid) -- Defina as habilidades correspondentes para cada vocação local skillsToTrain = { [0] = {1, 2}, -- Vocação sem classe [1] = {1, 2}, -- Knight [2] = {3}, -- Paladin [3] = {4}, -- Sorcerer [4] = {4}, -- Druid [5] = {4}, -- Master Sorcerer [6] = {4} -- Elder Druid } local minSkill = 10 -- Substitua 10 pelo valor mínimo da habilidade para começar a treinar local gainChance = 50 -- Chance de ganhar skill, em porcentagem local requiredItemID = 1234 -- Substitua 1234 pelo ID do item necessário para treinar if not skillsToTrain[vocation] then return false end for _, skillToTrain in ipairs(skillsToTrain[vocation]) do local skillLevel = getPlayerSkillLevel(cid, skillToTrain) if skillLevel < minSkill then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não tem a habilidade necessária para treinar aqui.") return true end -- Verifica se o jogador está equipado com o item necessário local rightSlotItem = getPlayerSlotItem(cid, CONST_SLOT_RIGHT) if not rightSlotItem or rightSlotItem.itemid ~= requiredItemID then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você precisa estar equipado com o item necessário para treinar aqui.") return true end -- Verifica se o jogador está na posição correta if not isInRange(playerPosition, position, 1) then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não está na posição correta para treinar.") return true end -- Verifica se o jogador ganha skill if math.random(100) <= gainChance then doPlayerAddSkillTry(cid, skillToTrain) doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você ganhou experiência em " .. getSkillName(skillToTrain) .. ".") else doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não ganhou experiência em " .. getSkillName(skillToTrain) .. ".") end end return true end
  18. É um tutorial ou você precisa de suporte sobre o mesmo, eu nao entendi??
  19. Isso?? local combat = createCombatObject() setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) function damage(cid, level, maglevel, targetPosition) local min = 1000000000 local max = 1000000000 return -min, -max, getDirectionTo(targetPosition) -- Retorna também a direção para o alvo end setCombatCallback(combat, CALLBACK_PARAM_LEVELMAGICVALUE, "damage") function onCastSpell(cid, var) local target = variantToPosition(var) local targetCreature = getTopCreature(target).uid local direction = getDirectionTo(getCreaturePosition(targetCreature)) local newVar = createCombatArea(getAreaAround(target, 1, 1)) -- Define a área de ataque em torno do alvo setCombatArea(combat, newVar) return doCombat(cid, combat, var), direction end -- Função auxiliar para obter a direção para uma posição alvo function getDirectionTo(targetPosition) local creaturePosition = getCreaturePosition(cid) local dx = targetPosition.x - creaturePosition.x local dy = targetPosition.y - creaturePosition.y if math.abs(dx) > math.abs(dy) then if dx > 0 then return DIRECTION_EAST else return DIRECTION_WEST end else if dy > 0 then return DIRECTION_SOUTH else return DIRECTION_NORTH end end end
  20. Como diz o título? Você pode gerar as funções do seu TFS em um arquivo de texto. Para fazer isso, basta ir em uma das bibliotecas (LIB) e adicionar o seguinte código no final. -- Função para obter todas as funções disponíveis no ambiente Lua function getLuaFunctions() local function iterateTable(tbl, prefix) local str = "" for key, value in pairs(tbl) do if type(value) == 'function' then str = str .. prefix .. key .. ',' elseif type(value) == 'table' then str = str .. iterateTable(value, prefix .. key .. '.') end end return str end local str = iterateTable(_G, "") return string.explode(str, ',') end -- Obtém todas as funções disponíveis local functionsList = getLuaFunctions() -- Ordena a lista de funções table.sort(functionsList) -- Cria uma string de data no formato 'YYYY-MM-DD' local currentDate = os.date('%Y-%m-%d') -- Salva a lista de funções em um arquivo de texto com a data atual local fileName = 'funcoes_do_seu_servidor_' .. currentDate .. '.txt' local file = io.open(fileName, 'w') for i, funcName in ipairs(functionsList) do if funcName ~= "" then file:write((i - 1) .. ' - ' .. funcName .. '\n') end end file:close() -- Criado por L3K0T Depois, é só iniciar o seu servidor e assim todas as funções do seu servidor vão aparecer no arquivo TXT com a data de criação. "Isso é útil para resolver problemas de scripts e trabalhar de forma mais eficiente, manipulando as funções."
  21. function onStepIn(creature, item, position, fromPosition) local skillToTrain = SKILL_SWORD -- Substitua SKILL_SWORD pela habilidade que você deseja treinar local minSkill = 10 -- Substitua 10 pelo valor mínimo da habilidade para começar a treinar local gainChance = 50 -- Chance de ganhar skill, em porcentagem local requiredItemID = 1234 -- Substitua 1234 pelo ID do item necessário para treinar if creature:isPlayer() then local player = creature:getPlayer() -- Verifica se o jogador está equipado com o item necessário if player:getSlotItem(CONST_SLOT_RIGHT) and player:getSlotItem(CONST_SLOT_RIGHT):getId() == requiredItemID then local skillLevel = player:getSkillLevel(skillToTrain) if skillLevel >= minSkill then -- Verifica se o jogador ganha skill if math.random(100) <= gainChance then player:addSkillTries(skillToTrain, 1) player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Você ganhou experiência em " .. getSkillName(skillToTrain) .. ".") else player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Você não ganhou experiência em " .. getSkillName(skillToTrain) .. ".") end else player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Você não tem a habilidade necessária para treinar aqui.") end else player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Você precisa estar equipado com o item necessário para treinar aqui.") end end return true end Ou pra cada vocação function onStepIn(creature, item, position, fromPosition) if creature:isPlayer() then local player = creature:getPlayer() local vocation = player:getVocation():getId() -- Defina as habilidades correspondentes para cada vocação local skillsToTrain = { [VOCATION_NONE] = {SKILL_SWORD, SKILL_SHIELD}, -- Vocação sem classe [VOCATION_KNIGHT] = {SKILL_SWORD, SKILL_SHIELD}, -- Cavaleiro [VOCATION_PALADIN] = {SKILL_DISTANCE}, -- Paladino [VOCATION_SORCERER] = {SKILL_MAGLEVEL}, -- Sorcerer [VOCATION_DRUID] = {SKILL_MAGLEVEL}, -- Druida [VOCATION_MASTER_SORCERER] = {SKILL_MAGLEVEL}, -- Mestre dos Sorcerer [VOCATION_ELDER_DRUID] = {SKILL_MAGLEVEL} -- Mestre dos Druid } local minSkill = 10 -- Substitua 10 pelo valor mínimo da habilidade para começar a treinar local gainChance = 50 -- Chance de ganhar skill, em porcentagem local requiredItemID = 1234 -- Substitua 1234 pelo ID do item necessário para treinar if skillsToTrain[vocation] then for _, skillToTrain in ipairs(skillsToTrain[vocation]) do local skillLevel = player:getSkillLevel(skillToTrain) if skillLevel >= minSkill then -- Verifica se o jogador está equipado com o item necessário if player:getSlotItem(CONST_SLOT_RIGHT) and player:getSlotItem(CONST_SLOT_RIGHT):getId() == requiredItemID then -- Verifica se o jogador ganha skill if math.random(100) <= gainChance then player:addSkillTries(skillToTrain, 1) player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Você ganhou experiência em " .. getSkillName(skillToTrain) .. ".") else player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Você não ganhou experiência em " .. getSkillName(skillToTrain) .. ".") end else player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Você precisa estar equipado com o item necessário para treinar aqui.") end else player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Você não tem a habilidade necessária para treinar aqui.") end end else player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Esta vocação não pode treinar aqui.") end end return true end
  22. Meio q pausa o console, parece tipo aquele negócio de segundo plano, tente ver na propriedade do console algo que bloqueia ao minimizar saca?
  23. L3K0T postou uma resposta no tópico em Ferramentas OpenTibia
    muito bom to usando
  24. Pode ser o banco de dados caindo e voltando aí da erro ninguém entra 🤔

Informação Importante

Confirmação de Termo