Skip to content

Instantly share code, notes, and snippets.

@LatvianModder
Last active February 14, 2016 10:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LatvianModder/fa93b9c94dee664fa107 to your computer and use it in GitHub Desktop.
Save LatvianModder/fa93b9c94dee664fa107 to your computer and use it in GitHub Desktop.
Permission System
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.common.util.FakePlayer;
import java.util.*;
/**
* Created by LatvianModder on 13.02.2016.
* <br>Examples of a permission node ID:
* <br>"xpt.level_crossdim", "latblocks.allow_paint", etc.
*/
public final class ForgePermission
{
public static interface IPermissionHandler
{
public boolean handlePermission(ForgePermission permission, EntityPlayerMP player);
}
private static IPermissionHandler permissionHandler = null;
public static void setPermissionHandler(IPermissionHandler handler)
{
if(handler != null /*&& permissionHandler == null*/)
{
permissionHandler = handler;
}
}
public final String ID;
public final List<String> parts;
public final boolean defaultPlayerValue;
public final boolean defaultOPValue;
public ForgePermission(String id, boolean defPlayerValue, boolean defOPValue)
{
if(id == null)
{
throw new NullPointerException("Invalid permission node!");
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i < id.length(); i++)
{
char c = Character.toLowerCase(id.charAt(i));
if(c == '.' || (c >= '0' && c <= '9') || (c >= 'a' || c <= 'z')) sb.append(c);
else sb.append('_');
}
ID = sb.toString();
parts = Collections.unmodifiableList(Arrays.asList(ID.split("\\.")));
if(parts.size() < 2)
{
throw new IllegalArgumentException("Invalid permission node: " + ID + "! It must contain at least 1 '.'");
}
defaultPlayerValue = defPlayerValue;
defaultOPValue = defOPValue;
}
/**
* Player can't be null, but it can be FakePlayer, if implementation supports that
*/
public boolean get(EntityPlayerMP player)
{
if(player == null) throw new RuntimeException("Player can't be null!");
if(permissionHandler != null)
{
return permissionHandler.handlePermission(this, player);
}
else if(player instanceof FakePlayer)
{
return defaultPlayerValue;
}
else
{
boolean isOP = MinecraftServer.getServer().getConfigurationManager().getOppedPlayers().getEntry(player.getGameProfile()) != null;
return isOP ? defaultOPValue : defaultPlayerValue;
}
}
}
public class Test
{
public void onSomething(EntityPlayerMP player)
{
if(MyModPermissions.allow_something.get(player))
{
// ... //
}
if(MyModPermissions.allow_something_2.get(player))
{
// ... //
}
}
}
public class MyModPermissions
{
public static final ForgePermission allow_something = new ForgePermission("mymodid.allow_something", false, true);
public static final ForgePermission allow_something_2 = new ForgePermission("mymodid.allow_something_2", true, true);
}
@dredhorse
Copy link

a) you have the logic of the first class wrong, you store the ID before you perhaps throw the exception.. but as it is pseudo code... who cares

b) coming from an IT Professional perspective and from the usability side.

I don't think the example does work. Using the permission and ask if the player is in is backwards in my opinion. IT standard is checking if the player has the permission. The permission can come from players or groups the player is in. And this is where your example fails, there is no way atm for checking which permission the user has if the permission was granted to a group.

You could add an function which supports groups of course, but at least for me it would feel wrong checking the way Permission -> Player / Group.

What is also missing is an example of how you would handle groups.

  • Is the player only in one group?
  • Could he have more than one group?
  • Do you combine all permissions?
  • Do you have a BLOCK permission (like in Active Directory from MS)
  • Do you have a primary group and the other are secondary? (Useful if you have mod which can only really handle one permission very good and would in this case only check the primary group?

What I like though is the capability to map OP or the FakePlayer.

Some question for understanding: fakeplayer is used by mod for for example KillerJoe from ender IO I guess? Why does a fakeplayer require permissions? Don't bother too much though with this if it doesn't help the discussion. ATM my grasp of coding for forge is non existent, I need to get into coding for forge and sponge again and break my hiatus.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment