Histórico de Curtidas
-
MatCollier deu reputação a EddyHavoc em [TUTORIAL] [UBUNTU] Como gerar e configurar uma nova chave RSA[TUTORIAL] [UBUNTU] Como gerar e configurar uma nova chave RSA
Este tutorial pode ser útil para você deixar o uso obrigatório do seu client customizado para o seu servidor.
Para seguir este tutorial você precisará ter o OpenSSL instalado.
Consultando se o seu sistema já tem OpenSSL
Gerando a chave RSA
Primeiramente, vamos gerar uma nova chave RSA exclusiva
Assim que gerado, será criado um arquivo "key.pem" no diretório em que você está, esta será a sua chave RSA.
Execute agora o seguinte comando
Após executado o comando acima, será criado um arquivo "public.pem" neste mesmo diretório. Esta é a sua RSA pública.
Precisamos agora converter a chave RSA publica em hexadecimal para decimal, somente desta forma será aceito no Servidor e no OTClient.
Antes de tudo será necessário tratar a RSA pública, portando execute os comandos abaixo:
Após executar o comando acima o terminal deve printar algo como isso:
Em seguida execute o comando abaixo:
Após executar o comando acima o terminal deve printar algo como isso:
Agora para realizar a conversão de Hex para Decimal utilize o seguinte site: Hexadecimal to Decimal Converter (rapidtables.com)
A sua RSA deve ter obrigatoriamente 309 caracteres.
Configurando a Chave RSA no OTClient
Agora entre no seguinte caminho modules/gamelib/ do OTClient e abra o arquivo const.lua
Procure por OTSERV_RSA, você encontrará algo como isto:
Apague e insira a sua chave RSA pública já em Decimal, quando inserir indico deixar tudo em uma linha, como exemplo abaixo:
Não é necessário mexer na CIPSOFT_RSA.
Configurando a Chave RSA no Servidor
Substitua o seu novo arquivo gerado key.pem pelo mesmo arquivo localizado na pasta do seu servidor.
Considerações Finais
Pronto! Melhoria concluída com sucesso!
Após isso só será possível efetuar login em seu servidor com um client que tem a sua RSA pública configurada.
Créditos:
@Cjaker
Sun
Marcos Pacheco
@Breno Alves
@EddyHavoc
@Cat
-
MatCollier recebeu reputação de Cat em Cliente 11 atualizado novas sprites 12 funcionando@JZDJ Irmão, o cliente é ótimo, porém ele tem o bug dos itens aparecerem sem nome no Market (não é o item.otb, é o client, porque usando client 11.49 ou 11.44 com sprites até o 11.90, ou até mesmo o client 12, funciona normal).
Saberia como resolver esse problema do market sem os nomes? Rep+ de qualquer forma
-
MatCollier deu reputação a WooX em [TFS 1.2] Log de Erro da Distro?Você precisa iniciar a distro com o gdb pra pegar o log de crash.
apt-get install gdb gdb ./tfs run Você também pode fazer um script bash pra sempre iniciar a distro com o gdb, ai em caso de crash você sempre vai ter um log disponível.
-
MatCollier deu reputação a WooX em [TFS 1.2] Checar se o player pode abrir corpo (em lua)Há alguns dias atrás outra pessoa teve esta mesma duvida em um servidor de Estudo de Lua no Discord que participo, porem ele estava usando TFS 0.x. A solução que ele encontrou foi adicionar um atributo ao corpo que contém quem deu o ultimo dano e em casos de party, adiciona uma lista dos jogadores na party. Ele precisava verificar isso em uma action (acho que ele estava fazendo algum tipo de Auto-Loot), vou deixar uma imagem do código final que ele me enviou. Talvez para TFS 1.x exista uma solução bem mais simples, mas eu desconheço.
-
MatCollier deu reputação a Pedro. em Nakjila Layout 1xValeu mat, qualquer parada tô aqui p te ajudar.
Gesior, mas da pra adapta-lo pra qualquer AAC.
-
MatCollier recebeu reputação de Pedro. em Nakjila Layout 1x@Yinz Absurdo demais! Layout muito lindo. Vou tentar adaptar ele ao meu site pra utilizar. REP+++
-
MatCollier deu reputação a Pedro. em Nakjila Layout 1xOlá, tava olhando aqui um antigo HD que por acaso não estava funcionando e acabei conseguindo recuperar algumas coisas, então como estou afastado do forum estarei disponibilizando aqui.
Version: TFS 1x+
Download:
Nakjila
Virustotal:
AQUI
Images:
-
MatCollier deu reputação a Pedro. em Envy Layout TFS 1xLet the world explode.
Envy.rar
Scan
https://www.virustotal.com/pt/file/907d2
-
MatCollier deu reputação a Pedro. em GODLike Layout 1xOlá, tava olhando aqui um antigo HD que por acaso não estava funcionando e acabei conseguindo recuperar algumas coisas, então como estou afastado do forum estarei disponibilizando aqui.
Version: TFS 1x+
Download:
GODLike
Virustotal:
AQUI
Images:
-
MatCollier deu reputação a Mathias Kenfi em [TFS 1.2] Setar action id com a função addItemA uid é o doPlayerADDItem
-
MatCollier recebeu reputação de Mathias Kenfi em [TFS 1.2] Setar action id com a função addItem@Coltera @Joaovettor Deu certo!!!
Muito obrigado caras!!!
REP +
-
MatCollier deu reputação a Coltera em [TFS 1.2] Setar action id com a função addItem@MatCollier Eu testei e ta funcionando, tenta desta forma:
local item = player:addItem(2086, 1) item:setActionId(1000)
-
MatCollier deu reputação a Mathias Kenfi em [TFS 1.2] Setar action id com a função addItemTente usar essa função
doSetItemActionId(uid, actionId)
-
MatCollier deu reputação a luanluciano93 em [TFS 1.2] Lucky Clover Amulet
-
MatCollier deu reputação a luanluciano93 em [TFS 1.2] Lucky Clover AmuletResultado sobre o que pesquisei ...
Em data/events/scripts/monster.lua tem uma função que pelo que me parece gera o loot do monstro:
function Monster:onDropLoot(corpse) if configManager.getNumber(configKeys.RATE_LOOT) == 0 then return end local player = Player(corpse:getCorpseOwner()) local mType = self:getType() if not player or player:getStamina() > 840 then local monsterLoot = mType:getLoot() for i = 1, #monsterLoot do local item = corpse:createLootItem(monsterLoot[i]) if not item then print('[Warning] DropLoot:', 'Could not add loot item to corpse.') end end if player then local text = ("Loot of %s: %s"):format(mType:getNameDescription(), corpse:getContentDescription()) local party = player:getParty() if party then party:broadcastPartyLoot(text) else player:sendTextMessage(MESSAGE_LOOT, text) end end else local text = ("Loot of %s: nothing (due to low stamina)"):format(mType:getNameDescription()) local party = player:getParty() if party then party:broadcastPartyLoot(text) else player:sendTextMessage(MESSAGE_LOOT, text) end end end Existe um parte nele que usa a função corpse:createLootItem(monsterLoot), ou seja a função createLootItem que esta em data/lib/core/container.lua:
function Container.createLootItem(self, item) if self:getEmptySlots() == 0 then return true end local itemCount = 0 local randvalue = getLootRandom() if randvalue < item.chance then if ItemType(item.itemId):isStackable() then itemCount = randvalue % item.maxCount + 1 else itemCount = 1 end end if itemCount > 0 then local tmpItem = self:addItem(item.itemId, math.min(itemCount, 100)) if not tmpItem then return false end if tmpItem:isContainer() then for i = 1, #item.childLoot do if not tmpItem:createLootItem(item.childLoot[i]) then tmpItem:remove() return false end end end if item.subType ~= -1 then tmpItem:setAttribute(ITEM_ATTRIBUTE_CHARGES, item.subType) end if item.actionId ~= -1 then tmpItem:setActionId(item.actionId) end if item.text and item.text ~= "" then tmpItem:setText(item.text) end end return true end Você poderia usar esta linha:
if randvalue < item.chance then Para aumentar a chance do item se tiver com o uso do amuleto.
-
MatCollier deu reputação a luanluciano93 em [TFS 1.2] Função getCorpseOwner em Lualocal corpse = Tile(target:getPosition()):getTopDownItem() if not corpse or not corpse:isContainer() then return false end if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == player:getId() then return true end
-
MatCollier recebeu reputação de Pedriinz em Auto Loot Sytem for TFS 1.3 + revscripts@Pedriinz Você é um monstro! Pegou com o rewardboss aqui sem dar crash. Muito obrigado.
Rep+
-
MatCollier deu reputação a Pedriinz em Auto Loot Sytem for TFS 1.3 + revscriptsDepois de milhões de anos sem programar porcaria nenhuma... Eu desenvolvi este sistema como um método de estudo. (C++)
Este sistema foi inspirado no Auto Loot System por @psychonaut. (OTland)
Criei o mesmo na versão mais recente do tfs.
Auto Loot System for TFS 1.3
Como funciona?
Simples, quando você mata um monstro e abre o corpo (você precisa clicar no corpo), os itens vão para o seu personagem.
Instalando
em actions.cpp, encontre:
if (corpseOwner != 0 && !player->canOpenCorpse(corpseOwner)) { return RETURNVALUE_YOUARENOTTHEOWNER; } e mude isso para:
if (corpseOwner != 0 && !player->canOpenCorpse(corpseOwner)) { return RETURNVALUE_YOUARENOTTHEOWNER; } else { if (player->canOpenCorpse(corpseOwner) && player->autoLootList.size() != 0) { if (player->getCapacity() > 100 * 100) { //Minimum of Capacity for autoloot works. (100 CAP) for (Item* item : container->getItemList()) { if (player->getItemFromAutoLoot(item->getID())) { std::ostringstream msgAutoLoot; msgAutoLoot << "You looted a " << item->getItemCount() << "x " << item->getName() << "."; g_game.internalMoveItem(container, player, CONST_SLOT_WHEREEVER, item, item->getItemCount(), nullptr); player->sendTextMessage(MESSAGE_INFO_DESCR, msgAutoLoot.str()); } } } else { player->sendTextMessage(MESSAGE_INFO_DESCR, "Sorry, you don't have enough capacity to use auto loot, so it has been disabled. (100+ capacity is required)"); } } } em player.h, abaixo de:
std::unordered_set<uint32_t> VIPList; adicione isso:
std::set<uint32_t> autoLootList; ainda em player.h encontre:
bool hasLearnedInstantSpell(const std::string& spellName) const; adicione em baixo:
void addItemToAutoLoot(uint16_t itemId); void removeItemFromAutoLoot(uint16_t itemId); bool getItemFromAutoLoot(uint16_t itemId); em player.cpp no final do arquivo, adicione:
void Player::addItemToAutoLoot(uint16_t itemId) { autoLootList.insert(itemId); } void Player::removeItemFromAutoLoot(uint16_t itemId) { autoLootList.erase(itemId); } bool Player::getItemFromAutoLoot(const uint16_t itemId) { return autoLootList.find(itemId) != autoLootList.end(); } em luascript.cpp encontre:
registerMethod("Player", "getFightMode", LuaScriptInterface::luaPlayerGetFightMode); e adicione em baixo:
registerMethod("Player", "addItemToAutoLoot", LuaScriptInterface::luaPlayerAddItemToAutoLoot); registerMethod("Player", "removeItemFromAutoLoot", LuaScriptInterface::luaPlayerRemoveItemFromAutoLoot); registerMethod("Player", "getItemFromAutoLoot", LuaScriptInterface::luaPlayerGetItemFromAutoLoot); registerMethod("Player", "getAutoLootList", LuaScriptInterface::luaPlayerGetAutoLootList); ainda em luascript.cpp encontre essa função:
int LuaScriptInterface::luaPlayerGetFightMode(lua_State* L) { // player:getFightMode() Player* player = getUserdata<Player>(L, 1); if (player) { lua_pushnumber(L, player->fightMode); } else { lua_pushnil(L); } return 1; }
abaixo dela, adicione:
int LuaScriptInterface::luaPlayerAddItemToAutoLoot(lua_State* L) { // player:addItemToAutoLoot(itemId) Player* player = getUserdata<Player>(L, 1); if (!player) { lua_pushnil(L); return 1; } uint16_t itemId; if (isNumber(L, 2)) { itemId = getNumber<uint16_t>(L, 2); } else { itemId = Item::items.getItemIdByName(getString(L, 2)); if (itemId == 0) { lua_pushnil(L); return 1; } } player->addItemToAutoLoot(itemId); pushBoolean(L, true); return 1; } int LuaScriptInterface::luaPlayerRemoveItemFromAutoLoot(lua_State* L) { // player:removeItemFromAutoLoot(itemId) Player* player = getUserdata<Player>(L, 1); if (!player) { lua_pushnil(L); return 1; } uint16_t itemId; if (isNumber(L, 2)) { itemId = getNumber<uint16_t>(L, 2); } else { itemId = Item::items.getItemIdByName(getString(L, 2)); if (itemId == 0) { lua_pushnil(L); return 1; } } player->removeItemFromAutoLoot(itemId); pushBoolean(L, true); return 1; } int LuaScriptInterface::luaPlayerGetItemFromAutoLoot(lua_State* L) { // player:getItemFromAutoLoot(itemId) Player* player = getUserdata<Player>(L, 1); if (!player) { lua_pushnil(L); return 1; } uint16_t itemId; if (isNumber(L, 2)) { itemId = getNumber<uint16_t>(L, 2); } else { itemId = Item::items.getItemIdByName(getString(L, 2)); if (itemId == 0) { lua_pushnil(L); return 1; } } if (player->getItemFromAutoLoot(itemId)) { pushBoolean(L, true); } else { pushBoolean(L, false); } return 1; } int LuaScriptInterface::luaPlayerGetAutoLootList(lua_State* L) { // player:getAutoLootList() Player* player = getUserdata<Player>(L, 1); if (player) { std::set<uint32_t> value = player->autoLootList; if (value.size() == 0) { lua_pushnil(L); return 1; } int index = 0; lua_createtable(L, value.size(), 0); for(auto i : value) { lua_pushnumber(L, i); lua_rawseti(L, -2, ++index); } } else { lua_pushnil(L); } return 1; }
em luascript.h encontre:
static int luaPlayerGetFightMode(lua_State* L);
adicione a baixo:
static int luaPlayerAddItemToAutoLoot(lua_State* L); static int luaPlayerRemoveItemFromAutoLoot(lua_State* L); static int luaPlayerGetItemFromAutoLoot(lua_State* L); static int luaPlayerGetAutoLootList(lua_State* L);
em iologindata.cpp encontre:
//load storage map query.str(std::string()); query << "SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = " << player->getGUID(); if ((result = db.storeQuery(query.str()))) { do { player->addStorageValue(result->getNumber<uint32_t>("key"), result->getNumber<int32_t>("value"), true); } while (result->next()); }
e adicione em baixo:
query.str(std::string()); query << "SELECT `autoloot_list` FROM `player_autoloot` WHERE `player_id` = " << player->getGUID(); if ((result = db.storeQuery(query.str()))) { unsigned long lootlistSize; const char* autolootlist = result->getStream("autoloot_list", lootlistSize); PropStream propStreamList; propStreamList.init(autolootlist, lootlistSize); int16_t value; int16_t item = propStreamList.read<int16_t>(value); while (item) { player->addItemToAutoLoot(value); item = propStreamList.read<int16_t>(value); } }
acima de:
//save inbox items adicione:
query.str(std::string()); query << "DELETE FROM `player_autoloot` WHERE `player_id` = " << player->getGUID(); if (!db.executeQuery(query.str())) { return false; } PropWriteStream propWriteStreamAutoLoot; for (auto i : player->autoLootList) { propWriteStreamAutoLoot.write<uint16_t>(i); } size_t lootlistSize; const char* autolootlist = propWriteStreamAutoLoot.getStream(lootlistSize); query.str(std::string()); DBInsert autolootQuery("INSERT INTO `player_autoloot` (`player_id`, `autoloot_list`) VALUES "); query << player->getGUID() << ',' << db.escapeBlob(autolootlist, lootlistSize); if (!autolootQuery.addRow(query)) { return false; } if (!autolootQuery.execute()) { return false; }
em sua database, execute esta query
CREATE TABLE player_autoloot ( id int NOT NULL AUTO_INCREMENT, player_id int NOT NULL, autoloot_list blob, PRIMARY KEY (id) );
agora vá em data/scripts/talkactions e crie esse arquivo LUA
autoloot.lua
local talk = TalkAction("!autoloot") function talk.onSay(player, words, param) local i = player:getAutoLootList() local cache = "Check your loot list: " local split = param:split(",") local action = split[1] if param == "list" then if i then for _, item in ipairs(i) do cache = cache .. (ItemType(item)):getName() .. ", " end else player:sendTextMessage(MESSAGE_INFO_DESCR, "Your list is empty! Add some item and try again.") return false end player:sendTextMessage(MESSAGE_INFO_DESCR, cache:sub(1, -3)) return false end if action == "add" then local item = split[2]:gsub("%s+", "", 1) local itemType = ItemType(item) if itemType:getId() == 0 then itemType = ItemType(tonumber(item)) if itemType:getName() == '' then player:sendCancelMessage("There is no item with that id or name.") return false end end if player:getItemFromAutoLoot(itemType:getId()) then player:sendCancelMessage("You're already autolooting this item.") return false end player:addItemToAutoLoot(itemType:getId()) player:sendTextMessage(MESSAGE_INFO_DESCR, "You're now auto looting " .. itemType:getName()) return false elseif action == "remove" then local item = split[2]:gsub("%s+", "", 1) local itemType = ItemType(item) if itemType:getId() == 0 then itemType = ItemType(tonumber(item)) if itemType:getName() == '' then player:sendCancelMessage("There is no item with that id or name.") return false end end if player:getItemFromAutoLoot(itemType:getId()) then player:removeItemFromAutoLoot(itemType:getId()) player:sendTextMessage(MESSAGE_INFO_DESCR, "You removed the " .. itemType:getName() .. " from your loot list.") else player:sendCancelMessage("This item does not exist in your loot list.") end return false end player:sendTextMessage(MESSAGE_EVENT_ORANGE, "Auto Loot commands (items are automatically moved to your bp if you open monster corpse):"..'\n'.."!addloot add, nameItem - add item to auto loot by name"..'\n'.."!autoloot remove, itemName - remove item from auto loot by name"..'\n'.."!autoloot list - list your current auto loot items") return false end talk:separator(" ") talk:register()
É isso, espero que gostem do sisteminha
Se você encontrar algum bug, deixe-me saber.
Falta fazer:
Optimizar a mensagem de loot.
Adicionar ModalWindow.
Cheers~
-
MatCollier deu reputação a Pedriinz em Auto Loot Sytem for TFS 1.3 + revscriptsYo!
Acabei de realizar algumas atualizações no código. As mudanças foram:
Junção de todos os scripts LUA em um só, resultando em um único comando para administrar o sistema de autoloot.
Exemplo:
!autoloot add, boots of haste !autoloot remove, boots of haste !autoloot list !autoloot
Também adicionei algumas verificações no script para que o mesmo não seja executado caso o personagem não tenha nenhum item adicionado a lista de autoloot. (optimização). Verificação de capacidade também está aqui agora, caso o personagem não tenha mais que 100 de cap uma mensagem é retornada para o player informando que não foi possível saquear aquele loot devida a mesma. (No futuro talvez eu deixe isso configurável pelo config.lua).
Cheers
-
MatCollier deu reputação a penisagudo em TFS [1.2] Market Clientes 10 e 11@MatCollier testa esses aqui e ve se funciona, são clientes mais atualizados:
https://github.com/opentibiabr/tools
-
MatCollier deu reputação a JZDJ em Cliente 11 atualizado novas sprites 12 funcionandoFiquei um tempo sem postar nada, hj eu trago até vcs um cliente 11.44.5516 atualizado com as sprites do tibia 12.03.7844.
Essa versão 11 se conecta com o login.php do site, ou seja, tem acesso ao servidor.
Se dá algum problema não tenho certeza, só sei que estou jogando com ele e até então não deu erro.
Assista ao vídeo com o 11.44 funcionando.
Como podem ver no vídeo, as novas sprites estão funcionando sem crash do cliente e nem do servidor.
Mounts.xml, outfits.xml e items.xml devem ser configurados no seu servidor.
Cliente 11.44.5516 está atualizado com as novas sprites e com ip 127.0.0.1 ( localhost ), não mostrei os demais itens para não ficar um vídeo muito longo.
Download:
Tibia 11.44.5516 versão 12.rar
Scan:
Virus Total
Abraços e bom proveito do conteúdo.
Não se esqueça de dar um REP+ bem bacana!
Créditos:
Cipsoft pelos sprites e cliente
-
MatCollier deu reputação a wendel em Cast com bonus de expRep +, esse nova linha que você mandou funcionou aqui.
-
MatCollier recebeu reputação de wendel em Cast com bonus de exp@wendel Então, a primeira coisa que eu faria é te recomendar usar esse outro sistema aqui (que o Lyu mandou como resposta ao tópico):
Que me parece mais organizado e mais fácil de entender. Até porque, do jeito que tá aí creio eu que apenas quem "fraggar" o monstro vai receber experiência extra (exemplo, se eu usasse teu script no meu ot, e 4 pessoas estivessem upando de exp shared, só quem deu o last hit iria ganhar exp extra).
Talvez seja bom tu testar essa situação que mencionei aí.
Caso não seja compatível com teu server e tu queira manter o teu, pelo que entendi o problema é:
Se estiver tudo certinho nos teus scripts de receber exp, o cara já iria ganhar a experiência do monstro, e com esse script tu fez ele ganhar 105/2% (que seria 52,5%) da experiência a mais. Então se tu mudar aquele 1.05 pra somente 0.05 e tirar o /2, deveria ficar certo, pq a exp "extra" q ele vai receber seria só os 5%.
Assim:
local count = ((getMonsterInfo(string.lower(getCreatureName(target))).experience*0.05*exp)) -- 0.05 = 5%
Posso estar errado, mas acho que vale o teste.
-
MatCollier deu reputação a luanluciano93 em Premium account ficou free, é teleportado@LeoTK a titulo de conhecimento ...
• o evento onLogin não precisa ser registrado.
• TRUE em maiúscula é gambiarra do TFS. não use-o
• Se o personagem for premium você não precisa da variável "pos", portanto pode declarar ela depois da segunda verificação ...
function onLogin(cid) if isPremium(cid) then setPlayerStorageValue(cid, 6787656, 1) elseif getPlayerStorageValue(cid, 6787656) == 1 and not isPremium(cid) then doPlayerSetTown(cid, 1) doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid))) doSendMagicEffect(getPlayerPosition(cid), 240) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Sua Premium expirou!\nNao deixe de visitar nosso SHOP.") setPlayerStorageValue(cid, 6787656, 0) end return true end
-
MatCollier deu reputação a luanluciano93 em [TFS 1.2] Bônus de Exp para quem estiver no Client 11@MatCollier ótimo! Que bom que deu certo!