Rewrote networking system (experimental)

This commit is contained in:
bdew committed 2014-07-29 12:43:53 +03:00
1 parent 9b0ed5b0b5
commit 03d9b0fef0
6 files changed
+74 -57

No files matched your search

+1 -1
View File
@@ -21,7 +21,7 @@ buildscript {
apply plugin: 'scala'
apply plugin: 'forge'
version = "1.4.0"
version = "1.4.1"
if (project.hasProperty('buildnum')) {
project.version = project.version + '.' + project.buildnum
+12
View File
@@ -0,0 +1,12 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.network
abstract class Message extends Serializable
+25 -25
View File
@@ -9,63 +9,63 @@
package net.bdew.lib.network
import cpw.mods.fml.common.network.{FMLOutboundHandler, NetworkRegistry}
import java.util
import cpw.mods.fml.common.network.{FMLEmbeddedChannel, FMLOutboundHandler, NetworkRegistry}
import cpw.mods.fml.relauncher.Side
import net.minecraft.nbt.NBTTagCompound
import io.netty.channel.{ChannelFutureListener, ChannelHandler}
import net.bdew.lib.{BdLib, Misc}
import net.minecraft.entity.player.EntityPlayerMP
import io.netty.channel.{ChannelHandler, ChannelFutureListener}
class NetChannel(val name: String) {
val channels = NetworkRegistry.INSTANCE.newChannel(name, new NBTMessageToMessageCodec)
var channels: util.EnumMap[Side, FMLEmbeddedChannel] = null
var serverHandlers = Map.empty[String, (NBTTagCompound, EntityPlayerMP) => Unit]
var clientHandlers = Map.empty[String, (NBTTagCompound) => Unit]
def init() {
channels = NetworkRegistry.INSTANCE.newChannel(name, new SerializedMessageCodec)
BdLib.logInfo("Initialized network channel '%s' for mod '%s'", name, Misc.getActiveModId)
addHandler(Side.SERVER, new NetChannelServerHandler(this))
addHandler(Side.CLIENT, new NetChannelClientHandler(this))
}
def regServerHandler(id: String, callable: (NBTTagCompound, EntityPlayerMP) => Unit) =
if (serverHandlers.contains(id))
sys.error("Command name already in use: %s".format(name))
else
serverHandlers += (id -> callable)
var clientChain = PartialFunction.empty[Message, Unit]
var serverChain = PartialFunction.empty[(Message, EntityPlayerMP), Unit]
def regClientHandler(id: String, callable: (NBTTagCompound) => Unit) =
if (clientHandlers.contains(id))
sys.error("Command name already in use: %s".format(name))
else
clientHandlers += (id -> callable)
def regServerHandler(f: PartialFunction[(Message, EntityPlayerMP), Unit]) =
serverChain = serverChain.orElse(f)
addHandler(Side.SERVER, new NetChannelServerHandler(this))
addHandler(Side.CLIENT, new NetChannelClientHandler(this))
def regClientHandler(f: PartialFunction[Message, Unit]) =
clientChain = clientChain.orElse(f)
def addHandler(side: Side, handler: ChannelHandler) {
private def addHandler(side: Side, handler: ChannelHandler) {
val ch = channels.get(side)
val name = ch.findChannelHandlerNameForType(classOf[NBTMessageToMessageCodec])
val name = ch.findChannelHandlerNameForType(classOf[SerializedMessageCodec])
ch.pipeline().addAfter(name, side + "Handler", handler)
}
def sendToAll(message: NBTTagCompound) {
def sendToAll(message: Message) {
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL)
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
}
def sendTo(message: NBTTagCompound, player: EntityPlayerMP) {
def sendTo(message: Message, player: EntityPlayerMP) {
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER)
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player)
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
}
def sendToAllAround(message: NBTTagCompound, point: NetworkRegistry.TargetPoint) {
def sendToAllAround(message: Message, point: NetworkRegistry.TargetPoint) {
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT)
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point)
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
}
def sendToDimension(message: NBTTagCompound, dimensionId: Int) {
def sendToDimension(message: Message, dimensionId: Int) {
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION)
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(new Integer(dimensionId))
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
}
def sendToServer(message: NBTTagCompound) {
def sendToServer(message: Message) {
channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER)
channels.get(Side.CLIENT).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
}
@@ -10,15 +10,17 @@
package net.bdew.lib.network
import io.netty.channel.{ChannelHandlerContext, SimpleChannelInboundHandler}
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.BdLib
class NetChannelClientHandler(ch: NetChannel) extends SimpleChannelInboundHandler[NBTTagCompound] {
def channelRead0(ctx: ChannelHandlerContext, msg: NBTTagCompound) {
val cmd = msg.getString("_cmd")
ch.clientHandlers.getOrElse(cmd, {
BdLib.log.error("Unknown command: '%s' from server".format(cmd))
return
})(msg)
class NetChannelClientHandler(ch: NetChannel) extends SimpleChannelInboundHandler[Message] {
def channelRead0(ctx: ChannelHandlerContext, msg: Message) {
try {
if (ch.clientChain.isDefinedAt(msg))
ch.clientChain(msg)
else
BdLib.logWarn("Unable to handle message from server: %s", msg)
} catch {
case e: Throwable => BdLib.logErrorException("Error handling packet", e)
}
}
}
@@ -9,19 +9,21 @@
package net.bdew.lib.network
import io.netty.channel.{ChannelHandlerContext, SimpleChannelInboundHandler}
import net.minecraft.nbt.NBTTagCompound
import cpw.mods.fml.common.network.NetworkRegistry
import net.minecraft.network.NetHandlerPlayServer
import io.netty.channel.{ChannelHandlerContext, SimpleChannelInboundHandler}
import net.bdew.lib.BdLib
import net.minecraft.network.NetHandlerPlayServer
class NetChannelServerHandler(ch: NetChannel) extends SimpleChannelInboundHandler[NBTTagCompound] {
def channelRead0(ctx: ChannelHandlerContext, msg: NBTTagCompound) {
val cmd = msg.getString("_cmd")
val nh = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get.asInstanceOf[NetHandlerPlayServer].playerEntity
ch.serverHandlers.getOrElse(cmd, {
BdLib.log.error("Unknown command: '%s' from '%s'".format(cmd, nh.getCommandSenderName))
return
})(msg, nh)
class NetChannelServerHandler(ch: NetChannel) extends SimpleChannelInboundHandler[Message] {
def channelRead0(ctx: ChannelHandlerContext, msg: Message) {
try {
val player = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get.asInstanceOf[NetHandlerPlayServer].playerEntity
if (ch.serverChain.isDefinedAt(msg, player))
ch.serverChain(msg, player)
else
BdLib.logWarn("Unable to handle message from user %s: %s", player.getDisplayName, msg)
} catch {
case e: Throwable => BdLib.logErrorException("Error handling packet", e)
}
}
}
@@ -9,30 +9,31 @@
package net.bdew.lib.network
import io.netty.handler.codec.MessageToMessageCodec
import cpw.mods.fml.common.network.internal.FMLProxyPacket
import net.minecraft.nbt.{CompressedStreamTools, NBTTagCompound}
import io.netty.channel.ChannelHandlerContext
import java.io.{ObjectInputStream, ObjectOutputStream}
import java.util
import java.io.{DataInputStream, DataOutputStream}
import io.netty.buffer.{ByteBufInputStream, ByteBufOutputStream, Unpooled}
import cpw.mods.fml.common.network.NetworkRegistry
import cpw.mods.fml.common.network.internal.FMLProxyPacket
import io.netty.buffer.{ByteBufInputStream, ByteBufOutputStream, Unpooled}
import io.netty.channel.ChannelHandler.Sharable
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.MessageToMessageCodec
import net.bdew.lib.BdLib
@Sharable
class NBTMessageToMessageCodec extends MessageToMessageCodec[FMLProxyPacket, NBTTagCompound] {
def encode(ctx: ChannelHandlerContext, msg: NBTTagCompound, out: util.List[AnyRef]) {
class SerializedMessageCodec extends MessageToMessageCodec[FMLProxyPacket, Message] {
def encode(ctx: ChannelHandlerContext, msg: Message, out: util.List[AnyRef]) {
val buff = Unpooled.buffer()
val writer = new DataOutputStream(new ByteBufOutputStream(buff))
CompressedStreamTools.write(msg, writer)
val writer = new ObjectOutputStream(new ByteBufOutputStream(buff))
writer.writeObject(msg)
val pkt = new FMLProxyPacket(buff, ctx.channel.attr(NetworkRegistry.FML_CHANNEL).get)
out.add(pkt)
}
def decode(ctx: ChannelHandlerContext, msg: FMLProxyPacket, out: util.List[AnyRef]) {
try {
val stream = new DataInputStream(new ByteBufInputStream(msg.payload()))
out.add(CompressedStreamTools.read(stream))
val reader = new ObjectInputStream(new ByteBufInputStream(msg.payload()))
out.add(reader.readObject())
} catch {
case e: Throwable => BdLib.log.error("Error decoding packet", e)
}