otomeuhugo 128 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 Link para o comentário https://tibiadevs.com/forums/topic/71-c-opcodes-854/ Compartilhar em outros sites Mais opções de compartilhamento...
Suporte DarkninoxD 66 Postado 17 de Agosto 2023 Suporte Compartilhar Postado 17 de Agosto 2023 Topico aprovado, obrigado por contribuir com a comunidade. Link para o comentário https://tibiadevs.com/forums/topic/71-c-opcodes-854/#findComment-331 Compartilhar em outros sites Mais opções de compartilhamento...
Posts Recomendados
Crie uma conta ou entre para comentar
Você precisar ser um membro para fazer um comentário
Criar uma conta
Crie uma nova conta em nossa comunidade. É fácil!
Crie uma nova contaEntrar
Já tem uma conta? Faça o login.
Entrar Agora