• 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++ Doubts About C++ Source TFS 1.3

Yan18

Member
Joined
Jun 14, 2014
Messages
104
Solutions
3
Reaction score
17
Hello everyone!

I'm learning C++ to developing my own server. I would like to understand somethings that I can't understand.

I have difficult in understading Lua_State *L. I understood the concept, but in the practice, I don't understand.

C++:
int LuaScriptInterface::luaPlayerSendTextMessage(lua_State* L)
In the function above, the function has only unique parameter (Lua_State *L).

Lua:
player:sendTextMessage(MESSAGE_TYPE, "Text")
But in C++ (source) the function has an unique argument, why in the Lua the function has two parameters?

And the another doubt is, why some variables receive a kind of values like this:
Code:
Example 1 :

uint32_t Player::playerAutoID = 0x10000000;

------------------------------------------------------------------------------
Example 2:

Cylinder* Game::internalGetCylinder(Player* player, const Position& pos) const
{
    if (pos.x != 0xFFFF)
    {
        return map.getTile(pos);
    }
}

------------------------------------------------------------------------------
Example 3:

auto output = OutputMessagePool::getOutputMessage();
    output->addByte(0x14);
This values like 0x10000000 is memory address? I would like to understand why some variables receive values like that.


Sorry if my doubts are obvious, I'm beginner in C++ yet.
 
Solution
lua_State* L is a pointer to the information in the lua state
you use it to access information inside of the state via the lua C api
when you send arguments through lua to a function such as Player.sendTextMessage, they are added to the stack
in your example, this is how the stack looks like:
Code:
1: player userdata
2: message type
3: text
if you look in luaPlayerSendTextMessage in the source, youll see that it grabs each argument from the stack,
C++:
1: Player* player = getUserdata<Player>(L, 1);
2 & 3: TextMessage message(getNumber<MessageClasses>(L, 2), getString(L, 3));

to answer your other question, its just a simple hex value that translates to a real number, theyre used to make things easier and its generally cleaner...
lua_State* L is a pointer to the information in the lua state
you use it to access information inside of the state via the lua C api
when you send arguments through lua to a function such as Player.sendTextMessage, they are added to the stack
in your example, this is how the stack looks like:
Code:
1: player userdata
2: message type
3: text
if you look in luaPlayerSendTextMessage in the source, youll see that it grabs each argument from the stack,
C++:
1: Player* player = getUserdata<Player>(L, 1);
2 & 3: TextMessage message(getNumber<MessageClasses>(L, 2), getString(L, 3));

to answer your other question, its just a simple hex value that translates to a real number, theyre used to make things easier and its generally cleaner for stuff like bytes, offsets, and bitmasks because it's just easier
 
Solution
lua_State* L is a pointer to the information in the lua state
you use it to access information inside of the state via the lua C api
when you send arguments through lua to a function such as Player.sendTextMessage, they are added to the stack
in your example, this is how the stack looks like:
Code:
1: player userdata
2: message type
3: text
if you look in luaPlayerSendTextMessage in the source, youll see that it grabs each argument from the stack,
C++:
1: Player* player = getUserdata<Player>(L, 1);
2 & 3: TextMessage message(getNumber<MessageClasses>(L, 2), getString(L, 3));

to answer your other question, its just a simple hex value that translates to a real number, theyre used to make things easier and its generally cleaner for stuff like bytes, offsets, and bitmasks because it's just easier
Now I get it, thanks friend!
 
Now I get it, thanks friend!
figured i'd add some extra information so you properly understand how a C function works, so here we go:

it's important to fully understand how a stack works and what's being added / removed when using the lua C api as well
as you'll notice almost all functions return 1 in luascript.cpp, just like sendTextMessage
this pushes 1 value onto the stack and returns it, any other values are discarded from the stack by lua automatically
in the case of sendTextMessage, it can return 3 things, nil, false, and true
if the player doesn't exist, it will return nil
C++:
    Player* player = getUserdata<Player>(L, 1);
    if (!player) {
        lua_pushnil(L);
        return 1;
    }
lua_pushnil(L); pushes a nil value onto the stack and return 1 consumes the top value of the stack, which in this case is nil
if there's a specific channel id supplied and it doesn't exist, or the player is not in that channel, it will return false:
C++:
        if (!channel || !channel->hasUser(*player)) {
            pushBoolean(L, false);
            return 1;
        }
again, pushBoolean obviously does the same thing, but pushes false, lua consumes top of the stack, and gives you back false in lua

and finally if things all go well it returns true
C++:
    player->sendTextMessage(message);
    pushBoolean(L, true);

    return 1;

there's other numbers of return values u can explore in luascript.cpp if u jsut ctrl+f for return 2 and return 0 and see what it looks like

here's a link to learn how a stack works: Stack Data Structure (Introduction and Program) - GeeksforGeeks (https://www.geeksforgeeks.org/stack-data-structure-introduction-program/)
 
figured i'd add some extra information so you properly understand how a C function works, so here we go:

it's important to fully understand how a stack works and what's being added / removed when using the lua C api as well
as you'll notice almost all functions return 1 in luascript.cpp, just like sendTextMessage
this pushes 1 value onto the stack and returns it, any other values are discarded from the stack by lua automatically
in the case of sendTextMessage, it can return 3 things, nil, false, and true
if the player doesn't exist, it will return nil
C++:
    Player* player = getUserdata<Player>(L, 1);
    if (!player) {
        lua_pushnil(L);
        return 1;
    }
lua_pushnil(L); pushes a nil value onto the stack and return 1 consumes the top value of the stack, which in this case is nil
if there's a specific channel id supplied and it doesn't exist, or the player is not in that channel, it will return false:
C++:
        if (!channel || !channel->hasUser(*player)) {
            pushBoolean(L, false);
            return 1;
        }
again, pushBoolean obviously does the same thing, but pushes false, lua consumes top of the stack, and gives you back false in lua

and finally if things all go well it returns true
C++:
    player->sendTextMessage(message);
    pushBoolean(L, true);

    return 1;

there's other numbers of return values u can explore in luascript.cpp if u jsut ctrl+f for return 2 and return 0 and see what it looks like

here's a link to learn how a stack works: Stack Data Structure (Introduction and Program) - GeeksforGeeks (https://www.geeksforgeeks.org/stack-data-structure-introduction-program/)
Thanks bro, it helped me a lot. I'm going to see this link.
 
Back
Top