1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-07-14 16:02:57 +00:00
Jonathan Coates 7436447a6e
Several command permission fixes
- Attach permission checks to the first argument (so the literal
   command name) rather than the last argument. This fixes commands
   showing up when they shouldn't.

 - HelpingArgumentBuilder now inherits permissions of its leaf nodes.
   This only really impacts the "track" subcommand.

 - Don't autocomplete the computer selector for the "queue" subcommand.
   As everyone has permission for this command, it's possible to find
   all computer ids and labels in the world.

   I'm in mixed minds about this, but don't think this is an exploit -
   computer ids/labels are sent to in-range players so shouldn't be
   considered secret - but worth patching none-the-less.
2023-07-06 23:41:23 +01:00

97 lines
2.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.command;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.MinecraftServer;
import java.util.function.Predicate;
/**
* The level a user must be at in order to execute a command.
*/
public enum UserLevel implements Predicate<CommandSource>
{
/**
* Only can be used by the owner of the server: namely the server console or the player in SSP.
*/
OWNER,
/**
* Can only be used by ops.
*/
OP,
/**
* Can be used by any op, or the player in SSP.
*/
OWNER_OP,
/**
* Can be used by anyone.
*/
ANYONE;
public int toLevel()
{
switch( this )
{
case OWNER:
return 4;
case OP:
case OWNER_OP:
return 2;
case ANYONE:
default:
return 0;
}
}
@Override
public boolean test( CommandSource source )
{
if( this == ANYONE ) return true;
if( this == OWNER ) return isOwner( source );
if( this == OWNER_OP && isOwner( source ) ) return true;
return source.hasPermission( toLevel() );
}
/**
* Take the union of two {@link UserLevel}s.
* <p>
* This satisfies the property that for all sources {@code s}, {@code a.test(s) || b.test(s) == (a b).test(s)}.
*
* @param left The first user level to take the union of.
* @param right The second user level to take the union of.
* @return The union of two levels.
*/
public static UserLevel union( UserLevel left, UserLevel right )
{
if( left == right ) return left;
// x ANYONE = ANYONE
if( left == ANYONE || right == ANYONE ) return ANYONE;
// x OWNER = OWNER
if( left == OWNER ) return right;
if( right == OWNER ) return left;
// At this point, we have x != y and x, y ∈ { OP, OWNER_OP }.
return OWNER_OP;
}
private static boolean isOwner( CommandSource source )
{
MinecraftServer server = source.getServer();
Entity sender = source.getEntity();
return server.isDedicatedServer()
? source.getEntity() == null && source.hasPermission( 4 ) && source.getTextName().equals( "Server" )
: sender instanceof PlayerEntity && server.isSingleplayerOwner( ((PlayerEntity) sender).getGameProfile() );
}
}