• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

RevScripts BLOCK MC PVP

Bee King

Well-Known Member
Joined
May 9, 2024
Messages
128
Reaction score
56

Hello everyone,

My server allows MC (multi-client), but I want it to be used exclusively for progression, not for PVP...

I've seen on some servers that MC PVP is blocked — for example, if a player with the same IP has a character with a skull, other characters using the same IP cannot attack, get a skull, etc.

Does anyone have an idea how to make this work?

I’m using TFS 1.5 downgrade NekiRo 8.0...

I’ve already added a system where the player only gets a skull if they have their hand closed (similar to modern open PVP mechanics). Now I’d like to add a feature to block PVP between characters using the same IP.

Here’s my security mode — I think the change should be made here:

data/scripts/security.lua


LUA:
local ec = EventCallback

ec.onTargetCombat = function(self, target)
    if self and self:isMonster() then
        return true
    end
    if self and self:hasSecureMode() then
        if target:isPlayer() then
            return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE
        end
    end

    return RETURNVALUE_NOERROR
end

ec:register()


 
You can use the function below to perform these checks before attacking the target.

C++:
bool Player::setAttackedCreature(Creature* creature)
{
    if (!Creature::setAttackedCreature(creature)) {
        sendCancelTarget();
        return false;
    }

    if (chaseMode && creature) {
        if (followCreature != creature) {
            //chase opponent
            setFollowCreature(creature);
        }
    } else if (followCreature) {
        setFollowCreature(nullptr);
    }

    if (creature) {
        g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game, getID())));
    }
    return true;
}
 
This change made directly in security.lua — can you check if there are any flaws? Maybe I’ll try it this way if it’s easier.



LUA:
local ec = EventCallback

-- Retorna o primeiro jogador do IP (o "principal" que pode PVP)
local function getFirstPlayerByIp(ip)
    for _, pid in ipairs(Game.getPlayers()) do
        if pid:getIp() == ip then
            return pid
        end
    end
    return nil
end

ec.onTargetCombat = function(self, target)
    -- Permite atacar monstros normalmente
    if target and target:isMonster() then
        return RETURNVALUE_NOERROR
    end

    -- Verifica ataques entre players
    if self and target and self:isPlayer() and target:isPlayer() then
        local attackerIp = self:getIp()
        local firstPlayer = getFirstPlayerByIp(attackerIp)

        -- Se o atacante não for o primeiro player do IP, bloqueia PVP
        if firstPlayer and firstPlayer:getId() ~= self:getId() then
            self:sendCancelMessage("Apenas um personagem por IP pode participar de PVP.")
            return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE
        end
    end

    -- Mantém o comportamento do modo seguro (secure mode)
    if self and self:hasSecureMode() and target and target:isPlayer() then
        return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE
    end

    return RETURNVALUE_NOERROR
end

ec:register()
 
Last edited:
try this code:

LUA:
local ec = EventCallback

-- Verifica se já existe algum jogador do mesmo IP em combate PVP
local function hasIpInPvp(ip, excludePlayer)
    for _, player in ipairs(Game.getPlayers()) do
        if player:getIp() == ip and player:getId() ~= excludePlayer:getId() then
            -- Verifica se o jogador tem skull (está em PVP)
            if player:getSkull() > SKULL_NONE then
                return true, player:getName()
            end

            -- Ou verifica se está atacando outro jogador
            local target = player:getTarget()
            if target and target:isPlayer() then
                return true, player:getName()
            end
        end
    end
    return false, nil
end

ec.onTargetCombat = function(self, target)
    -- Permite atacar monstros normalmente
    if target and target:isMonster() then
        return RETURNVALUE_NOERROR
    end

    -- Verifica ataques entre players
    if self and target and self:isPlayer() and target:isPlayer() then
        local attackerIp = self:getIp()
        
        -- Bloqueia se outro char do mesmo IP já estiver em PVP
        local hasOtherInPvp, otherCharName = hasIpInPvp(attackerIp, self)
        if hasOtherInPvp then
            self:sendCancelMessage("Outro personagem do seu IP (" .. otherCharName .. ") já está em combate PVP.")
            return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE
        end
    end

    -- Mantém o comportamento do modo seguro (secure mode)
    if self and self:hasSecureMode() and target and target:isPlayer() then
        return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE
    end

    return RETURNVALUE_NOERROR
end

ec:register()
 
It didn’t work for the part where you can only get PK with a closed hand… I made some changes and now everything works fine. The red trap and MC PvP are gone xD thanks!




LUA:
local ec = EventCallback

-- Verifica se já existe algum jogador do mesmo IP em combate PVP
local function hasIpInPvp(ip, excludePlayer)
    for _, player in ipairs(Game.getPlayers()) do
        if player:getIp() == ip and player:getId() ~= excludePlayer:getId() then
            -- Verifica se o jogador tem skull (está em PVP)
            if player:getSkull() > SKULL_NONE then
                return true, player:getName()
            end

            -- Ou verifica se está atacando outro jogador
            local target = player:getTarget()
            if target and target:isPlayer() then
                return true, player:getName()
            end
        end
    end
    return false, nil
end

ec.onTargetCombat = function(self, target)
    -- Permite que monstros ataquem normalmente
    if self and self:isMonster() then
        return RETURNVALUE_NOERROR
    end

    -- Verifica ataques entre players
    if self and target and self:isPlayer() and target:isPlayer() then
        local attackerIp = self:getIp()
        
        -- Bloqueia se outro char do mesmo IP já estiver em PVP
        local hasOtherInPvp, otherCharName = hasIpInPvp(attackerIp, self)
        if hasOtherInPvp then
            self:sendCancelMessage("Outro personagem do seu IP (" .. otherCharName .. ") já está em combate PVP.")
            return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE
        end
    end

    -- Mantém o comportamento do modo seguro (secure mode)
    if self and self:hasSecureMode() and target and target:isPlayer() then
        return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE
    end

    return RETURNVALUE_NOERROR
end

ec:register()
 
Back
Top