Last active
December 28, 2015 09:39
-
-
Save RainWarrior/7480335 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.minecraftforge.permissions.api | |
import java.util.{ List => JList } | |
import com.google.gson.JsonObject | |
import net.minecraft.tileentity.TileEntity | |
import net.minecraft.dispenser.ILocation | |
import net.minecraft.entity.{ Entity, EntityLiving, player } | |
import player.EntityPlayer | |
import net.minecraft.world.World | |
import net.minecraftforge.common.FakePlayer | |
import collection.JavaConversions._ | |
package context { | |
trait IContext | |
trait IDimensionContext extends IContext { | |
def dimensionId: Int | |
} | |
trait ILocationContext extends IDimensionContext { | |
def x: Double | |
def y: Double | |
def z: Double | |
} | |
trait IBlockLocationContext extends ILocationContext { | |
def blockX: Int | |
def blockY: Int | |
def blockZ: Int | |
} | |
trait IBlockContext extends IBlockLocationContext { | |
def blockId: Int | |
def blockMetadata: Int | |
def hasTileEntity: Boolean | |
} | |
trait IRotationContext extends IContext { | |
def pitch: Float | |
def yaw: Float | |
} | |
trait INameContext extends IContext { | |
def name: String | |
} | |
trait IHealthContext extends IContext { | |
def maxHealth: Float | |
def currentHealth: Float | |
} | |
trait IAreaContext extends IContext { | |
def locations: JList[IBlockLocationContext] | |
def overlapsWith(context: IAreaContext): Boolean | |
def contains(area: IAreaContext): Boolean | |
def contains(loc: ILocationContext): Boolean | |
} | |
class EntityContext(entity: Entity) extends ILocationContext with IRotationContext { | |
override val x = entity.posX | |
override val y = entity.posY | |
override val z = entity.posZ | |
override val dimensionId = entity.worldObj.provider.dimensionId | |
val entityId = entity.entityId | |
override val pitch = entity.rotationPitch | |
override val yaw = entity.rotationYaw | |
} | |
class EntityLivingContext(entity: EntityLiving) extends EntityContext(entity) with IHealthContext { | |
override val maxHealth = entity.getMaxHealth | |
override val currentHealth = entity.getHealth | |
} | |
class PlayerContext(player: EntityPlayer) extends EntityContext(player) with INameContext { | |
override val name = player.username | |
} | |
class Point( | |
override val x: Double, | |
override val y: Double, | |
override val z: Double, | |
override val dimensionId: Int) extends ILocationContext { | |
def this(loc: ILocation) = this(loc.getX, loc.getY, loc.getZ, loc.getWorld.provider.dimensionId) | |
} | |
class TileEntityContext(te: TileEntity) extends IBlockContext { | |
override val blockId = te.blockType.blockID | |
override val blockMetadata = te.blockMetadata | |
override val hasTileEntity = true | |
override val blockX = te.xCoord | |
override val blockY = te.yCoord | |
override val blockZ = te.zCoord | |
override def x = blockX | |
override def y = blockY | |
override def z = blockZ | |
override val dimensionId = te.worldObj.provider.dimensionId | |
} | |
class WorldContext(world: World) extends IDimensionContext { | |
override val dimensionId = world.provider.dimensionId | |
} | |
} | |
import context._ | |
trait IChecker { | |
import IChecker._ | |
def apply(name: String, node: String, userContext: IContext, targetContext: IContext): Boolean | |
def apply(name: String, node: String): Boolean = apply(name, node, null, null) | |
def getGlobalContext: IContext = GLOBAL | |
def getDefaultContext(player: EntityPlayer): IContext = new PlayerContext(player) | |
def getDefaultContext(te: TileEntity): IContext = new TileEntityContext(te) | |
def getDefaultContext(loc: ILocation): IContext = new Point(loc) | |
def getDefaultContext(entity: Entity): IContext = new EntityContext(entity) | |
def getdefaultContext(el: EntityLiving): IContext = new EntityLivingContext(el) | |
def getDefaultContext(world: World): IContext = new WorldContext(world) | |
def getDefaultContext(obj: AnyRef): IContext = GLOBAL | |
def registerPermissions(perms: JList[PermReg]): Unit | |
} | |
object IChecker { | |
val GLOBAL = new IContext {} | |
case class PermReg(key: String, role: RegisteredPermValue, data: JsonObject) | |
} | |
object OpChecker extends IChecker { | |
import IChecker._ | |
private var opPerms = Set.empty[String] | |
private var deniedPerms = Set.empty[String] | |
private var allowedPerms = Set.empty[String] | |
override def apply(name: String, node: String, userContext: IContext, targetContext: IContext): Boolean = { | |
if(deniedPerms(node)) false | |
else { | |
if(allowedPerms(node)) true | |
else { | |
if(opPerms(node)) isOp(name) | |
else throw new UnregisterredPermissionException(node) | |
} | |
} | |
} | |
private def isOp(username: String): Boolean = { | |
import cpw.mods.fml.common.FMLCommonHandler | |
import net.minecraft.server.integrated.IntegratedServer | |
val server = FMLCommonHandler.instance.getSidedDelegate.getServer | |
if(server.isSinglePlayer) server match { | |
case _: IntegratedServer => server.getServerOwner.equalsIgnoreCase(username) // SSP | |
case _ => server.getConfigurationManager.getOps.contains(username) // LAN | |
} else server.getConfigurationManager.getOps.contains(username) // SMP | |
} | |
override def registerPermissions(perms: JList[PermReg]): Unit = { | |
import RegisteredPermValue._ | |
for(perm <- perms if !isRegisterred(perm.key)) perm.role match { | |
case OP => opPerms += perm.key | |
case NONOP => allowedPerms += perm.key | |
case FALSE => deniedPerms += perm.key | |
case TRUE => allowedPerms += perm.key | |
} | |
} | |
private def isRegisterred(node: String) = | |
opPerms(node) || allowedPerms(node) || deniedPerms(node) | |
class UnregisterredPermissionException(val node: String) | |
extends RuntimeException(s"Unregisterred Permission encountered: $node") | |
} | |
object PermissionManager { | |
var checker: Option[IChecker] = None | |
val DEFAULT: IChecker = OpChecker | |
def setChecker(newChecker: IChecker) = checker match { | |
case Some(ch) => throw new IllegalStateException("Two Mods are trying to register permissions systems!") | |
case None => Option(newChecker) match { | |
case Some(nch) => checker = Some(nch) | |
case None => checker = Some(DEFAULT) | |
} | |
} | |
@inline final def checkerHelper(player: EntityPlayer)(f: (IChecker) => Boolean) = checker match { | |
case Some(ch) => player match { | |
case _: FakePlayer => throw new IllegalArgumentException("You cannot check permissions with a fake player. Use PermManager.ge >tPerm(username, node)"); | |
case _ => f(ch) | |
} | |
case None => throw new IllegalStateException("No permissions system!") | |
} | |
def checkPerm(player: EntityPlayer, node: String): Boolean = checkerHelper(player) { ch => | |
val context = ch.getDefaultContext(player) | |
ch(player.username, node, context, context) | |
} | |
def checkPerm(player: EntityPlayer, node: String, targetContext: Entity) = checkerHelper(player) { ch => | |
ch(player.username, node, ch.getDefaultContext(player), ch.getDefaultContext(targetContext)) | |
} | |
def checkPerm(player: EntityPlayer, node: String, targetContext: ILocation) = checkerHelper(player) { ch => | |
ch(player.username, node, ch.getDefaultContext(player), ch.getDefaultContext(targetContext)) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment