Ir para conteúdo
Propaganda

[C++] Opcodes 8.54


Posts Recomendados

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

  • Like 7
  • Thanks 1
Link para o comentário
Compartilhar em outros sites

  • otomeuhugo mudou o título para [C++] Opcodes 8.54

Participe da Conversa

Você pode postar agora e se cadastrar mais tarde. Cadastre-se Agora para publicar com Sua Conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.

×
  • Criar Novo...