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

[Error - MoveEvent::executeStep] Call stack overflor

president vankk

Web Developer & AuraOT Owner
Joined
Jul 10, 2009
Messages
5,719
Solutions
9
Reaction score
339
Everyone know this bug exist, is the stranger to anyone. A guy called Bruno Minervino posted it on Otland's GitHub and nobody give attention to this seriously bug. Has this bug on last commit of TFS 1.2!

To the people who don't know the bug is this:

He was trying it:
Code:
bool MoveEvent::executeStep(Creature* creature, Item* item, const Position& pos, const Position& fromPos)
{
  //onStepIn(creature, item, pos, fromPosition)
  //onStepOut(creature, item, pos, fromPosition)
  if (!m_scriptInterface->reserveScriptEnv()) {
  std::cout << "[Error - MoveEvent::executeStep] Call stack overflow" << std::endl;
  return false;
  }

  ScriptEnvironment* env = m_scriptInterface->getScriptEnv();
  env->setScriptId(m_scriptId, m_scriptInterface);

  lua_State* L = m_scriptInterface->getLuaState();

  m_scriptInterface->pushFunction(m_scriptId);
  LuaScriptInterface::pushUserdata<Creature>(L, creature);
  LuaScriptInterface::setCreatureMetatable(L, -1, creature);
  LuaScriptInterface::pushThing(L, item);
  LuaScriptInterface::pushPosition(L, pos);
  Tile* tile = g_game.map.getTile(fromPos);
  Player* player = creature->getPlayer();
  LuaScriptInterface::pushPosition(L, !tile->getGround()->isBlocking ? fromPos : player->getTemplePosition());
  return m_scriptInterface->callFunction(4);
}

GitHub

If anyone interested to help the community will be happy!
 
Why do you give the source code?

Show the lua code which teleports to underwater and get him back from underwater.
 
This problem happens with the function fromPosition. If have a fromPosition then probably you can crash it.

The lua code you can use this https://github.com/otland/forgottenserver/blob/master/data/movements/scripts/walkback.lua

I have the code below for TFS 0.4 to prevent this bug but probably it won't work with TFS 1.2
Code:
if(lastPosition.x == 0) then -- player just logged in
     lastPosition = getTownTemplePosition(getPlayerTown(cid))
     doSendMagicEffect(lastPosition, CONST_ME_TELEPORT)
   end
 
Last edited:
I helped him solve it yesterday. It is not a TFS bug, it can happen whenever your script sends the player to a position that will fire another move event, in this case the invisible tile sends the player to another invisible tile, both fire the same move event and that will start an infinite loop, not because of some bug in TFS, but because the script is unsafe. It's the script responsibility not to start a chain of unending events, because TFS has no way to know that your script is unsafe, nor it should. This is a pseudocode on how to avoid the stack overflow for that specific issue:

Code:
function onStepIn(player, item, position, fromPosition)
        if player:cantDive() then
                --[[
                        This is where you should be careful, because if fromPosition
                        fires this same event, we will start an infinite loop.
                ]]
                --player:teleportTo(fromPosition, false)
                if Tile(fromPosition):getGround():getActionId() == ACTION_ID then
                        player:teleportTo(BOAT_POSITION --[[TEMPLE_POSITION]], false)
                else
                        -- Now it's safe to do this
                        player:teleportTo(fromPosition, false)
                end
        end
        return true
end

Hope it helps,

Non Sequitur
 
@Non Sequitur
It can happens with chests too.

For the same reason, the script (for quest chests it's walkback.lua) teleports the player to a unsafe position. This should fix it:

Code:
local function isQuestChest(item)
    local itemid = item:getId()
    if itemid == 1738 or itemid == 1740 or (itemid >= 1746 and itemid <= 1749) then
        return true
    end
end

local function isWalkable(item)
    if item.uid > 0 and item.uid <= 65535 then
        return false
    end
    return true
end

local function isPositionSafe(position)
    local tile = Tile(position)
    for _, item in ipairs(tile:getItems()) do
        if isQuestChest(item) and not isWalkable(item) then
            return false
        end
    end
    return true
end

function onStepIn(creature, item, position, fromPosition)
    if not isWalkable(item) then
        if creature:isPlayer() then
            local safePosition = creature:getTown():getTemplePosition()

            if position.x == fromPosition.x and position.y == fromPosition.y and position.z == fromPosition.z then
                creature:teleportTo(safePosition, false)
                return true
            elseif not isPositionSafe(fromPosition) then
                creature:teleportTo(safePosition, false)
                return true
            end          
        end

        creature:teleportTo(fromPosition, false)
    end
    return true
end
 
The problem here is that the last position is a magicWall, so waht you should do is to remove the magicwall from position, and teleport player back to the position.

It can be done on lua in a few lines, that's how @Colors solved it.
 
Back
Top