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

UPDATE 3: Moveitem + Antipush + Anti-Crash Elf Bot - Bug Fixes - TFS 0.4 11/04/2024

alexxxxxxx

Member
Joined
Aug 16, 2015
Messages
10
Reaction score
15
Location
Brasil
GitHub
l3k0t
YouTube
UCMP25Br519j7dD1FF
huepix9_10_111551.png.88526652870dc8bec26af7285b9566ba.png.b10f8027f16d174ed30e52adda1dda38.png

TUTORIAL BY L3K0T EN TFS 0.4



Hello everyone, I bring you an update I made to the system, containing 3 new item movement functionalities and protection against Elf Bot. These additions have been carefully implemented to enhance the gaming experience and maintain the integrity of your server.

The new functionalities have the vital function of preventing players from leaving unwanted items in inappropriate locations, such as at the entrance of their house, on top of their depots, or on teleports. Now, only owners, sub-owners, and invited guests have permission to manipulate items in these locations.

This update package has been meticulously reviewed to prevent abuse by malicious players and ensure a fair and balanced gaming environment for all users.


Starting the Tutorial

Open the file "creatureevents.cpp" with your preferred text editor. I personally recommend Notepad++. Search for :

In creatureevents.cpp
C++:
return "onPrepareDeath";

Add below:
C++:
case CREATURE_EVENT_MOVEITEM:
return "onMoveItem";
case CREATURE_EVENT_MOVEITEM2:
return "onMoveItem2";

in:
C++:
return "cid, deathList";

Add below:
C++:
case CREATURE_EVENT_MOVEITEM:
return "moveItem, frompos, topos, cid";
case CREATURE_EVENT_MOVEITEM2:
return "cid, item, count, toContainer, fromContainer, fromPos, toPos";

In:
C++:
m_type = CREATURE_EVENT_PREPAREDEATH;

Add below:
C++:
else if(tmpStr == "moveitem")
m_type = CREATURE_EVENT_MOVEITEM;
else if(tmpStr == "moveitem2")
m_type = CREATURE_EVENT_MOVEITEM2;

Search for:
C++:
bool CreatureEvents::playerLogout(Player* player, bool forceLogout)
{
    //fire global event if is registered
    bool result = true;
    for(CreatureEventList::iterator it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it)
    {
        if((*it)->getEventType() == CREATURE_EVENT_LOGOUT && (*it)->isLoaded()
            && !(*it)->executeLogout(player, forceLogout) && result)
            result = false;
    }

    return result;
}

Add below:
C++:
uint32_t CreatureEvents::executeMoveItems(Creature* actor, Item* item, const Position& frompos, const Position& pos)
{
    // fire global event if is registered
    for(CreatureEventList::iterator it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it)
    {
        if((*it)->getEventType() == CREATURE_EVENT_MOVEITEM)
        {
            if(!(*it)->executeMoveItem(actor, item, frompos, pos))
                return 0;
        }
    }
    return 1;
}

in:
C++:
bool CreatureEvents::playerLogin(Player* player)
{
    //fire global event if is registered
    bool result = true;
    for(CreatureEventList::iterator it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it)
    {
        if((*it)->getEventType() == CREATURE_EVENT_LOGIN && (*it)->isLoaded()
            && !(*it)->executeLogin(player) && result)
            result = false;
    }
 
    if (result)
    {
        for(CreatureEventList::iterator it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it)
            {
                CreatureEvent* event = *it;
                if(event->isLoaded() && ( event->getRegister() == "player" || event->getRegister() == "all") )
                    player->registerCreatureEvent(event->getName());
            }
    }

    return result;
}

Add below:
C++:
uint32_t CreatureEvent::executeMoveItem(Creature* actor, Item* item, const Position& frompos, const Position& pos)
{
    //onMoveItem(moveItem, frompos, position, cid)
    if(m_interface->reserveEnv())
    {
        ScriptEnviroment* env = m_interface->getEnv();
        if(m_scripted == EVENT_SCRIPT_BUFFER)
        {
            env->setRealPos(pos);
            std::stringstream scriptstream;

            env->streamThing(scriptstream, "moveItem", item, env->addThing(item));
            env->streamPosition(scriptstream, "position", frompos, 0);

            env->streamPosition(scriptstream, "position", pos, 0);
            scriptstream << "local cid = " << env->addThing(actor) << std::endl;

            scriptstream << m_scriptData;
            bool result = true;
            if(m_interface->loadBuffer(scriptstream.str()))
            {
                lua_State* L = m_interface->getState();
                result = m_interface->getGlobalBool(L, "_result", true);
            }

            m_interface->releaseEnv();
            return result;
        }
        else
        {
            #ifdef __DEBUG_LUASCRIPTS__
            char desc[35];
            sprintf(desc, "%s", player->getName().c_str());
            env->setEventDesc(desc);
            #endif

            env->setScriptId(m_scriptId, m_interface);
            env->setRealPos(pos);

            lua_State* L = m_interface->getState();
            m_interface->pushFunction(m_scriptId);

            LuaInterface::pushThing(L, item, env->addThing(item));
            LuaInterface::pushPosition(L, frompos, 0);
            LuaInterface::pushPosition(L, pos, 0);

            lua_pushnumber(L, env->addThing(actor));
            bool result = m_interface->callFunction(4);
            m_interface->releaseEnv();
            return result;
        }
    }
    else
    {
        std::clog << "[Error - CreatureEvent::executeMoveItem] Call stack overflow." << std::endl;
        return 0;
    }
}

uint32_t CreatureEvent::executeMoveItem2(Player* player, Item* item, uint8_t count, const Position& fromPos, const Position& toPos, Item* toContainer, Item* fromContainer, int16_t fstack)
{
    //onMoveItem2(cid, item, count, toContainer, fromContainer, fromPos, toPos)
    if(m_interface->reserveEnv())
    {
        ScriptEnviroment* env = m_interface->getEnv();
        if(m_scripted == EVENT_SCRIPT_BUFFER)
        {
            env->setRealPos(player->getPosition());
            std::stringstream scriptstream;
            scriptstream << "local cid = " << env->addThing(player) << std::endl;

            env->streamThing(scriptstream, "item", item, env->addThing(item));
            scriptstream << "local count = " << count << std::endl;
            env->streamThing(scriptstream, "toContainer", toContainer, env->addThing(toContainer));
            env->streamThing(scriptstream, "fromContainer", fromContainer, env->addThing(fromContainer));
            env->streamPosition(scriptstream, "fromPos", fromPos, fstack);
            env->streamPosition(scriptstream, "toPos", toPos, 0);


            scriptstream << m_scriptData;
            bool result = true;
            if(m_interface->loadBuffer(scriptstream.str()))
            {
                lua_State* L = m_interface->getState();
                result = m_interface->getGlobalBool(L, "_result", true);
            }

            m_interface->releaseEnv();
            return result;
        }
        else
        {
            #ifdef __DEBUG_LUASCRIPTS__
            char desc[30];
            sprintf(desc, "%s", player->getName().c_str());
            env->setEvent(desc);
            #endif

            env->setScriptId(m_scriptId, m_interface);
            env->setRealPos(player->getPosition());

            lua_State* L = m_interface->getState();
            m_interface->pushFunction(m_scriptId);

            lua_pushnumber(L, env->addThing(player));

            LuaInterface::pushThing(L, item, env->addThing(item));
            lua_pushnumber(L, count);
            LuaInterface::pushThing(L, toContainer, env->addThing(toContainer));
            LuaInterface::pushThing(L, fromContainer, env->addThing(fromContainer));
            LuaInterface::pushPosition(L, fromPos, fstack);
            LuaInterface::pushPosition(L, toPos, 0);

            //lua_pushnumber(L, env->addThing(actor));
            bool result = m_interface->callFunction(7);
            m_interface->releaseEnv();
            return result;
        }
    }
    else
    {
        std::clog << "[Error - CreatureEvent::executeMoveItem] Call stack overflow." << std::endl;
        return 0;
    }
}

Now in creatureevents.h in:
C++:
CREATURE_EVENT_PREPAREDEATH,

Add below:
C++:
CREATURE_EVENT_MOVEITEM,
CREATURE_EVENT_MOVEITEM2

in:
C++:
uint32_t executePrepareDeath(Creature* creature, DeathList deathList);

Add below:
C++:
uint32_t executeMoveItem(Creature* actor, Item* item, const Position& frompos, const Position& pos);
uint32_t executeMoveItem2(Player* player, Item* item, uint8_t count, const Position& fromPos, const Position& toPos, Item* toContainer, Item* fromContainer, int16_t fstack);

in:
C++:
bool playerLogout(Player* player, bool forceLogout);

Add below:
C++:
uint32_t executeMoveItems(Creature* actor, Item* item, const Position& frompos, const Position& pos);
uint32_t executeMoveItem2(Player* player, Item* item, uint8_t count, const Position& fromPos, const Position& toPos, Item* toContainer, Item* fromContainer, int16_t fstack);


Now in game.cpp:
C++:
    if(!canThrowObjectTo(mapFromPos, mapToPos) && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere))
    {
        player->sendCancelMessage(RET_CANNOTTHROW);
        return false;
    }
 
    ReturnValue ret = internalMoveItem(player, fromCylinder, toCylinder, toIndex, item, count, NULL);
    if(ret == RET_NOERROR)
        return true;
    player->sendCancelMessage(ret);
    return false;
}

Change for:
C++:
if (!canThrowObjectTo(mapFromPos, mapToPos) && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere)) {
    player->sendCancelMessage(RET_CANNOTTHROW);
    return false;
}


bool success = true;
CreatureEventList moveitemEvents = player->getCreatureEvents(CREATURE_EVENT_MOVEITEM2);
for (CreatureEventList::iterator it = moveitemEvents.begin(); it != moveitemEvents.end(); ++it) {
    Item* toContainer = toCylinder->getItem();
    Item* fromContainer = fromCylinder->getItem();
    if (!(*it)->executeMoveItem2(player, item, count, fromPos, toPos, (toContainer ? toContainer : 0), (fromContainer ? fromContainer : 0), fromStackpos) && success)
        success = false;
}

if (!success)
    return false;


if (g_config.getBool(ConfigManager::ANTI_PUSH)) {
    std::string antiPushItems = g_config.getString(ConfigManager::ANTI_PUSH_ITEMS);
    IntegerVec tmpVec = vectorAtoi(explodeString(antiPushItems, ","));
    if (tmpVec[0] != 0) {
        for (IntegerVec::iterator it = tmpVec.begin(); it != tmpVec.end(); ++it) {
            if (item->getID() == uint32_t(*it) && player->hasCondition(CONDITION_EXHAUST, 1)) {
                player->sendTextMessage(MSG_STATUS_SMALL, "Please wait a few seconds to move this item.");
                return false;
            }
        }
    }
}


int32_t delay = g_config.getNumber(ConfigManager::ANTI_PUSH_DELAY);
if (Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_EXHAUST, delay, 0, false, 1))
    player->addCondition(condition);


if (!g_creatureEvents->executeMoveItems(player, item, mapFromPos, mapToPos))
    return false;


ReturnValue ret = internalMoveItem(player, fromCylinder, toCylinder, toIndex, item, count, NULL);
if (ret != RET_NOERROR) {
    player->sendCancelMessage(ret);
    return false;
}


player->setNextAction(OTSYS_TIME() + g_config.getNumber(ConfigManager::ACTIONS_DELAY_INTERVAL) - 10);
return true;
}


Now in configmanager.h
C++:
ADMIN_ENCRYPTION_DATA

Add below:
C++:
ANTI_PUSH_ITEMS,

in:
C++:
STAMINA_DESTROY_LOOT,

Add below:
C++:
ANTI_PUSH_DELAY,


in:
C++:
ADDONS_PREMIUM,

Add below:
C++:
ANTI_PUSH
Now you can compile the Source.

Now you can compile the Source. Thanks All = TY

Configuring on the server


Open your server's config.lua file and add this anywhere inside:

Add:
C++:
-- Anti-Push
useAntiPush = true
antiPushItems = "2148,2152,2160,3976"
antiPushDelay = 500


Navigate to the 'creaturescripts' directory and locate the file 'login.lua'.
In event registrations, add:

login.lua
Lua:
registerCreatureEvent(cid, "MoveItem")
registerCreatureEvent(cid, "MoveItem2")

Create a new Lua file in scripts named houseprotection.lua and add this:
C++:
function onMoveItem(moveItem, frompos, position, cid)

    if position.x == CONTAINER_POSITION then
        return true
    end

    local house = getHouseFromPos(frompos) or getHouseFromPos(position) --correção 100%
    if type(house) == "number" then
 
        local owner = getHouseOwner(house)
 
        if owner == 0 then
            return false, doPlayerSendCancel(cid, "Isso não é Possível.")
        end
 
        if owner ~= getPlayerGUID(cid) then
            local sub = getHouseAccessList(house, 0x101):explode("\n")
            local guest = getHouseAccessList(house, 0x100):explode("\n")
            local isInvited = false

            if (#sub > 0) and isInArray(sub, getCreatureName(cid)) then
                isInvited = true
            end
   
            if (#guest > 0) and isInArray(guest, getCreatureName(cid)) then
                isInvited = true
            end

            if not isInvited then
                return false, doPlayerSendCancel(cid, "Desculpe, você não está invitado.")
            end
     
        end
    end
 
    return true
end

Create a new Lua file in scripts named moveitem2.lua and add the following below:
C++:
local depottiles = {} --piso pra n jogar
local depots = {2589} --id dos dps
local group = 3 --id dos group 6 é todos.
 
local function checkIfThrow(pos,topos)
                    if topos.x == 0xffff then
                        return false
                    end
                local thing = getThingFromPos(pos)
                if isInArray(depottiles,thing.itemid) then
                            if not isInArea(topos,{x=pos.x-1,y=pos.y-1,z=pos.z},{x=pos.x+1,y=pos.y+1, z=pos.z}) then            
                            return true
                        end
                else
                for i = 1, #depots do
                    if depots[i] == getTileItemById(topos,depots[i]).itemid or getTileInfo(topos).actionid == 7483 then
                        return true
                    end
                end
            end                        
    return false
end


function onMoveItem2(cid, item, count, toContainer, fromContainer, fromPos, toPos)
    if isPlayer(cid) then
        local pos = getThingPos(cid)
            if getPlayerGroupId(cid) > group then
                return true
        end
   
        if checkIfThrow({x=pos.x,y=pos.y,z=pos.z,stackpos=0},toPos) then
            doPlayerSendCancel(cid,"Não jogue item ai!!")
            doSendMagicEffect(getThingPos(cid),CONST_ME_POFF)
            return false
        end
    end
    return true
fim
Ready!
REP+

Credits:

@L3K0T = I
Fir3element
Summ
Wise
GOD Wille
Yan Lima"​
 
Last edited:
This is actually pretty smart idea! I love it! I may have to re-implement it for Black Tek Server
 
Back
Top