Cuberite反作弊插件编写

点击查看代码
function Initialize(Plugin)
    Plugin:SetName("Anticheat")
    Plugin:SetVersion(1)

    cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_MOVING, OnPlayerMoving)

    LOG("Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
    return true
end
local playerData = {}

function OnPlayerMoving(Player)
    local playerName = Player:GetName()
    
    -- 初始化玩家数据
    if not playerData[playerName] then
        playerData[playerName] = {
            groundPos = Player:GetPosition(),
            groundY = Player:GetPosY(),  -- 初始地面高度
            lastY = Player:GetPosY()
        }
    end

    -- 更新地面基准高度
    if Player:IsOnGround() then
        playerData[playerName].groundPos = Player:GetPosition()
        playerData[playerName].groundY = Player:GetPosY()
    end

    -- 计算垂直位移并发送
    local currentY = Player:GetPosY()
    local deltaY = currentY - playerData[playerName].groundY
    if deltaY > 1.3 then  -- 过滤微小波动
        Player:SendMessage(string.format("垂直位移: %.2f 米 ", deltaY))
        Player:SendMessage(playerData[playerName].groundY)
        Player:SetPosition(playerData[playerName].groundPos)
        return true
    end
    local pos = Player:GetPosition()
    local world = Player:GetWorld()
    
    -- 定义碰撞箱范围
    local minPos = Vector3i(
        math.floor(pos.x - 0.3),
        math.floor(pos.y),
        math.floor(pos.z - 0.3)
    )
    local maxPos = Vector3i(
        math.floor(pos.x + 0.3),
        math.floor(pos.y + 1.8),
        math.floor(pos.z + 0.3)
    )
    
    -- 遍历所有可能碰撞的方块
    for x = minPos.x, maxPos.x do
        for y = minPos.y, maxPos.y do
            for z = minPos.z, maxPos.z do
                local blockID = world:GetBlock(Vector3i(x, y, z))
                if cBlockInfo:IsSolid(blockID) then
                    Player:SetPosition(pos) -- 回传原位
                    return true -- 阻断移动
                end
            end
        end
    end
    return false
end
local playerStatus = {}  -- 玩家状态表结构: { [玩家名] = { lastHurtTime = 0, isFlying = false } }

-- 自动清理过期数据
local function CleanupPlayerData()
    local now = os.time()
    for name, data in pairs(playerStatus) do
        if (now - data.lastHurtTime) > 300 then  -- 5分钟无活动清理数据
            playerStatus[name] = nil
        end
    end
end
function OnTakeDamage(Receiver, TDI)
    LOG("Damage: Raw ".. TDI.RawDamage .. ", Final:" .. TDI.FinalDamage);

    -- If the attacker is a spider, make it deal 999 points of damage (insta-death spiders):
    if ((TDI.Attacker ~= nil) and TDI.Attacker:IsA("cSpider")) then
        TDI.FinalDamage = 999;
    end
end
cPluginManager.AddHook(cPluginManager.HOOK_TAKE_DAMAGE, OnTakeDamage)

-- 注册钩子
cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_MOVING, OnPlayerMoving)

参考资料

https://api.cuberite.org/cPlayer.html

posted @ 2025-05-03 09:32  meny  阅读(34)  评论(0)    收藏  举报