otomeuhugo 126 Postado 17 de Agosto 2023 Compartilhar Postado 17 de Agosto 2023 Bom, hoje o conceito do opcodes já é difundido nos servidores, mas alguns mais antigos não possuem. Esse que vou trazer foi testado nas versões 8.54, então vamos lá. Uma explicação breve do que são os Opcodes, esse é um sistema essencial pra todo otServer, pois ele permite o desenvolvimento de muitas outras funcionalidade de forma mais simples. Através dos opcodes é possível fazer a troca de informação entre servidor e cliente em tempo real. (Obs: Será necessário a source do servidor) PROTOCOLGAME.H Spoiler Você irá procurar no arquivo por: void AddShopItem(NetworkMessage_ptr msg, const ShopInfo item); E embaixo dessa linha você irá adicionar: void parseExtendedOpcode(NetworkMessage& msg); void sendExtendedOpcode(uint8_t opcode, const std::string& buffer); PROTOCOLGAME.CPP Spoiler Bom, nesse arquivo você deverá achar no código o seguinte trecho: uint32_t key[4] = {msg.GetU32(), msg.GetU32(), msg.GetU32(), msg.GetU32()}; enableXTEAEncryption(); setXTEAKey(key); E embaixo desse trecho você acrescenta: // notifies to otclient that this server can receive extended game protocol opcodes if(operatingSystem >= CLIENTOS_OTCLIENT_LINUX) sendExtendedOpcode(0x00, std::string()); Agora você irá procurar pelo seguinte trecho: void ProtocolGame::AddShopItem(NetworkMessage_ptr msg, const ShopInfo item){ const ItemType& it = Item::items[item.itemId]; msg->AddU16(it.clientId); if(it.isSplash() || it.isFluidContainer()) msg->AddByte(fluidMap[item.subType % 8]); else if(it.stackable || it.charges) msg->AddByte(item.subType); else msg->AddByte(0x01); msg->AddString(item.itemName); msg->AddU32(uint32_t(it.weight * 100)); msg->AddU32(item.buyPrice); msg->AddU32(item.sellPrice); } E embaixo dele você irá adicionar: void ProtocolGame::parseExtendedOpcode(NetworkMessage& msg){ uint8_t opcode = msg.GetByte(); std::string buffer = msg.GetString(); // process additional opcodes via lua script event addGameTask(&Game::parsePlayerExtendedOpcode, player->getID(), opcode, buffer); } void ProtocolGame::sendExtendedOpcode(uint8_t opcode, const std::string& buffer){ // extended opcodes can only be send to players using otclient, cipsoft's tibia can't understand them NetworkMessage_ptr msg = getOutputBuffer(); if(msg){ TRACK_MESSAGE(msg); msg->AddByte(0x32); msg->AddByte(opcode); msg->AddString(buffer); } } Agora você terá que achar o seguinte trecho: case 0x1E: // keep alive / ping responseparseReceivePing(msg); break; E logo embaixo acrescente: case 0x32: // otclient extended opcode parseExtendedOpcode(msg); break; ENUMS.H Spoiler Você terá que achar o seguinte trecho: enum GuildLevel_t{ GUILDLEVEL_NONE = 0, GUILDLEVEL_MEMBER, GUILDLEVEL_VICE, GUILDLEVEL_LEADER }; E embaixo você substituirá o "OperatingSystem" por este: enum OperatingSystem_t{ CLIENTOS_LINUX = 0x01, CLIENTOS_WINDOWS = 0x02, CLIENTOS_OTCLIENT_LINUX = 0x0A, CLIENTOS_OTCLIENT_WINDOWS = 0x0B, CLIENTOS_OTCLIENT_MAC = 0x0C }; PLAYER.H Spoiler Você irá procurar pelo seguinte trecho: void sendCreatureShield(const Creature* creature) E embaixo dele você adicione: void sendExtendedOpcode(uint8_t opcode, const std::string& buffer){ if(client) client->sendExtendedOpcode(opcode, buffer); } LUASCRIPT.CPP Spoiler Você irá procurar pelo seguinte trecho: void LuaScriptInterface::registerFunctions(){ E embaixo dessa linha você irá adicionar: //doSendPlayerExtendedOpcode(cid, opcode, buffer) lua_register(m_luaState, "doSendPlayerExtendedOpcode", LuaScriptInterface::luaDoSendPlayerExtendedOpcode); Agora você irá buscar por: SHIFT_OPERATOR(int32_t, LeftShift, <<) SHIFT_OPERATOR(int32_t, RightShift, >>) SHIFT_OPERATOR(uint32_t, ULeftShift, <<) SHIFT_OPERATOR(uint32_t, URightShift, >>) #undef SHIFT_OPERATOR E embaixo disso adicione: int32_t LuaScriptInterface::luaDoSendPlayerExtendedOpcode(lua_State* L){ //doSendPlayerExtendedOpcode(cid, opcode, buffer) std::string buffer = popString(L); int opcode = popNumber(L); ScriptEnviroment* env = getEnv(); if(Player* player = env->getPlayerByUID(popNumber(L))) { player->sendExtendedOpcode(opcode, buffer); lua_pushboolean(L, true); } lua_pushboolean(L, false); return 1; } LUASCRIPT.H Spoiler Você irá procurar pelo seguinte trecho: virtual void registerFunctions(); E embaixo dele adicione: static int32_t luaDoSendPlayerExtendedOpcode(lua_State* L); CREATUREEVENT.H Spoiler Você deverá procurar por: CREATURE_EVENT_PREPAREDEATH E irá substituir ele por: CREATURE_EVENT_PREPAREDEATH,CREATURE_EVENT_EXTENDED_OPCODE // otclient additional network opcodes Agora procure por: uint32_t executePrepareDeath(Creature* creature, DeathList deathList); E embaixo acrescente: uint32_t executeExtendedOpcode(Creature* creature, uint8_t opcode, const std::string& buffer); CREATUREEVENT.CPP Spoiler Você irá procurar pelo seguinte trecho: else if(tmpStr == "death") m_type = CREATURE_EVENT_DEATH; E embaixo adicione: else if(tmpStr == "extendedopcode") m_type = CREATURE_EVENT_EXTENDED_OPCODE; Agora busque por: case CREATURE_EVENT_DEATH: return "onDeath"; E embaixo acrescente: case CREATURE_EVENT_EXTENDED_OPCODE: return "onExtendedOpcode"; Agora busque por: case CREATURE_EVENT_DEATH: return "cid, corpse, deathList"; E embaixo adicione: case CREATURE_EVENT_EXTENDED_OPCODE: return "cid, opcode, buffer"; Agora você irá buscar por: std::cout << "[Error - CreatureEvent::executeFollow] Call stack overflow." << std::endl; return 0; } } E embaixo acrescente: uint32_t CreatureEvent::executeExtendedOpcode(Creature* creature, uint8_t opcode, const std::string& buffer){ //onExtendedOpcode(cid, opcode, buffer) if(m_interface->reserveEnv()){ ScriptEnviroment* env = m_interface->getEnv(); if(m_scripted == EVENT_SCRIPT_BUFFER){ env->setRealPos(creature->getPosition()); std::stringstream scriptstream; scriptstream << "local cid = " << env->addThing(creature) << std::endl;scriptstream << "local opcode = " << (int)opcode << std::endl; scriptstream << "local buffer = " << buffer.c_str() << std::endl; scriptstream << m_scriptData; bool result = true; if(m_interface->loadBuffer(scriptstream.str())){ lua_State* L = m_interface->getState(); result = m_interface->getGlobalBool(L, "_result", true); } m_interface->releaseEnv(); return result; }else{ #ifdef __DEBUG_LUASCRIPTS__char desc[35]; sprintf(desc, "%s", player->getName().c_str()); env->setEvent(desc); #endif env->setScriptId(m_scriptId, m_interface); env->setRealPos(creature->getPosition()); lua_State* L = m_interface->getState(); m_interface->pushFunction(m_scriptId); lua_pushnumber(L, env->addThing(creature)); lua_pushnumber(L, opcode); lua_pushlstring(L, buffer.c_str(), buffer.length()); bool result = m_interface->callFunction(3); m_interface->releaseEnv(); return result; } }else{ std::cout << "[Error - CreatureEvent::executeRemoved] Call stack overflow." << std::endl; return 0; } } GAME.H Spoiler Você irá buscar por: int32_t getLightHour() {return lightHour;} void startDecay(Item* item); E embaixo adicione: void parsePlayerExtendedOpcode(uint32_t playerId, uint8_t opcode, const std::string& buffer); GAME.CPP Spoiler Você irá procurar por: player->sendTextMessage(MSG_INFO_DESCR, buffer);} E embaixo adicione: void Game::parsePlayerExtendedOpcode(uint32_t playerId, uint8_t opcode, const std::string& buffer){ Player* player = getPlayerByID(playerId); if(!player || player->isRemoved()) return; CreatureEventList extendedOpcodeEvents = player->getCreatureEvents(CREATURE_EVENT_EXTENDED_OPCODE); for(CreatureEventList::iterator it = extendedOpcodeEvents.begin(); it != extendedOpcodeEvents.end(); ++it)(*it)->executeExtendedOpcode(player, opcode, buffer); } Agora na pasta data do servidor você irá abrir o /creaturescripts/creaturescripts.xml e vai adicionar: <event type="extendedopcode" name="ExtendedOpcode" event="script" value="extendedopcode.lua"/> Agora em /creaturescripts crie o arquivo extendedopcode.lua e adicione nele: OPCODE_LANGUAGE = 1 function onExtendedOpcode(cid, opcode, buffer) if opcode == OPCODE_LANGUAGE then -- otclient language if buffer == 'en' or buffer == 'pt' then -- example, setting player language, because otclient is multi-language... --doCreatureSetStorage(cid, CREATURE_STORAGE_LANGUAGE, buffer) end else -- other opcodes can be ignored, and the server will just work fine... end end Créditos: MaXwEllDeN 100% por adaptar o código 7 1 Citar Link para o comentário Compartilhar em outros sites Mais opções de compartilhamento...
Suporte DarkninoxD 62 Postado 17 de Agosto 2023 Suporte Compartilhar Postado 17 de Agosto 2023 Topico aprovado, obrigado por contribuir com a comunidade. Citar Link para o comentário Compartilhar em outros sites Mais opções de compartilhamento...
Posts Recomendados
Participe da Conversa
Você pode postar agora e se cadastrar mais tarde. Cadastre-se Agora para publicar com Sua Conta.