Skip to content

Instantly share code, notes, and snippets.

@RainWarrior
Last active December 28, 2015 09:39
Show Gist options
  • Save RainWarrior/7480335 to your computer and use it in GitHub Desktop.
Save RainWarrior/7480335 to your computer and use it in GitHub Desktop.
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