• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[C++] - New Extended Opcode problem

Joined
Jul 18, 2014
Messages
193
Solutions
2
Reaction score
15
This days I've been seeing this topic and I added a new function in server sources to send a new opcode to otclient. Everything is fine, I added the respective byte in server and received it in otclient but when I'm going to get the value in an otclient mod that it's sent from the server, always shows like a random number or a zero value.
Why this happens? Any idea?

Thanks.
 
This days I've been seeing this topic and I added a new function in server sources to send a new opcode to otclient. Everything is fine, I added the respective byte in server and received it in otclient but when I'm going to get the value in an otclient mod that it's sent from the server, always shows like a random number or a zero value.
Why this happens? Any idea?

Thanks.

Can you show some scripts? Especially the one when you're sending the buffer, and those where you're receiving it/utilizing it.
 
Can you show some scripts? Especially the one when you're sending the buffer, and those where you're receiving it/utilizing it.

Sure. This is what I used in server (TFS 1.3 for 10.99):

protocolgamebase.cpp
C++:
void ProtocolGameBase::sendOpcodeInfo() {
    NetworkMessage msg;
    msg.addByte(0xFF);
  
    msg.add<uint16_t>(player->getOpcodeInfo());
}

luascript.cpp (of course registered before as a method to be used in lua scripts)
C++:
int LuaScriptInterface::luaPlayerSetOpcodeInfo(lua_State* L) {
    Player* player = getUserdata<Player>(L, 1);
    if (player) {
        player->opcodeInfo = getNumber<uint16_t>(L, 2);
        player->sendOpcodeInfo();
        pushBoolean(L, true);
    }
    else {
        lua_pushnil(L);
    }
    return 1;
}

player.cpp
C++:
void Player::sendOpcodeInfo() {
    if (client) {
        client->sendOpcodeInfo();
    }
}
client is protocolgamebase object.

And this is what I used in otclient (latest version from github):

localplayer.cpp (also registered before as a member function):
C++:
void LocalPlayer::setOpcodeInfo(int opcodeInfo) {
    m_opcodeInfo = opcodeInfo;
}

protocolgameparse.cpp
C++:
void ProtocolGame::parsePlayerOpcodeInfo(const InputMessagePtr& msg) {
    int info = msg->getU16();
    m_localPlayer->setOpcodeInfo(info);
}

protocolcodes.h (added respective code for byte in protocolgamebase.cpp from server):
C++:
GameServerSendOpcodeInfo = 255

Now in a new otclient module I used this in init function:
Lua:
function init()
    local player = g_game.getLocalPlayer()
    print("op: "..player:getOpcodeInfo())
end
player:getOpcodeInfo() only returns variable m_opcodeInfo from otclient (also added by myself).

In server files, I added a lua script for talkactions with this code:
Lua:
player:setOpcodeInfo(10);
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "OPCODE INFO: "..player:getOpcodeInfo())
And shows correctly the number 10 as I set before with player:setOpcodeInfo(10) but in otclient console only shows a number like: 165203921.
 
When you're using TFS 1.3, then there is already such function built into distro, you don't need to implement it yourself.

Here is cut from lib/core/player.lua
Code:
function Player.sendExtendedOpcode(self, opcode, buffer)
    if not self:isUsingOtClient() then
        return false
    end

    local networkMessage = NetworkMessage()
    networkMessage:addByte(0x32)
    networkMessage:addByte(opcode)
    networkMessage:addString(buffer)
    networkMessage:sendToPlayer(self)
    networkMessage:delete()
    return true
end

Usage is self explaining.
 
Sure. This is what I used in server (TFS 1.3 for 10.99):

protocolgamebase.cpp
C++:
void ProtocolGameBase::sendOpcodeInfo() {
    NetworkMessage msg;
    msg.addByte(0xFF);
 
    msg.add<uint16_t>(player->getOpcodeInfo());
}

luascript.cpp (of course registered before as a method to be used in lua scripts)
C++:
int LuaScriptInterface::luaPlayerSetOpcodeInfo(lua_State* L) {
    Player* player = getUserdata<Player>(L, 1);
    if (player) {
        player->opcodeInfo = getNumber<uint16_t>(L, 2);
        player->sendOpcodeInfo();
        pushBoolean(L, true);
    }
    else {
        lua_pushnil(L);
    }
    return 1;
}

player.cpp
C++:
void Player::sendOpcodeInfo() {
    if (client) {
        client->sendOpcodeInfo();
    }
}
client is protocolgamebase object.

And this is what I used in otclient (latest version from github):

localplayer.cpp (also registered before as a member function):
C++:
void LocalPlayer::setOpcodeInfo(int opcodeInfo) {
    m_opcodeInfo = opcodeInfo;
}

protocolgameparse.cpp
C++:
void ProtocolGame::parsePlayerOpcodeInfo(const InputMessagePtr& msg) {
    int info = msg->getU16();
    m_localPlayer->setOpcodeInfo(info);
}

protocolcodes.h (added respective code for byte in protocolgamebase.cpp from server):
C++:
GameServerSendOpcodeInfo = 255

Now in a new otclient module I used this in init function:
Lua:
function init()
    local player = g_game.getLocalPlayer()
    print("op: "..player:getOpcodeInfo())
end
player:getOpcodeInfo() only returns variable m_opcodeInfo from otclient (also added by myself).

In server files, I added a lua script for talkactions with this code:
Lua:
player:setOpcodeInfo(10);
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "OPCODE INFO: "..player:getOpcodeInfo())
And shows correctly the number 10 as I set before with player:setOpcodeInfo(10) but in otclient console only shows a number like: 165203921.

Are you using this extended opcode support?
If so, why don't you send buffer via doSendPlayerExtendedOpcode(cid, opcode, buffer) / player:doSendPlayerExtendedOpcode(opcode, buffer)
And receive it in client in lua?

You don't need to hardcode any of this if you are using that.

But in your case, I don't think this does what it's supposed to do

Lua:
void Player::sendOpcodeInfo() {
    if (client) {
        client->sendOpcodeInfo();
    }
}

Can you check whether invoking this does 100% trigger the client to receive the packet?
If so, print out both what you're inserting into the packet at the moment of insertion (on server side) and print what you receive (client side).
If it's still not synced up, might be that the opcode you're sending it via is already reserved for something else and something else is being read from another source.

Either way, I recommend using the lua only option i mentioned, should work without problems if you added support for extended opcodes.
 
When you're using TFS 1.3, then there is already such function built into distro, you don't need to implement it yourself.

Here is cut from lib/core/player.lua
Code:
function Player.sendExtendedOpcode(self, opcode, buffer)
    if not self:isUsingOtClient() then
        return false
    end

    local networkMessage = NetworkMessage()
    networkMessage:addByte(0x32)
    networkMessage:addByte(opcode)
    networkMessage:addString(buffer)
    networkMessage:sendToPlayer(self)
    networkMessage:delete()
    return true
end

Usage is self explaining.
Are you using this extended opcode support?
If so, why don't you send buffer via doSendPlayerExtendedOpcode(cid, opcode, buffer) / player:doSendPlayerExtendedOpcode(opcode, buffer)
And receive it in client in lua?

You don't need to hardcode any of this if you are using that.

But in your case, I don't think this does what it's supposed to do

Lua:
void Player::sendOpcodeInfo() {
    if (client) {
        client->sendOpcodeInfo();
    }
}

Can you check whether invoking this does 100% trigger the client to receive the packet?
If so, print out both what you're inserting into the packet at the moment of insertion (on server side) and print what you receive (client side).
If it's still not synced up, might be that the opcode you're sending it via is already reserved for something else and something else is being read from another source.

Either way, I recommend using the lua only option i mentioned, should work without problems if you added support for extended opcodes.

But with this, how can I get buffer in otclient? I mean, in talkaction script from server I put this:
Lua:
player:sendExtendedOpcode(80, "Example Text")
And in otclient I want to get that text instead of call a function. For example:
Lua:
local msg = ProtocolGame.getOpcode(80)
print("message: "..msg)
And it'll print:
message: Example Text

I was seeing the InputMessage, trying to get that string with this, but I didn't get nothing.
Any idea?
 
at init() function
ProtocolGame.registerExtendedOpcode(80, youOpcodeFunction)
Code:
function youOpcodeFunction(protocol, opcode, buffer)
  print("message: "..buffer)
end
 
at init() function
ProtocolGame.registerExtendedOpcode(80, youOpcodeFunction)
Code:
function youOpcodeFunction(protocol, opcode, buffer)
  print("message: "..buffer)
end
Great! Those parameters is what I needed. Thank you! By the way, do you know why custom modules doesn't load automatically when client opens?
 
Great! Those parameters is what I needed. Thank you! By the way, do you know why custom modules doesn't load automatically when client opens?

Make sure the otmod file of your module contains
Code:
  @onLoad: init()
  @onUnload: terminate()

And that your init() function in the module's lua file calls all appropriate functions that you want it to call + imports the style from otui. (e.g. g_ui.importStyle('stylename'))
 
Make sure the otmod file of your module contains
Code:
  @onLoad: init()
  @onUnload: terminate()

And that your init() function in the module's lua file calls all appropriate functions that you want it to call + imports the style from otui. (e.g. g_ui.importStyle('stylename'))

Module works fine and can be loaded manually at modulemanager but the problem was it doesn't load automatically, but using autoload: true in .otmod file fixes it.
 
Back
Top