| package li.cil.oc.server |
| |
| import cpw.mods.fml.common.eventhandler.SubscribeEvent |
| import cpw.mods.fml.common.network.FMLNetworkEvent.ServerCustomPacketEvent |
| import li.cil.oc.Localization |
| import li.cil.oc.api |
| import li.cil.oc.api.internal.Server |
| import li.cil.oc.api.machine.Machine |
| import li.cil.oc.common.Achievement |
| import li.cil.oc.common.PacketType |
| import li.cil.oc.common.component.TextBuffer |
| import li.cil.oc.common.entity.Drone |
| import li.cil.oc.common.item.Delegator |
| import li.cil.oc.common.item.data.DriveData |
| import li.cil.oc.common.item.traits.FileSystemLike |
| import li.cil.oc.common.tileentity._ |
| import li.cil.oc.common.tileentity.traits.Computer |
| import li.cil.oc.common.{PacketHandler => CommonPacketHandler} |
| import li.cil.oc.integration.fmp.EventHandler |
| import net.minecraft.entity.player.EntityPlayer |
| import net.minecraft.entity.player.EntityPlayerMP |
| import net.minecraft.nbt.NBTTagCompound |
| import net.minecraft.network.NetHandlerPlayServer |
| import net.minecraftforge.common.DimensionManager |
| |
| object PacketHandler extends CommonPacketHandler { |
| @SubscribeEvent |
| def onPacket(e: ServerCustomPacketEvent) = |
| onPacketData(e.packet.payload, e.handler.asInstanceOf[NetHandlerPlayServer].playerEntity) |
| |
| override protected def world(player: EntityPlayer, dimension: Int) = |
| Option(DimensionManager.getWorld(dimension)) |
| |
| override def dispatch(p: PacketParser) { |
| p.packetType match { |
| case PacketType.ComputerPower => onComputerPower(p) |
| case PacketType.CopyToAnalyzer => onCopyToAnalyzer(p) |
| case PacketType.DriveMode => onDriveMode(p) |
| case PacketType.DronePower => onDronePower(p) |
| case PacketType.KeyDown => onKeyDown(p) |
| case PacketType.KeyUp => onKeyUp(p) |
| case PacketType.Clipboard => onClipboard(p) |
| case PacketType.MouseClickOrDrag => onMouseClick(p) |
| case PacketType.MouseScroll => onMouseScroll(p) |
| case PacketType.MouseUp => onMouseUp(p) |
| case PacketType.MultiPartPlace => onMultiPartPlace(p) |
| case PacketType.PetVisibility => onPetVisibility(p) |
| case PacketType.RackMountableMapping => onRackMountableMapping(p) |
| case PacketType.RackRelayState => onRackRelayState(p) |
| case PacketType.RobotAssemblerStart => onRobotAssemblerStart(p) |
| case PacketType.RobotStateRequest => onRobotStateRequest(p) |
| case PacketType.ServerPower => onServerPower(p) |
| case PacketType.TextBufferInit => onTextBufferInit(p) |
| case PacketType.WaypointLabel => onWaypointLabel(p) |
| case _ => // Invalid packet. |
| } |
| } |
| |
| def onComputerPower(p: PacketParser) = |
| p.readTileEntity[Computer]() match { |
| case Some(t) => p.player match { |
| case player: EntityPlayerMP => trySetComputerPower(t.machine, p.readBoolean(), player) |
| case _ => |
| } |
| case _ => // Invalid packet. |
| } |
| |
| def onServerPower(p: PacketParser) = |
| p.readTileEntity[Rack]() match { |
| case Some(t) => |
| val mountableIndex = p.readInt() |
| t.getMountable(mountableIndex) match { |
| case server: Server => p.player match { |
| case player: EntityPlayerMP => trySetComputerPower(server.machine, p.readBoolean(), player) |
| case _ => // Invalid packet. |
| } |
| case _ => // Invalid packet. |
| } |
| case _ => // Invalid packet. |
| } |
| |
| def onCopyToAnalyzer(p: PacketParser) { |
| ComponentTracker.get(p.player.worldObj, p.readUTF()) match { |
| case Some(buffer: TextBuffer) => buffer.copyToAnalyzer(p.readInt(), p.player.asInstanceOf[EntityPlayer]) |
| case _ => // Invalid Packet |
| } |
| } |
| |
| def onDriveMode(p: PacketParser) = p.player match { |
| case player: EntityPlayerMP => |
| Delegator.subItem(player.getHeldItem) match { |
| case Some(drive: FileSystemLike) => |
| val data = new DriveData(player.getHeldItem) |
| data.isUnmanaged = p.readBoolean() |
| data.save(player.getHeldItem) |
| case _ => // Invalid packet. |
| } |
| case _ => // Invalid packet. |
| } |
| |
| def onDronePower(p: PacketParser) = |
| p.readEntity[Drone]() match { |
| case Some(drone) => p.player match { |
| case player: EntityPlayerMP => |
| val power = p.readBoolean() |
| if (power) { |
| drone.preparePowerUp() |
| } |
| trySetComputerPower(drone.machine, power, player) |
| case _ => |
| } |
| case _ => // Invalid packet. |
| } |
| |
| private def trySetComputerPower(computer: Machine, value: Boolean, player: EntityPlayerMP) { |
| if (computer.canInteract(player.getCommandSenderName)) { |
| if (value) { |
| if (!computer.isPaused) { |
| computer.start() |
| computer.lastError match { |
| case message if message != null => player.addChatMessage(Localization.Analyzer.LastError(message)) |
| case _ => |
| } |
| } |
| } |
| else computer.stop() |
| } |
| } |
| |
| def onKeyDown(p: PacketParser) { |
| ComponentTracker.get(p.player.worldObj, p.readUTF()) match { |
| case Some(buffer: api.internal.TextBuffer) => buffer.keyDown(p.readChar(), p.readInt(), p.player.asInstanceOf[EntityPlayer]) |
| case _ => // Invalid Packet |
| } |
| } |
| |
| def onKeyUp(p: PacketParser) { |
| ComponentTracker.get(p.player.worldObj, p.readUTF()) match { |
| case Some(buffer: api.internal.TextBuffer) => buffer.keyUp(p.readChar(), p.readInt(), p.player.asInstanceOf[EntityPlayer]) |
| case _ => // Invalid Packet |
| } |
| } |
| |
| def onClipboard(p: PacketParser) { |
| ComponentTracker.get(p.player.worldObj, p.readUTF()) match { |
| case Some(buffer: api.internal.TextBuffer) => buffer.clipboard(p.readUTF(), p.player.asInstanceOf[EntityPlayer]) |
| case _ => // Invalid Packet |
| } |
| } |
| |
| def onMouseClick(p: PacketParser) { |
| ComponentTracker.get(p.player.worldObj, p.readUTF()) match { |
| case Some(buffer: api.internal.TextBuffer) => |
| val x = p.readFloat() |
| val y = p.readFloat() |
| val dragging = p.readBoolean() |
| val button = p.readByte() |
| val player = p.player.asInstanceOf[EntityPlayer] |
| if (dragging) buffer.mouseDrag(x, y, button, player) |
| else buffer.mouseDown(x, y, button, player) |
| case _ => // Invalid Packet |
| } |
| } |
| |
| def onMouseUp(p: PacketParser) { |
| ComponentTracker.get(p.player.worldObj, p.readUTF()) match { |
| case Some(buffer: api.internal.TextBuffer) => |
| val x = p.readFloat() |
| val y = p.readFloat() |
| val button = p.readByte() |
| val player = p.player.asInstanceOf[EntityPlayer] |
| buffer.mouseUp(x, y, button, player) |
| case _ => // Invalid Packet |
| } |
| } |
| |
| def onMouseScroll(p: PacketParser) { |
| ComponentTracker.get(p.player.worldObj, p.readUTF()) match { |
| case Some(buffer: api.internal.TextBuffer) => |
| val x = p.readFloat() |
| val y = p.readFloat() |
| val button = p.readByte() |
| val player = p.player.asInstanceOf[EntityPlayer] |
| buffer.mouseScroll(x, y, button, player) |
| case _ => // Invalid Packet |
| } |
| } |
| |
| def onMultiPartPlace(p: PacketParser) { |
| p.player match { |
| case player: EntityPlayerMP => EventHandler.place(player) |
| case _ => // Invalid packet. |
| } |
| } |
| |
| def onPetVisibility(p: PacketParser) { |
| p.player match { |
| case player: EntityPlayerMP => |
| if (if (p.readBoolean()) { |
| PetVisibility.hidden.remove(player.getCommandSenderName) |
| } |
| else { |
| PetVisibility.hidden.add(player.getCommandSenderName) |
| }) { |
| // Something changed. |
| PacketSender.sendPetVisibility(Some(player.getCommandSenderName)) |
| } |
| case _ => // Invalid packet. |
| } |
| } |
| |
| def onRackMountableMapping(p: PacketParser) = |
| p.readTileEntity[Rack]() match { |
| case Some(t) => p.player match { |
| case player: EntityPlayerMP if t.isUseableByPlayer(player) => |
| val mountableIndex = p.readInt() |
| val nodeIndex = p.readInt() |
| val side = p.readDirection() |
| t.connect(mountableIndex, nodeIndex, side) |
| case _ => |
| } |
| case _ => // Invalid packet. |
| } |
| |
| def onRackRelayState(p: PacketParser) = |
| p.readTileEntity[Rack]() match { |
| case Some(t) => p.player match { |
| case player: EntityPlayerMP if t.isUseableByPlayer(player) => |
| t.isRelayEnabled = p.readBoolean() |
| case _ => |
| } |
| case _ => // Invalid packet. |
| } |
| |
| def onRobotAssemblerStart(p: PacketParser) = |
| p.readTileEntity[Assembler]() match { |
| case Some(assembler) => |
| if (assembler.start(p.player match { |
| case player: EntityPlayerMP => player.capabilities.isCreativeMode |
| case _ => false |
| })) assembler.output.foreach(stack => Achievement.onAssemble(stack, p.player)) |
| case _ => // Invalid packet. |
| } |
| |
| def onRobotStateRequest(p: PacketParser) = |
| p.readTileEntity[RobotProxy]() match { |
| case Some(proxy) => proxy.world.markBlockForUpdate(proxy.x, proxy.y, proxy.z) |
| case _ => // Invalid packet. |
| } |
| |
| def onTextBufferInit(p: PacketParser) { |
| val address = p.readUTF() |
| p.player match { |
| case entity: EntityPlayerMP => |
| ComponentTracker.get(p.player.worldObj, address) match { |
| case Some(buffer: TextBuffer) => |
| if (buffer.host match { |
| case screen: Screen if !screen.isOrigin => false |
| case _ => true |
| }) { |
| val nbt = new NBTTagCompound() |
| buffer.data.save(nbt) |
| nbt.setInteger("maxWidth", buffer.getMaximumWidth) |
| nbt.setInteger("maxHeight", buffer.getMaximumHeight) |
| nbt.setInteger("viewportWidth", buffer.getViewportWidth) |
| nbt.setInteger("viewportHeight", buffer.getViewportHeight) |
| PacketSender.sendTextBufferInit(address, nbt, entity) |
| } |
| case _ => // Invalid packet. |
| } |
| case _ => // Invalid packet. |
| } |
| } |
| |
| def onWaypointLabel(p: PacketParser) = |
| p.readTileEntity[Waypoint]() match { |
| case Some(waypoint) => p.player match { |
| case player: EntityPlayerMP if player.getDistanceSq(waypoint.x + 0.5, waypoint.y + 0.5, waypoint.z + 0.5) <= 64 => |
| val label = p.readUTF().take(32) |
| if (label != waypoint.label) { |
| waypoint.label = label |
| PacketSender.sendWaypointLabel(waypoint) |
| } |
| case _ => |
| } |
| case _ => // Invalid packet. |
| } |
| } |