Skip to content
Permalink
Browse files Browse the repository at this point in the history
reworked custom network code to not use java serialization
  • Loading branch information
bdew committed May 31, 2021
1 parent e9a0eef commit 4472105
Show file tree
Hide file tree
Showing 14 changed files with 70 additions and 66 deletions.
2 changes: 1 addition & 1 deletion build.properties
@@ -1,5 +1,5 @@
mod.id=bdlib
mod.version=1.15.1
mod.version=1.16.0
curseforge.id=70496
minecraft.version=1.16.5
forge.version=36.1.0
Expand Down
@@ -1,21 +1,21 @@
package net.bdew.lib.multiblock.data

import net.bdew.lib.multiblock.network.MsgOutputCfgPayload
import net.bdew.lib.multiblock.network.MsgOutputCfg
import net.minecraft.nbt.CompoundNBT
import sun.reflect.generics.reflectiveObjects.NotImplementedException

abstract class OutputConfig {
def id: String
def read(t: CompoundNBT): Unit
def write(t: CompoundNBT): Unit
def handleConfigPacket(m: MsgOutputCfgPayload): Unit
def handleConfigPacket(m: MsgOutputCfg): Unit
}

class OutputConfigInvalid extends OutputConfig {
override val id: String = "invalid"
def read(t: CompoundNBT): Unit = {}
def write(t: CompoundNBT): Unit = throw new NotImplementedException
def handleConfigPacket(m: MsgOutputCfgPayload): Unit = throw new NotImplementedException
def handleConfigPacket(m: MsgOutputCfg): Unit = throw new NotImplementedException
}

object OutputConfigManager {
Expand Down
Expand Up @@ -2,7 +2,7 @@ package net.bdew.lib.multiblock.data

import net.bdew.lib.PimpVanilla._
import net.bdew.lib.misc.RSMode
import net.bdew.lib.multiblock.network.{MsgOutputCfgPayload, MsgOutputCfgRSMode}
import net.bdew.lib.multiblock.network.{MsgOutputCfg, MsgOutputCfgRSMode}
import net.minecraft.nbt.CompoundNBT

import scala.collection.mutable
Expand Down Expand Up @@ -33,8 +33,8 @@ class OutputConfigFluid extends OutputConfig with OutputConfigRSControllable {
t.putInt("rsMode", rsMode.id)
}

def handleConfigPacket(m: MsgOutputCfgPayload): Unit = m match {
case MsgOutputCfgRSMode(r) => rsMode = r
def handleConfigPacket(m: MsgOutputCfg): Unit = m match {
case MsgOutputCfgRSMode(_, r) => rsMode = r
case _ => sys.error("Invalid output config packet %s to config %s".format(m, this))
}
}
@@ -1,6 +1,6 @@
package net.bdew.lib.multiblock.data

import net.bdew.lib.multiblock.network.{MsgOutputCfgPayload, MsgOutputCfgSlot}
import net.bdew.lib.multiblock.network.{MsgOutputCfg, MsgOutputCfgSlot}
import net.minecraft.nbt.CompoundNBT

trait OutputConfigSlots {
Expand All @@ -18,8 +18,8 @@ class OutputConfigFluidSlots(val slotsDef: SlotSet) extends OutputConfigFluid wi
super.write(t)
t.putString("slot", slot.id)
}
override def handleConfigPacket(m: MsgOutputCfgPayload): Unit = m match {
case MsgOutputCfgSlot(id) => slot = slotsDef.get(id)
override def handleConfigPacket(m: MsgOutputCfg): Unit = m match {
case MsgOutputCfgSlot(_, id) => slot = slotsDef.get(id)
case _ => super.handleConfigPacket(m)
}
}
@@ -1,7 +1,7 @@
package net.bdew.lib.multiblock.data

import net.bdew.lib.misc.RSMode
import net.bdew.lib.multiblock.network.{MsgOutputCfgPayload, MsgOutputCfgRSMode}
import net.bdew.lib.multiblock.network.{MsgOutputCfg, MsgOutputCfgRSMode}
import net.minecraft.nbt.CompoundNBT

class OutputConfigItems extends OutputConfig with OutputConfigRSControllable {
Expand All @@ -16,8 +16,8 @@ class OutputConfigItems extends OutputConfig with OutputConfigRSControllable {
t.putInt("rsMode", rsMode.id)
}

def handleConfigPacket(m: MsgOutputCfgPayload): Unit = m match {
case MsgOutputCfgRSMode(r) => rsMode = r
def handleConfigPacket(m: MsgOutputCfg): Unit = m match {
case MsgOutputCfgRSMode(_, r) => rsMode = r
case _ => sys.error("Invalid output config packet %s to config %s".format(m, this))
}

Expand Down
@@ -1,7 +1,7 @@
package net.bdew.lib.multiblock.data

import net.bdew.lib.misc.RSMode
import net.bdew.lib.multiblock.network.{MsgOutputCfgPayload, MsgOutputCfgRSMode}
import net.bdew.lib.multiblock.network.{MsgOutputCfg, MsgOutputCfgRSMode}
import net.minecraft.nbt.CompoundNBT

class OutputConfigPower(var unit: String = "fe") extends OutputConfig with OutputConfigRSControllable {
Expand All @@ -27,8 +27,8 @@ class OutputConfigPower(var unit: String = "fe") extends OutputConfig with Outpu
t.putString("unit", unit)
}

def handleConfigPacket(m: MsgOutputCfgPayload): Unit = m match {
case MsgOutputCfgRSMode(r) => rsMode = r
def handleConfigPacket(m: MsgOutputCfg): Unit = m match {
case MsgOutputCfgRSMode(_, r) => rsMode = r
case _ => sys.error("Invalid output config packet %s to config %s".format(m, this))
}
}
Expand Up @@ -6,7 +6,7 @@ import net.bdew.lib.gui.{Point, Rect, Texture}
import net.bdew.lib.misc.RSMode
import net.bdew.lib.multiblock.data.OutputConfigRSControllable
import net.bdew.lib.multiblock.interact.CIOutputFaces
import net.bdew.lib.multiblock.network.{MsgOutputCfg, MsgOutputCfgRSMode, MultiblockNetHandler}
import net.bdew.lib.multiblock.network.{MsgOutputCfgRSMode, MultiblockNetHandler}
import net.minecraft.util.text.ITextComponent

import java.util.Locale
Expand Down Expand Up @@ -34,6 +34,6 @@ class WidgetRSConfig(te: CIOutputFaces, output: Int, p: Point) extends WidgetSub
)

def clicked(b: WidgetButtonIcon): Unit = {
MultiblockNetHandler.sendToServer(MsgOutputCfg(output, MsgOutputCfgRSMode(next(cfg.rsMode))))
MultiblockNetHandler.sendToServer(MsgOutputCfgRSMode(output, next(cfg.rsMode)))
}
}
@@ -1,5 +1,5 @@
package net.bdew.lib.multiblock.network

trait MsgOutputCfgPayload extends Serializable

case class MsgOutputCfg(output: Int, payload: MsgOutputCfgPayload) extends MultiblockNetHandler.Message
trait MsgOutputCfg {
def output: Int
}
@@ -1,5 +1,16 @@
package net.bdew.lib.multiblock.network

import net.bdew.lib.misc.RSMode
import net.minecraft.network.PacketBuffer

case class MsgOutputCfgRSMode(rsMode: RSMode.Value) extends MsgOutputCfgPayload
case class MsgOutputCfgRSMode(output: Int, rsMode: RSMode.Value) extends MultiblockNetHandler.Message with MsgOutputCfg

object CodecOutputCfgRSMode extends MultiblockNetHandler.Codec[MsgOutputCfgRSMode] {
override def encodeMsg(m: MsgOutputCfgRSMode, p: PacketBuffer): Unit = {
p.writeVarInt(m.output)
p.writeByte(m.rsMode.id)
}

override def decodeMsg(p: PacketBuffer): MsgOutputCfgRSMode =
MsgOutputCfgRSMode(p.readVarInt(), RSMode(p.readByte()))
}
@@ -1,3 +1,16 @@
package net.bdew.lib.multiblock.network

case class MsgOutputCfgSlot(slot: String) extends MsgOutputCfgPayload
import net.minecraft.network.PacketBuffer

case class MsgOutputCfgSlot(output: Int, slot: String) extends MultiblockNetHandler.Message with MsgOutputCfg

object CodecOutputCfgSlot extends MultiblockNetHandler.Codec[MsgOutputCfgSlot] {
override def encodeMsg(m: MsgOutputCfgSlot, p: PacketBuffer): Unit = {
p.writeVarInt(m.output)
p.writeUtf(m.slot)
}

override def decodeMsg(p: PacketBuffer): MsgOutputCfgSlot = {
MsgOutputCfgSlot(p.readVarInt(), p.readUtf(100))
}
}
Expand Up @@ -3,9 +3,17 @@ package net.bdew.lib.multiblock.network
import net.bdew.lib.multiblock.interact.ContainerOutputFaces
import net.bdew.lib.network.NetChannel

object MultiblockNetHandler extends NetChannel("multiblock", "1") {
regServerContainerHandler(1, classOf[MsgOutputCfg], classOf[ContainerOutputFaces]) { (msg, cont, _) =>
cont.te.outputConfig(msg.output).handleConfigPacket(msg.payload)
object MultiblockNetHandler extends NetChannel("multiblock", "2") {
private def forwardConfigMsg(m: MsgOutputCfg, cont: ContainerOutputFaces): Unit = {
cont.te.outputConfig(m.output).handleConfigPacket(m)
cont.te.outputConfig.updated()
}

regServerContainerHandler(1, CodecOutputCfgRSMode, classOf[ContainerOutputFaces]) { (msg, cont, _) =>
forwardConfigMsg(msg, cont)
}

regServerContainerHandler(2, CodecOutputCfgSlot, classOf[ContainerOutputFaces]) { (msg, cont, _) =>
forwardConfigMsg(msg, cont)
}
}
2 changes: 1 addition & 1 deletion src/main/scala/net/bdew/lib/network/BaseMessage.scala
@@ -1,3 +1,3 @@
package net.bdew.lib.network

abstract class BaseMessage[CH <: NetChannel] extends Serializable
abstract class BaseMessage[CH <: NetChannel]
23 changes: 0 additions & 23 deletions src/main/scala/net/bdew/lib/network/CompoundNBTSerialize.scala

This file was deleted.

27 changes: 11 additions & 16 deletions src/main/scala/net/bdew/lib/network/NetChannel.scala
@@ -1,6 +1,5 @@
package net.bdew.lib.network

import io.netty.buffer.{ByteBufInputStream, ByteBufOutputStream}
import net.bdew.lib.{BdLib, Misc}
import net.minecraft.entity.player.ServerPlayerEntity
import net.minecraft.inventory.container.Container
Expand All @@ -10,8 +9,8 @@ import net.minecraft.world.World
import net.minecraftforge.fml.network.simple.SimpleChannel
import net.minecraftforge.fml.network.{NetworkDirection, NetworkEvent, NetworkRegistry, PacketDistributor}

import java.io.{ObjectInputStream, ObjectOutputStream}
import java.util.Optional
import scala.reflect.ClassTag

class NetChannel(val name: String, val version: String) {
val modId: String = Misc.getActiveModId
Expand All @@ -21,33 +20,29 @@ class NetChannel(val name: String, val version: String) {

type Message = BaseMessage[this.type]

private def encodeMsg[M <: Message](m: Message, p: PacketBuffer): Unit = {
val writer = new ObjectOutputStream(new ByteBufOutputStream(p))
writer.writeObject(m)
}

private def decodeMsg[M <: Message](p: PacketBuffer): M = {
val reader = new ObjectInputStream(new ByteBufInputStream(p))
reader.readObject().asInstanceOf[M]
abstract class Codec[M <: Message : ClassTag] {
val cls: Class[M] = implicitly[ClassTag[M]].runtimeClass.asInstanceOf[Class[M]]
def encodeMsg(m: M, p: PacketBuffer): Unit
def decodeMsg(p: PacketBuffer): M
}

def init(): Unit = {
BdLib.logInfo("Initialized network channel '%s' for mod '%s'", name, modId)
}

def regServerHandler[M <: Message](id: Int, cls: Class[M])(handler: (M, NetworkEvent.Context) => Unit): Unit = {
channel.registerMessage[M](id, cls, (m, p) => encodeMsg[M](m, p), m => decodeMsg(m),
def regServerHandler[M <: Message](id: Int, codec: Codec[M])(handler: (M, NetworkEvent.Context) => Unit): Unit = {
channel.registerMessage[M](id, codec.cls, codec.encodeMsg, codec.decodeMsg,
(m, cs) => handler(m, cs.get()), Optional.of(NetworkDirection.PLAY_TO_SERVER))
}

def regServerContainerHandler[M <: Message, C <: Container](id: Int, cls: Class[M], cont: Class[C])(handler: (M, C, NetworkEvent.Context) => Unit): Unit = {
regServerHandler(id, cls) { (msg, ctx) =>
def regServerContainerHandler[M <: Message, C <: Container](id: Int, codec: Codec[M], cont: Class[C])(handler: (M, C, NetworkEvent.Context) => Unit): Unit = {
regServerHandler(id, codec) { (msg, ctx) =>
Misc.asInstanceOpt(ctx.getSender.containerMenu, cont) foreach (cont => handler(msg, cont, ctx))
}
}

def regClientHandler[M <: Message](id: Int, cls: Class[M])(handler: M => Unit): Unit = {
channel.registerMessage[M](id, cls, (m, p) => encodeMsg[M](m, p), m => decodeMsg(m),
def regClientHandler[M <: Message](id: Int, codec: Codec[M])(handler: M => Unit): Unit = {
channel.registerMessage[M](id, codec.cls, codec.encodeMsg, codec.decodeMsg,
(m, _) => handler(m), Optional.of(NetworkDirection.PLAY_TO_CLIENT))
}

Expand Down

0 comments on commit 4472105

Please sign in to comment.