• 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!

Trying to receive a storage value from Tfs > Otclient

Nostalgian

Member
Joined
Mar 17, 2018
Messages
66
Reaction score
15
Ok so I'm trying to create a new skill menu for OTclient for some custom skills.

All of my skills work great, written in lua. The skill levels are using storage values. Now comes the time when I am trying to connect and display this information on Otclient.

Holy crap I am confused. I have created a new basic menu, and I think I know how to link it to the value, but my problem is that I can't figure out how to get the storage value from tfs to otclient. I know that I need to use extended opcodes, but with all the research I have done, there seems to be some key thing missing that causes it not to work. Maybe I'm overlooking it, I have no idea.

Here is what I have, why is it not working?

A new creaturescript:
customSkill.lua
Code:
function onExtendedOpcode(cid, opcode, buffer)
    local player = Player(cid)
    local skillLevel = player:getStorageValue(player, 20020)
    player:sendExtendedOpcode(cid, 52, skillLevel)
    return true
end

Register it creaturescripts:
Code:
<event type="extendedopcode" name="skillLevelOpcode" script="customSkill.lua" />

Then i created a new module in otclient by copy/pasting the existing skills.lua and added this in the init function:
Code:
ProtocolGame.registerExtendedOpcode(52, skillLevel)

Then this in the terminate function:
Code:
ProtocolGame.unregisterExtendedOpcode(52)

Then added this function at the bottom of the same file:
Code:
function skillLevel(protocol, opcode, buffer)
   print(buffer)
end


It does absolutely nothing. No errors, does not display the storage value as intended in the OTC terminal....nothing. its like this files dont exist.

What am I doing wrong?
 
Solution
Ok so here is where I am now:

I created a new lib file:
opcodeFunctions.lua
Code:
function Player.sendCustomStorageUpdate(self)
    local packet = NetworkMessage()
    packet:addByte(0x32) -- Extended Opcode (0x32 = 50 (in dec))
    packet:addByte(0x37) -- The Opcode of this Request (0x37 = 55 (in dec))
    packet:addByte(self:getStorageValue(20020))
    packet:sendToPlayer(self)
    packet:delete()
end

Then created a creaturescript and registered it:
opcodeTest.lua
Code:
function onLogin(player)
    player:sendCustomStorageUpdate()
    return true
end

It appears to be sending the opcode, but my client is not able to read it for some reason?
I am getting this error:
Code:
ERROR: ProtocolGame parse message exception (1 bytes unread...
Ok, so I'm trying to figure out where to put this stuff then. I've tried so many different things that I'm now fairly confused, haha.

So, say I create this custom function for this particular opcode:
Code:
function Player.sendCustomStorageUpdate(self)
    local packet = NetworkMessage()
    packet:addByte(0x32) -- Extended Opcode (0x32 = 50 (in dec))
    packet:addByte(0x37) -- The Opcode of this Request (0x37 = 55 (in dec))
    packet:addByte(player:getStorageValue(20020))
    packet:sendToPlayer(player)
    packet:delete()
end
Where should I put this function?

and then, once it is in place, I'm ready to use it by calling it from somewhere. In this case, lets say that when a character logs in, I want to create a script that sends this opcode to the client.

I would then need to..... create a new creaturescript? event?

Like:
Code:
function onLogin(player)
    player:sendCustomStorageUpdate()
    return true
end


Am I in the ballpark here? :)
 
Ok, so I'm trying to figure out where to put this stuff then. I've tried so many different things that I'm now fairly confused, haha.

So, say I create this custom function for this particular opcode:
Code:
function Player.sendCustomStorageUpdate(self)
    local packet = NetworkMessage()
    packet:addByte(0x32) -- Extended Opcode (0x32 = 50 (in dec))
    packet:addByte(0x37) -- The Opcode of this Request (0x37 = 55 (in dec))
    packet:addByte(player:getStorageValue(20020))
    packet:sendToPlayer(player)
    packet:delete()
end
Where should I put this function?

and then, once it is in place, I'm ready to use it by calling it from somewhere. In this case, lets say that when a character logs in, I want to create a script that sends this opcode to the client.

I would then need to..... create a new creaturescript? event?

Like:
Code:
function onLogin(player)
    player:sendCustomStorageUpdate()
    return true
end


Am I in the ballpark here? :)

Yeah, you're there. In your data folder, there's a lib folder.
All the libs you can find inside here are global functions that you can use throughout all your other scripts.
You can add new stuff which you intend to use throughout your server scripts to these libraries,

For example, you can find a player.lua library, where you have Player related functions.
You could put it there. You could also create a new library for opcode related stuff if you want to organize this stuff yourself (in this case, you also have to make sure your new lib is being loaded by including it in the lib.lua or core.lua loader.

And after that, yeah, you can do pretty much what you wrote up there in the onLogin event.

As for the creation of a new onLogin creaturescript - you can do that, sure. Some people also put everything related to onLogin in a single script. Either way it works, just make sure they're all properly registered in creaturescripts.xml and that the scripts return true, otherwise if one of the onLogins doesn't return true, player won't be able to log in.
 
Ok so here is where I am now:

I created a new lib file:
opcodeFunctions.lua
Code:
function Player.sendCustomStorageUpdate(self)
    local packet = NetworkMessage()
    packet:addByte(0x32) -- Extended Opcode (0x32 = 50 (in dec))
    packet:addByte(0x37) -- The Opcode of this Request (0x37 = 55 (in dec))
    packet:addByte(self:getStorageValue(20020))
    packet:sendToPlayer(self)
    packet:delete()
end

Then created a creaturescript and registered it:
opcodeTest.lua
Code:
function onLogin(player)
    player:sendCustomStorageUpdate()
    return true
end

It appears to be sending the opcode, but my client is not able to read it for some reason?
I am getting this error:
Code:
ERROR: ProtocolGame parse message exception (1 bytes unread, last opcode is 50, prev opcode is 180): InputMessage eof reached
Previous opcode is 180? wth

This is my "landing pad" on the client:
Code:
function init()
  connect(g_game, {
    onGameStart = onGameStart,
    onGameEnd = onGameEnd
  }, true)
end

function terminate()
  disconnect(g_game, {
    onGameStart = onGameStart,
    onGameEnd = onGameEnd
  })
end

function onGameStart()
    ProtocolGame.registerExtendedOpcode(55, receiveStorageFromServer) -- When extended opcode "10" is received, function called "receiveStorageFromServer" is called and some arguments are passed to it, including our packet's data.
end

function onGameEnd()
    ProtocolGame.unregisterExtendedOpcode(55, true)
end


function receiveStorageFromServer(protocol, opcode, buffer)
    print(buffer)
end

:O
 
Ok so here is where I am now:

I created a new lib file:
opcodeFunctions.lua
Code:
function Player.sendCustomStorageUpdate(self)
    local packet = NetworkMessage()
    packet:addByte(0x32) -- Extended Opcode (0x32 = 50 (in dec))
    packet:addByte(0x37) -- The Opcode of this Request (0x37 = 55 (in dec))
    packet:addByte(self:getStorageValue(20020))
    packet:sendToPlayer(self)
    packet:delete()
end

Then created a creaturescript and registered it:
opcodeTest.lua
Code:
function onLogin(player)
    player:sendCustomStorageUpdate()
    return true
end

It appears to be sending the opcode, but my client is not able to read it for some reason?
I am getting this error:
Code:
ERROR: ProtocolGame parse message exception (1 bytes unread, last opcode is 50, prev opcode is 180): InputMessage eof reached
Previous opcode is 180? wth

This is my "landing pad" on the client:
Code:
function init()
  connect(g_game, {
    onGameStart = onGameStart,
    onGameEnd = onGameEnd
  }, true)
end

function terminate()
  disconnect(g_game, {
    onGameStart = onGameStart,
    onGameEnd = onGameEnd
  })
end

function onGameStart()
    ProtocolGame.registerExtendedOpcode(55, receiveStorageFromServer) -- When extended opcode "10" is received, function called "receiveStorageFromServer" is called and some arguments are passed to it, including our packet's data.
end

function onGameEnd()
    ProtocolGame.unregisterExtendedOpcode(55, true)
end


function receiveStorageFromServer(protocol, opcode, buffer)
    print(buffer)
end

:O

Try to change this
packet:addByte(self:getStorageValue(20020))
to this:
packet:addString(tostring(self:getStorageValue(20020)))

If that doesn't work, you can try also changing this
Lua:
function receiveStorageFromServer(protocol, opcode, buffer)
    print(buffer)
end
to
Lua:
function receiveStorageFromServer(protocol, opcode, buffer)
    print("Received extended opcode " .. opcode .. " from server.")
    local storage = buffer:getString()
    print(storage)
end
 
Solution
Thank you so much! the string works perfectly! Once I'm rich and famous and ruling the world i'll be sure to remember you! :D

I wonder why it won't just read a byte? :O
 
Back
Top