Ir para conteúdo
Propaganda

Opcodes - Oque são? Como utilizar?


Posts Recomendados

  • Administrador

Salve rapaziada!

Me pediram no privado perguntando sobre Opcodes, como no começo eu tive bastante dificuldade de entender, estou fazendo este tutorial para explicar o básico.

 

Opcodes são a comunicação entre o cliente e o servidor sem fazer alterações na source. Na source você poderia usar sockets, que são pacotes de informação, diretamente sem usar funcionalidades do jogo como meio de transmissão, já o opcode utiliza recursos in game para fazer essa comunicação.

 

Exemplo:

No módulo game_skills, no arquivo skills.lua, você pode notar a utilização do seguinte código:

Spoiler

ProtocolGame.registerExtendedOpcode(102, function(protocol, opcode, buffer) onPokemonSkillChange(protocol, opcode, buffer) end)

Essa linha, serve para registrar o uso do opcode número 102, estamos dizendo ali, que quando recebermos uma solicitação por opcode, sentido Servidor > Cliente, sendo essa de número 102, deverá ser acionada a função onPokemonSkillChange.

Em outra parte do mesmo skills.lua, temos o seguinte código:

Spoiler
function refresh()
  local player = g_game.getLocalPlayer()
  if not player then return end

  if expSpeedEvent then expSpeedEvent:cancel() end
  expSpeedEvent = cycleEvent(checkExpSpeed, 30*1000)

  onExperienceChange(player, player:getExperience())
  onLevelChange(player, player:getLevel(), player:getLevelPercent())
  onStaminaChange(player, player:getStamina())

  for i=0,6 do
    onSkillChange(player, i, player:getSkillLevel(i), player:getSkillLevelPercent(i))
    onBaseSkillChange(player, i, player:getSkillBaseLevel(i))
  end

  g_game.getProtocolGame():sendExtendedOpcode(102, 'refresh')

  skillsWindow:setContentMinimumHeight(50)
  skillsWindow:setContentMaximumHeight(330)
end

 

Repare que a parte destaca: g_game.getProtocolGame():sendExtendedOpcode(102, 'refresh'), faz o envio de uma solicitação de sentido Cliente > Servidor, com o número 102 que é o id de identificação da opcode e na frente a string 'refresh', ou seja, um valor para o servidor conseguir enxergar o que deve ser feito. Para entender melhor vamos ao Servidor e olhar onde é tratada essa chamada do Cliente.

No Servidor, em data/creaturescripts/scripts/opcodes/opcode.lua, temos o seguinte código:

Spoiler

local op_crea = {
      OPCODE_SKILL_BAR = opcodes.OPCODE_SKILL_BAR,
      OPCODE_POKEMON_HEALTH = opcodes.OPCODE_POKEMON_HEALTH,
      OPCODE_BATTLE_POKEMON = opcodes.OPCODE_BATTLE_POKEMON,
      OPCODE_FIGHT_MODE = opcodes.OPCODE_FIGHT_MODE,
      OPCODE_WILD_POKEMON_STATS = opcodes.OPCODE_WILD_POKEMON_STATS,
      OPCODE_REQUEST_DUEL = opcodes.OPCODE_REQUEST_DUEL,
      OPCODE_ACCEPT_DUEL = opcodes.OPCODE_ACCEPT_DUEL,
      OPCODE_YOU_ARE_DEAD = opcodes.OPCODE_YOU_ARE_DEAD,
      OPCODE_DITTO_MEMORY = opcodes.OPCODE_DITTO_MEMORY,
}

function onExtendedOpcode(cid, opcode, buffer)
    if opcode == op_crea.OPCODE_SKILL_BAR then
        if buffer == "refresh" then
            doOTCSendPlayerSkills(cid)

        end
    elseif opcode == op_crea.OPCODE_POKEMON_HEALTH then
        if buffer == "refresh" then
            doOTCSendPokemonHealth(cid)
        end
    elseif opcode == op_crea.OPCODE_BATTLE_POKEMON then
        if buffer == "refresh" then
            if #getCreatureSummons(cid) >= 1 then
                doSendPlayerExtendedOpcode(cid, op_crea.OPCODE_BATTLE_POKEMON, tostring(getCreatureSummons(cid)[1]))
            end
        end

Repare nas partes que eu destaquei, irei explica-las abaixo:

Spoiler

 if opcode == op_crea.OPCODE_SKILL_BAR then - Não se assuste, essa parte é o número 102 disfarçado de constante, deve ter alguma tabela por ai no servidor que define que este texto é o número 102, então ele faz a pergunta "O número do opcode é igual a 102?".

if buffer == "refresh" then - No caso da condição acima for verdadeira, ele pergunta novamente "o valor informado no buffer foi 'refresh'?"

lembram do valor que era informado junto ao envio da opcode 102 no cliente? sim, esse mesmo!

doOTCSendPlayerSkills(cid) - E essa é a função que será executada quando o Servidor receber aquela opcode do cliente.

Vamos ver o que essa função faz?

em data/lib/106-main functions.lua, temos a definição daquela função, que é:

Spoiler

function doOTCSendPlayerSkills(cid)
    local str = {}
    table.insert(str, getPlayerClan(cid))
    table.insert(str, "|"..getPlayerCasinoCoins(cid))
    table.insert(str, "|"..getPlayerKantoCatches(cid).."|"..getPlayerTotalCatches(cid))
    table.insert(str, "|"..getPlayerWins(cid).."|"..getPlayerLoses(cid).."|"..getPlayerOfficialWins(cid).."|"..getPlayerOfficialLoses(cid).."|"..getPlayerPVPScore(cid))
    table.insert(str, "|"..getPlayerBadgeOfLeader(cid, "Brock"))
    table.insert(str, ";"..getPlayerBadgeOfLeader(cid, "Misty"))
    table.insert(str, ";"..getPlayerBadgeOfLeader(cid, "Surge"))
    table.insert(str, ";"..getPlayerBadgeOfLeader(cid, "Erika"))
    table.insert(str, ";"..getPlayerBadgeOfLeader(cid, "Sabrina"))
    table.insert(str, ";"..getPlayerBadgeOfLeader(cid, "Koga"))
    table.insert(str, ";"..getPlayerBadgeOfLeader(cid, "Blaine"))
    table.insert(str, ";"..getPlayerBadgeOfLeader(cid, "Giovanni"))
    return doSendPlayerExtendedOpcode(cid, opcodes.OPCODE_SKILL_BAR, table.concat(str))
end

Basicamente, está função preenche uma tabela com as informações sobre insígneas, coins, qtd capturas do player e envia de volta ao Cliente através do comando:

 return doSendPlayerExtendedOpcode(cid, opcodes.OPCODE_SKILL_BAR, table.concat(str))

lembrando que o opcodes.OPCODE_SKILL_BAR nada mais que que o número 102 e o table.concat(str) é o buffer, ou seja, um parâmetro da função doSendPlayerExtendedOpcode com os dados que serão enviados ao Cliente.

 

Espero que todos tenham entendido.

Créditos: maykeldoido

  • Like 5
  • Thanks 2
  • Haha 1
Link para o comentário
https://tibiadevs.com/forums/topic/78-opcodes-oque-s%C3%A3o-como-utilizar/
Compartilhar em outros sites

  • gutinha mudou o título para Opcodes - Oque são? Como utilizar?

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 conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
  • Criar Novo...