tracking pressed keys on server to send key up signals when a player disconnects / changes dimension / dies

This commit is contained in:
Florian Nücke 2013-11-07 17:50:51 +01:00
parent 2a48cb28d9
commit 99488799e9
3 changed files with 76 additions and 12 deletions

View File

@ -1,11 +1,14 @@
package li.cil.oc.common package li.cil.oc.common
import cpw.mods.fml.common.IPlayerTracker
import cpw.mods.fml.common.event._ import cpw.mods.fml.common.event._
import cpw.mods.fml.common.registry.GameRegistry
import li.cil.oc._ import li.cil.oc._
import li.cil.oc.server.component.Computer import li.cil.oc.server.component.Computer
import li.cil.oc.server.driver import li.cil.oc.server.driver
import li.cil.oc.server.fs import li.cil.oc.server.fs
import li.cil.oc.server.network import li.cil.oc.server.network
import net.minecraft.entity.player.EntityPlayer
import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.MinecraftForge
class Proxy { class Proxy {
@ -33,6 +36,22 @@ class Proxy {
MinecraftForge.EVENT_BUS.register(Computer) MinecraftForge.EVENT_BUS.register(Computer)
MinecraftForge.EVENT_BUS.register(network.Network) MinecraftForge.EVENT_BUS.register(network.Network)
GameRegistry.registerPlayerTracker(new IPlayerTracker {
def onPlayerRespawn(player: EntityPlayer) {
MinecraftForge.EVENT_BUS.post(new ReleasePressedKeys(player))
}
def onPlayerChangedDimension(player: EntityPlayer) {
MinecraftForge.EVENT_BUS.post(new ReleasePressedKeys(player))
}
def onPlayerLogout(player: EntityPlayer) {
MinecraftForge.EVENT_BUS.post(new ReleasePressedKeys(player))
}
def onPlayerLogin(player: EntityPlayer) {}
})
} }
def postInit(e: FMLPostInitializationEvent): Unit = { def postInit(e: FMLPostInitializationEvent): Unit = {

View File

@ -0,0 +1,6 @@
package li.cil.oc.common
import net.minecraft.entity.player.EntityPlayer
import net.minecraftforge.event.Event
class ReleasePressedKeys(val player: EntityPlayer) extends Event

View File

@ -1,17 +1,22 @@
package li.cil.oc.common.tileentity package li.cil.oc.common.tileentity
import cpw.mods.fml.common.network.Player
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.api.Network import li.cil.oc.api.Network
import li.cil.oc.api.network.{Visibility, Message} import li.cil.oc.api.network.{Visibility, Message}
import li.cil.oc.common.ReleasePressedKeys
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.event.ForgeSubscribe
import scala.collection.mutable
class Keyboard extends Rotatable with Environment { class Keyboard extends Rotatable with Environment {
val node = api.Network.newNode(this, Visibility.Network). val node = api.Network.newNode(this, Visibility.Network).
withComponent("keyboard"). withComponent("keyboard").
create() create()
val pressedKeys = mutable.Map.empty[EntityPlayer, mutable.Map[Integer, Character]]
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def updateEntity() { override def updateEntity() {
@ -22,6 +27,33 @@ class Keyboard extends Rotatable with Environment {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def invalidate() {
super.invalidate()
MinecraftForge.EVENT_BUS.unregister(this)
}
override def validate() {
super.validate()
MinecraftForge.EVENT_BUS.register(this)
}
override def onChunkUnload() {
super.onChunkUnload()
MinecraftForge.EVENT_BUS.unregister(this)
}
@ForgeSubscribe
def onReleasePressedKeys(e: ReleasePressedKeys) {
pressedKeys.get(e.player) match {
case Some(keys) => for ((code, char) <- keys)
node.sendToReachable("computer.signal", "key_up", char, code, e.player.getCommandSenderName)
case _ =>
}
pressedKeys.remove(e.player)
}
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) { override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt) super.readFromNBT(nbt)
node.load(nbt) node.load(nbt)
@ -36,15 +68,22 @@ class Keyboard extends Rotatable with Environment {
override def onMessage(message: Message) = { override def onMessage(message: Message) = {
message.data match { message.data match {
case Array(p: Player, char: Character, code: Integer) if message.name == "keyboard.keyDown" => case Array(p: EntityPlayer, char: Character, code: Integer) if message.name == "keyboard.keyDown" =>
if (isUseableByPlayer(p)) if (isUseableByPlayer(p)) {
node.sendToReachable("computer.signal", "key_down", char, code) pressedKeys.getOrElseUpdate(p, mutable.Map.empty[Integer, Character]) += code -> char
case Array(p: Player, char: Character, code: Integer) if message.name == "keyboard.keyUp" => node.sendToReachable("computer.signal", "key_down", char, code, p.getCommandSenderName)
if (isUseableByPlayer(p)) }
node.sendToReachable("computer.signal", "key_up", char, code) case Array(p: EntityPlayer, char: Character, code: Integer) if message.name == "keyboard.keyUp" =>
case Array(p: Player, value: String) if message.name == "keyboard.clipboard" => pressedKeys.get(p) match {
if (isUseableByPlayer(p)) case Some(keys) if keys.contains(code) =>
node.sendToReachable("computer.signal", "clipboard", value) keys -= code
node.sendToReachable("computer.signal", "key_up", char, code, p.getCommandSenderName)
case _ =>
}
case Array(p: EntityPlayer, value: String) if message.name == "keyboard.clipboard" =>
if (isUseableByPlayer(p)) {
node.sendToReachable("computer.signal", "clipboard", value, p.getCommandSenderName)
}
case _ => case _ =>
} }
super.onMessage(message) super.onMessage(message)
@ -52,6 +91,6 @@ class Keyboard extends Rotatable with Environment {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
def isUseableByPlayer(p: Player) = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this && def isUseableByPlayer(p: EntityPlayer) = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this &&
p.asInstanceOf[EntityPlayer].getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64 p.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64
} }