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

CreatureEvent [TFS 1.x] Anti MC

absoluten

std::cout
Joined
Apr 6, 2015
Messages
32
Reaction score
13
Location
Yalahar
Create a file in creaturescripts/scripts/with name: mctfs1.lua and put this code in archive:
Code:
local AccPorIp = 2

function onLogin(player) 

    local mc = 0
    for _, verificar in ipairs(Game.getPlayers()) do
        if player:getIp() == verificar:getIp() then
            mc = mc + 1
            if mc > AccPorIp then return false end
        end
    end
 
    return true
end


In creaturescripts.xml put this line:
Code:
<event type="login" name="Anti-Magebomb" script="mctfs1.lua"/>


ATTENTION! This script works in TFS 1.1 and 1.2 to TFS 1.0 change functions:
Code:
onLogin(player) --> onLogin(cid)
player:getIp() --> Player(cid):getIp()


Credits:
Absolute
Henrique
Luciana


Enjoy!
 
revscript?
Lua:
local AccPorIp = 2

local antiMcScript = CreatureEvent("antiMcScript")
function antiMcScript.onLogin(player)

    local mc = 0
    for _, verificar in ipairs(Game.getPlayers()) do
        if player:getIp() == verificar:getIp() then
            mc = mc + 1
            if mc > AccPorIp then return false end
        end
    end
 
    return true
end
antiMcScript:register()
 
This creaturecript have a critical bug. For example, if I have a 4 multi-client restriction, when I connect a 5th the 5th player will receive every onLogin event and inmediatly log-off. This, with a first items script, for example, causes item-dupe inmediatly. To fix this, @ michael helped me with this:

Lua:
local AccPorIp = 4

local antiMcScript = CreatureEvent("antiMcScript")
function antiMcScript.onLogin(player)

    local mc = 0
    for _, verificar in ipairs(Game.getPlayers()) do
        if player:getIp() == verificar:getIp() then
            mc = mc + 1
            local playerguid = player:getGuid()
if mc > AccPorIp then
  addEvent(function()
    local player = Player(playerguid)
    if player then
      player:remove()
    end
  end, 1000)
end
        end
    end
 
    return true
end
antiMcScript:register()
 
This creaturecript have a critical bug. For example, if I have a 4 multi-client restriction, when I connect a 5th the 5th player will receive every onLogin event and inmediatly log-off. This, with a first items script, for example, causes item-dupe inmediatly. To fix this, @ michael helped me with this:

Lua:
local AccPorIp = 4

local antiMcScript = CreatureEvent("antiMcScript")
function antiMcScript.onLogin(player)

    local mc = 0
    for _, verificar in ipairs(Game.getPlayers()) do
        if player:getIp() == verificar:getIp() then
            mc = mc + 1
            local playerguid = player:getGuid()
if mc > AccPorIp then
  addEvent(function()
    local player = Player(playerguid)
    if player then
      player:remove()
    end
  end, 1000)
end
        end
    end
 
    return true
end
antiMcScript:register()
Well this didn't worked either. Thanks to @Tofame he managed to add all this stuff in login.lua (includes welcome script, first items, anti-mc, and a little extra vocation regulation script).

Here's the recorded bug

And this is the clean code, just needs to be merged on login.lua

Lua:
local events = {
    'AdvanceSave'
}

local AccPorIp = 4

local config = {
    [0] = {
        --club, coat
        items = {{2398, 1}, {2461, 1}, {2467, 1}, {2649, 1}},
        --container rope, shovel, red apple
        container = {{2120, 1}, {2554, 1}, {2674, 2}}
    },   
    [1] = {
        --equipment spellbook, wand of vortex, magician's robe, mage hat, studded legs, leather boots, scarf
        items = {{2175, 1}, {2190, 1}, {8819, 1}, {8820, 1}, {2468, 1}, {2643, 1}, {2661, 1}},
        --container platinum coin, rope, shovel, mana potion
        container = {{7620, 5}}
    },
    [2] = {
        --equipment spellbook, snakebite rod, magician's robe, mage hat, studded legs, leather boots scarf
        items = {{2175, 1}, {2182, 1}, {8819, 1}, {8820, 1}, {2468, 1}, {2643, 1}, {2661, 1}},
        --container platinum coin, rope, shovel, mana potion
        container = {{7620, 5}}
    },
    [3] = {
        --equipment dwarven shield, 5 spear, ranger's cloak, ranger legs scarf, legion helmet
        items = {{2525, 1}, {2389, 5}, {2660, 1}, {8923, 1}, {2643, 1}, {2661, 1}, {2480, 1}},
        --container platinum coin, rope, shovel, health potion, mana potion
        container = {{7618, 5}, {7620, 5}}
    },
    [4] = {
        --equipment dwarven shield, steel axe, brass armor, brass helmet, brass legs scarf
        items = {{2525, 1}, {8601, 1}, {2465, 1}, {2460, 1}, {2478, 1}, {2643, 1}, {2661, 1}},
        --container platinum coin, jagged sword, daramian mace, rope, shovel, health potion, mana potion
        container = {{8602, 1}, {2439, 1}, {7618, 5}, {7620, 5}}
    }

}

function onLogin(player)
    local mc = 0
    for _, verificar in ipairs(Game.getPlayers()) do
        if player:getIp() == verificar:getIp() then
            mc = mc + 1
            if mc > AccPorIp then return false end
        end
    end
   
    local targetVocation = config[player:getVocation():getId()]

    local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!"
    if player:getLastLoginSaved() <= 0 then
        loginStr = loginStr .. " Please choose your outfit."
        player:sendOutfitWindow()
        player:openChannel(CHANNEL_DEFAULT)
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "If you wish to change your hometown talk to Kasmir, Quentin, Father Zuke or Isaaru and ask for a transfer.")
        -- First time login items
        if targetVocation then
            for i = 1, #targetVocation.items do
                player:addItem(targetVocation.items[i][1], targetVocation.items[i][2])
            end

            local backpack = player:getVocation():getId() == 0 and player:addItem(1987) or player:addItem(1988)
            if backpack then
                for i = 1, #targetVocation.container do
                    backpack:addItem(targetVocation.container[i][1], targetVocation.container[i][2])
                end
            end
        end
        -- First time login tell other players about it!
        print("\nWelcome to our newest member ["..player:getName().."]!\n")
        db.query("INSERT INTO `znote_global_storage` (`key`,`value`) VALUES ('1stLog_"..player:getAccountId().."', '"..os.time().."');")
        local players = Game.getPlayers()
        local playerName = player:getName()
        for _, onlineplayer in ipairs(players) do
            onlineplayer:sendTextMessage(MESSAGE_EVENT_ORANGE, "Welcome to our newest member ["..playerName.."]!")
        end
    else
        if loginStr ~= "" then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, loginStr)
            player:openChannel(CHANNEL_DEFAULT)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "The following talkactions are avaible: !bosscheck, !spells, !soft, !aol, !blesscheck, !critical, !dodge.")
        end
        loginStr = string.format("Your last visit was on %s.", os.date("%a %b %d %X %Y", player:getLastLoginSaved()))
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "If you wish to change your hometown talk to Kasmir, Quentin, Father Zuke or Isaaru and ask for a transfer.")
    end
    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, loginStr)

    -- Stamina
    nextUseStaminaTime[player.uid] = 0

    -- Promotion
    local vocation = player:getVocation()
    local promotion = vocation:getPromotion()
    local value = player:getStorageValue(PlayerStorageKeys.promotion)
        if value == 1 then
            player:setVocation(promotion)
    end
   

    -- Events
    player:registerEvent("PlayerDeath")
    player:registerEvent("DropLoot")
       
     -- Fix HP/Mana/Cap to match CIP, assume player left rook at level 8
    if player:getVocation():getId() == 0 then
       
        calchp = 5 * (player:getLevel() + 29)
        calcmana = 5 * (player:getLevel() + 10)
        calccap = 10 * (player:getLevel() + 39)
       
    elseif player:getVocation():getId() == 1 or player:getVocation():getId() == 5 then
       
        calchp = 5 * (player:getLevel() + 29)
        calcmana = 5 * ((6 * player:getLevel()) - (5 * 8) + 10)
        calccap = 10 * (player:getLevel() + 39)
       
    elseif player:getVocation():getId() == 2 or player:getVocation():getId() == 6 then
       
        calchp = 5 * (player:getLevel() + 29)
        calcmana = 5 * ((6 * player:getLevel()) - (5 * 8) + 10)
        calccap = 10 * (player:getLevel() + 39)
       
    elseif player:getVocation():getId() == 3 or player:getVocation():getId() == 7 then
       
        calchp = 5 * ((2 * player:getLevel()) - 8 + 29)
        calcmana = 5 * ((3 * player:getLevel())- (2 * 8) + 10)
        calccap = 10 * ((2 * player:getLevel()) - 8 + 39)
       
    elseif player:getVocation():getId() == 4 or player:getVocation():getId() == 8 then
       
        calchp = 5 *((3 * player:getLevel()) - (2 * 8) + 29)
        calcmana = 5 *(player:getLevel() + 10)
        calccap = 5 *((5 * player:getLevel()) - (5 * 8) + 94)
       
    end  

    if player:getMaxHealth() ~= calchp then
        player:setMaxHealth(calchp)
        player:addHealth(calchp)
   
    end
   
    if player:getMaxMana() ~= calcmana then
        player:setMaxMana(calcmana)
        player:addMana(calcmana)
   
    end
   
    if player:getCapacity() ~= (calccap * 100) then
        player:setCapacity(calccap * 100)
   
    end  
        player:setOutfit(player:getOutfit())
    return true
end

Regards!
 
Last edited:
And this is the clean code, just needs to be merged on login.lua
this code seems far from clean 😅 you forgot to remove a lot of stuff that are from your server only and are not present in a clean login script

there is no issue at all with the OP code, your issue was because the code was being executed AFTER the first item code part and not BEFORE
 
this code seems far from clean 😅 you forgot to remove a lot of stuff that are from your server only and are not present in a clean login script

there is no issue at all with the OP code, your issue was because the code was being executed AFTER the first item code part and not BEFORE

You're right on this. Anyways the code is there for reference if anyone wish to use it. Regards!
 
just fyi
if a player kicks an already connected character, it will not execute 'onLogin'
so, if someone have 2 ips (or a vm) he can:
login on ip2 then connect/kick in ip1
and stay online with how many characters he wont...
so, i prefer using it as a global event:

Lua:
-- Anti-MC = Limit max player connections at the same IP.
local maxPlayersPerIp = 2
local kickDelay = 10 -- seconds
local ignoreAccountType = 4 -- ignore players with account type above this value
local function kickPlayer(name)
  if Player(name) then Player(name):remove() end
end
function onThink(interval)
  local c = {}
  local players = Game.getPlayers()
  for i = #players,1,-1 do
    local player = players[i]
    local ip = player:getIp()
    if player:getAccountType() <= ignoreAccountType then
      if not c[ip] then
        c[ip] = 1
      else
        c[ip] = c[ip] + 1
        if c[ip] > maxPlayersPerIp then
          player:sendTextMessage(MESSAGE_STATUS_WARNING,"You have exceeded the limit of "..maxPlayersPerIp.." connections per IP. You will be disconnected in "..kickDelay.." seconds.")
          local name = player:getName()
          addEvent(kickPlayer,kickDelay*1000,name)
        end
      end
    end
  end
  return true
end
 
Back
Top