Impossible to prevent bucket item use
#1
Currently I'm trying to block item use, and even though it seems to work fine for preventing flint and steel use, any bucket just refuses.
No matter if I return true (preventing use) or false (allowing use) using HOOK_PLAYER_USING_ITEM, the bucket is used.
If it's a waterbucket the water is placed, if it's a lavabucket the lava is placed, if it's an empty bucket then whatever fluid was there before is now in the bucket.

Again, I can prevent flint and steel fine with this method, and Player:GetEquippedItem() does show the proper bucket when logged.
I'm not sure what's happening here, is it a bug in Cuberite?
Reply
Thanks given by:
#2
Try the OnPlayerRightClick hook instead. I do believe we should call the OnPlayerUsingItem hook when the bucket is used though.
Reply
Thanks given by:
#3
Well it is called, that's the thing. The action is just not prevented. I'll try OnPlayerRightClick though.

EDIT: Bucket use can't be prevented using that hook either.
Reply
Thanks given by:
#4
Could you upload the code?
Reply
Thanks given by:
#5
local sql = "SELECT towns.town_id, towns.nation_id, towns.town_permissions FROM townChunks INNER JOIN towns ON townChunks.town_id = towns.town_id WHERE chunkX = ? AND chunkZ = ? AND world = ?";
    local parameters = {math.floor(BlockX / 16), math.floor(BlockZ / 16), Player:GetWorld():GetName()};
    local town = ExecuteStatement(sql, parameters)[1];

    if not (town) then --The item is used on a block that is not part of a town, so it's allowed
        return false;
    else
        if (town[1] == GetPlayerTown(Player:GetUUID())) then
            allowed = CheckPermission(town[3], RESIDENTITEMUSE);
        else
            if (town[2] == GetPlayerNation(Player:GetUUID())) then
                allowed = CheckPermission(town[3], ALLYITEMUSE);
            else
                allowed = CheckPermission(town[3], OUTSIDERITEMUSE);
            end
        end

        if (allowed == true) then
            if (ItemToString(Player:GetEquippedItem()) == "lighter") then
                local sql = "SELECT towns.town_id, towns.town_fire_enabled FROM towns INNER JOIN townChunks ON towns.town_id = townChunks.town_id WHERE townChunks.chunkX = ? AND townChunks.chunkZ = ? AND townChunks.world = ?";
                local parameters = {math.floor(BlockX / 16), math.floor(BlockZ / 16), Player:GetWorld():GetName()};
                local town = ExecuteStatement(sql, parameters)[1];

                if (town and town[2] == 0) then --If fire is disabled in this town, prevent the player from starting a fire
                    return true; --Prevent item use
                else
                    return false; --Allow item use
                end
            else
                return false; --Allow item use
            end
        else
            return true; --Prevent item use
        end
    end
The CheckPermission function returns either true or false depending on if it's allowed or not.
Reply
Thanks given by:
#6
I've tried a simple
cPluginManager:AddHook(cPluginManager.HOOK_PLAYER_RIGHT_CLICK, function() return true end)
and it prevented the placements of buckets. On occasion the water/lava was there, but it was only client-side as it wasn't there anymore when re-logging. Are you sure your code is correct everywhere and returns true when it needs to?
Reply
Thanks given by:
#7
Just returning true does indeed block the use somehow... However, I'm 100% sure it doesn't with more code, no idea why. I literally have LOG('test') 1 row before returning true, and even though it does log the 'test', it allows bucket use.

Ooh and the water showing up while it's not actually placed, is related to this issue.
Reply
Thanks given by:
#8
OnPlayerRightClick (Maybe OnPlayerUsingItem as well) gets called twice. Once with a BLOCK_FACE_NONE parameter. Perhaps the LOG('test') is called from that?
Reply
Thanks given by:
#9
Yeah I just found that out, OnPlayerUsingItem gets called twice as well. If I LOG(town) then the first time it returns fine, the second time time will be a nil value. It seems the second time BlockX and BlockY both return -1 instead of the actual block that is being changed, meaning the query won't find anything, meaning it will return false at the first conditional statement.

Why exactly is it called twice? And how would I now prevent buckets from being placed like this?
Reply
Thanks given by:
#10
It's called twice because the client sends it twice. This allows things like fishing since you don't have a block selected in the world as well. It also makes the compass tool in WorldEdit possible.
Reply
Thanks given by:




Users browsing this thread: 2 Guest(s)