Large refactor to make way for "refresh" functionality

Features:
- New "refresh" capability (no button available yet) so the
client can have an updated GUI.
- The player can now control which types to be queried/displayed.

A great number of changes were made to allow this to happen to the mod
internally, as started from the last commit.

- P2PCache has been revisited. Instead of being a one-time instantiation,
the cache can now be queried from the client many times.

- Network has changed. Instead of sending an ItemStack (as previously), we
keep that info locally and send a byte only instead, so that should save
some network traffic.

- New packet for sending the refresh signal has been made. Other packets
send a "type" discriminator to make way for the typing feature.

Because I was lazy and didn't separate the commits, here are some other
changes made:
- Cleaned up a bit of the code to make it easier to read. This includes
code I've written before...
- Some name refactors. Some of the names were (mine) were quite frankly,
bad.

Signed-off-by: Firenoo <49818773+firenoo@users.noreply.github.com>
This commit is contained in:
Firenoo committed 2023-05-10 00:26:51 -07:00
1 parent d965431af1
commit 08c27e57a3
20 files changed
+271 -144

No files matched your search

@@ -2,9 +2,11 @@ package com.projecturanus.betterp2p.capability
import com.projecturanus.betterp2p.client.gui.widget.GuiScale
import com.projecturanus.betterp2p.item.BetterMemoryCardModes
import com.projecturanus.betterp2p.network.NONE
import com.projecturanus.betterp2p.network.NONE_SELECTED
data class MemoryInfo(var selectedEntry: Long = NONE,
const val TUNNEL_ANY: Int = -1
data class MemoryInfo(var selectedEntry: Long = NONE_SELECTED,
var frequency: Long = 0,
var mode: BetterMemoryCardModes = BetterMemoryCardModes.OUTPUT,
var gui: GuiScale = GuiScale.DYNAMIC)
var gui: GuiScale = GuiScale.DYNAMIC,
var type: Int = TUNNEL_ANY)
@@ -1,14 +1,17 @@
package com.projecturanus.betterp2p.client.gui
import appeng.client.gui.widgets.MEGuiTextField
import com.projecturanus.betterp2p.BetterP2P
import com.projecturanus.betterp2p.MODID
import com.projecturanus.betterp2p.capability.MemoryInfo
import com.projecturanus.betterp2p.capability.TUNNEL_ANY
import com.projecturanus.betterp2p.client.ClientCache
import com.projecturanus.betterp2p.client.TextureBound
import com.projecturanus.betterp2p.client.gui.widget.*
import com.projecturanus.betterp2p.item.BetterMemoryCardModes
import com.projecturanus.betterp2p.item.MAX_TOOLTIP_LENGTH
import com.projecturanus.betterp2p.network.*
import com.projecturanus.betterp2p.util.p2p.TunnelInfo
import net.minecraft.client.gui.FontRenderer
import net.minecraft.client.gui.GuiScreen
import net.minecraft.client.renderer.Tessellator
@@ -52,6 +55,9 @@ class GuiAdvancedMemoryCard(msg: S2CListP2P) : GuiScreen(), TextureBound {
private var mode = msg.memoryInfo.mode
private val modeButton: WidgetButton
private var type: TunnelInfo? = BetterP2P.proxy.getP2PFromIndex(msg.memoryInfo.type)
private val typeButton: WidgetButton
private val scrollBar: WidgetScrollBar
private val searchBar: MEGuiTextField
@@ -130,6 +136,28 @@ class GuiAdvancedMemoryCard(msg: S2CListP2P) : GuiScreen(), TextureBound {
}
}
}
typeButton = object: WidgetButton(this, 0, 0, 32, 32) {
val types = BetterP2P.proxy.getP2PTypeList()
private var index = 0
private fun nextType(): TunnelInfo {
// range: [0, types.size - 1]
index = (index + 1).rem(types.size)
return types[index]
}
override fun mousePressed(mouseX: Int, mouseY: Int) {
if (super.mousePressed(mc, mouseX, mouseY)) {
type = nextType()
hoverText = listOf(type!!.stack.displayName)
requestRefresh()
super.func_146113_a(mc.soundHandler)
}
// setTexCoords((mode.ordinal + 3) * 32.0, 232.0)
// syncMemoryInfo()
}
}
}
// Note this is called on resize too.
@@ -180,6 +208,13 @@ class GuiAdvancedMemoryCard(msg: S2CListP2P) : GuiScreen(), TextureBound {
} }
}
/**
* Request a refresh from C->S.
* TODO: Implement
*/
fun requestRefresh() {
}
fun refreshInfo(infos: List<P2PInfo>) {
this.infos.rebuild(infos.map(::InfoWrapper))
checkInfo()
@@ -187,7 +222,8 @@ class GuiAdvancedMemoryCard(msg: S2CListP2P) : GuiScreen(), TextureBound {
}
private fun syncMemoryInfo() {
ModNetwork.channel.sendToServer(C2SUpdateInfo(MemoryInfo(infos.selectedEntry, selectedInfo?.frequency ?: 0, mode, scale)))
ModNetwork.channel.sendToServer(
C2SUpdateInfo(MemoryInfo(infos.selectedEntry, selectedInfo?.frequency ?: 0, mode, scale, type?.index ?: TUNNEL_ANY)))
}
override fun onGuiClosed() {
@@ -1,7 +1,8 @@
package com.projecturanus.betterp2p.client.gui
import cpw.mods.fml.relauncher.Side
import cpw.mods.fml.relauncher.SideOnly
import net.minecraft.client.renderer.Tessellator
import net.minecraft.util.ResourceLocation
/**
* Draws a textured quad.
@@ -11,7 +12,10 @@ import net.minecraft.util.ResourceLocation
* u0, v0 - top left texture corner
* u1, v1 - bottom right texture corner
*/
fun drawTexturedQuad(tessellator: Tessellator, x0 : Double, y0: Double, x1: Double, y1: Double, u0: Double, v0: Double, u1: Double, v1: Double) {
@SideOnly(Side.CLIENT)
fun drawTexturedQuad(tessellator: Tessellator,
x0: Double, y0: Double, x1: Double, y1: Double,
u0: Double, v0: Double, u1: Double, v1: Double) {
tessellator.startDrawingQuads()
tessellator.addVertexWithUV(x0, y1, 0.0, u0, v1)
tessellator.addVertexWithUV(x1, y1, 0.0, u1, v1)
@@ -1,8 +1,6 @@
package com.projecturanus.betterp2p.client.gui
import com.projecturanus.betterp2p.network.NONE
import com.projecturanus.betterp2p.network.hashP2P
import kotlin.math.absoluteValue
import com.projecturanus.betterp2p.network.NONE_SELECTED
import kotlin.reflect.KProperty0
/**
@@ -43,7 +41,7 @@ class InfoList (initList: Collection<InfoWrapper>,
val selectedInfo: InfoWrapper?
get() = masterMap[selectedEntry]
var selectedEntry: Long = NONE
var selectedEntry: Long = NONE_SELECTED
val size: Int
get() = masterMap.size
@@ -143,7 +141,7 @@ class InfoList (initList: Collection<InfoWrapper>,
if (masterMap.containsKey(hashCode)) {
selectedEntry = hashCode
} else {
selectedEntry = NONE
selectedEntry = NONE_SELECTED
}
}
}
@@ -1,13 +1,11 @@
package com.projecturanus.betterp2p.client.gui
import appeng.api.parts.IPart
import appeng.api.parts.IPartItem
import appeng.parts.p2p.PartP2PTunnel
import com.projecturanus.betterp2p.BetterP2P
import com.projecturanus.betterp2p.network.P2PInfo
import com.projecturanus.betterp2p.network.hashP2P
import com.projecturanus.betterp2p.util.p2p.ClientTunnelInfo
import net.minecraft.client.gui.GuiButton
import net.minecraft.client.resources.I18n
import net.minecraft.init.Blocks
import net.minecraft.util.IIcon
import net.minecraftforge.common.util.ForgeDirection
@@ -16,7 +14,16 @@ class InfoWrapper(info: P2PInfo) {
val code: Long by lazy {
hashP2P(posX, posY, posZ, facing.ordinal, dim)
}
val frequency: Long = info.frequency
var frequency: Long = info.frequency
set(value) {
if (error || value == 0L) {
hoverInfo[4] = "§c" + I18n.format("gui.advanced_memory_card.p2p_status.unbound")
} else {
hoverInfo[4] = "§a" + I18n.format("gui.advanced_memory_card.p2p_status.bound")
}
field = value
}
val hasChannel = info.hasChannel
val posX: Int = info.posX
val posY: Int = info.posY
@@ -25,10 +32,15 @@ class InfoWrapper(info: P2PInfo) {
val facing: ForgeDirection = info.facing
val output: Boolean = info.output
/**
* The backing icon (quartz, iron, etc)
*/
val icon: IIcon
val overlay: IIcon
val typeName: String
/**
* The p2p overlay texture (frame)
*/
val overlay: IIcon
val description: String
val freqDisplay: String by lazy {
@@ -59,61 +71,37 @@ class InfoWrapper(info: P2PInfo) {
var name: String = info.name
var error: Boolean = false
set(value) {
if (value) {
hoverInfo[4] = "§c" + I18n.format("gui.advanced_memory_card.p2p_status.unbound")
} else {
hoverInfo[4] = "§a" + I18n.format("gui.advanced_memory_card.p2p_status.bound")
}
field = value
}
// Widgets
val bindButton = GuiButton(0, 0, 0, 34, 20, I18n.format("gui.advanced_memory_card.bind"))
val renameButton = GuiButton(0, 0, 0, 0, 0,"")
init {
val p: IPart? = (info.stack.item as? IPartItem)?.createPartFromItemStack(info.stack)
if (p is PartP2PTunnel<*>) {
icon = p.typeTexture
overlay = info.stack.iconIndex
typeName =
info.stack.item.getItemStackDisplayName(info.stack).split(" - ").getOrNull(1)
?: "§c<Something broke...>"
description = buildString {
append("Type: ")
append(typeName)
append(" - ")
if (output)
append(I18n.format("gui.advanced_memory_card.p2p_status.output"))
else
append(I18n.format("gui.advanced_memory_card.p2p_status.input"))
}
val online = info.hasChannel
hoverInfo = mutableListOf(
"§bP2P - $typeName",
"§e" + I18n.format("gui.advanced_memory_card.pos", info.posX, info.posY, info.posZ),
"§e" + I18n.format("gui.advanced_memory_card.side", info.facing.name),
"§e" + I18n.format("gui.advanced_memory_card.dim", info.world)
)
if (error || frequency == 0L) {
hoverInfo.add("§c" + I18n.format("gui.advanced_memory_card.p2p_status.unbound"))
} else {
hoverInfo.add("§a" + I18n.format("gui.advanced_memory_card.p2p_status.bound"))
}
if (!online) hoverInfo.add("§c" + I18n.format("gui.advanced_memory_card.p2p_status.offline"))
} else {
icon = Blocks.air.getIcon(0, 0)
overlay = Blocks.air.getIcon(0, 0)
typeName = "§c<Something broke...>"
description = "§c<Unknown>"
hoverInfo = mutableListOf(
"§b$typeName§r",
"§e" + I18n.format("gui.advanced_memory_card.pos", info.posX, info.posY, info.posZ),
"§e" + I18n.format("gui.advanced_memory_card.side", info.facing.name),
"§e" + I18n.format("gui.advanced_memory_card.dim", info.world)
)
val p2pType: ClientTunnelInfo = BetterP2P.proxy.getP2PFromIndex(info.type) as ClientTunnelInfo
icon = p2pType.icon()
overlay = p2pType.stack.iconIndex
description = buildString {
append("Type: ")
append(p2pType.dispName)
append(" - ")
if (output)
append(I18n.format("gui.advanced_memory_card.p2p_status.output"))
else
append(I18n.format("gui.advanced_memory_card.p2p_status.input"))
}
val online = info.hasChannel
hoverInfo = mutableListOf(
"§bP2P - ${p2pType.dispName}",
"§e" + I18n.format("gui.advanced_memory_card.pos", info.posX, info.posY, info.posZ),
"§e" + I18n.format("gui.advanced_memory_card.side", info.facing.name),
"§e" + I18n.format("gui.advanced_memory_card.dim", info.world)
)
if (error || frequency == 0L) {
hoverInfo.add("§c" + I18n.format("gui.advanced_memory_card.p2p_status.unbound"))
} else {
hoverInfo.add("§a" + I18n.format("gui.advanced_memory_card.p2p_status.bound"))
}
if (!online) hoverInfo.add("§c" + I18n.format("gui.advanced_memory_card.p2p_status.offline"))
}
override fun hashCode(): Int {
@@ -96,7 +96,7 @@ class WidgetP2PColumn(private val gui: GuiAdvancedMemoryCard,
}
private fun onBindButtonClicked(info: InfoWrapper) {
if (infos.selectedEntry == NONE) return
if (infos.selectedEntry == NONE_SELECTED) return
when (mode()) {
BetterMemoryCardModes.INPUT -> {
BetterP2P.logger.debug("Bind ${info.code} as input")
@@ -20,10 +20,6 @@ object P2PEntryConstants {
const val LEFT_ALIGN = 24
}
val typeIcons: List<IIcon> = listOf(
)
class WidgetP2PDevice(private val selectedInfoProperty: KProperty0<InfoWrapper?>, val modeSupplier: () -> BetterMemoryCardModes, val infoSupplier: () -> InfoWrapper?, var x: Int, var y: Int): Widget() {
var renderNameTextField = true
@@ -113,14 +109,26 @@ class WidgetP2PDevice(private val selectedInfoProperty: KProperty0<InfoWrapper?>
private fun drawIcon(gui: GuiAdvancedMemoryCard, icon: IIcon, overlay: IIcon, x: Int, y: Int) {
val tessellator = Tessellator.instance
gui.mc.renderEngine.bindTexture(gui.mc.renderEngine.getResourceLocation(0))
gui.bindTexture(gui.mc.renderEngine.getResourceLocation(0))
GL11.glPushAttrib(GL11.GL_BLEND or GL11.GL_TEXTURE_2D or GL11.GL_COLOR)
GL11.glEnable(GL11.GL_BLEND)
GL11.glEnable(GL11.GL_TEXTURE_2D)
GL11.glColor3f(255f, 255f, 255f)
OpenGlHelper.glBlendFunc(770, 771, 1, 0)
drawTexturedQuad(tessellator, x.toDouble() + 1, y.toDouble() + 1, x + 15.0, y + 15.0, icon.minU.toDouble(), icon.minV.toDouble(), icon.maxU.toDouble(), icon.maxV.toDouble())
drawTexturedQuad(tessellator, x.toDouble(), y.toDouble(), x + 16.0, y + 16.0, overlay.minU.toDouble(), overlay.minV.toDouble(), overlay.maxU.toDouble(), overlay.maxV.toDouble())
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0)
drawTexturedQuad(tessellator,
x0 = x.toDouble() + 1,
y0 = y.toDouble() + 1,
x1 = x + 15.0,
y1 = y + 15.0,
u0 = icon.minU.toDouble(), v0 = icon.minV.toDouble(),
u1 = icon.maxU.toDouble(), v1 = icon.maxV.toDouble())
drawTexturedQuad(tessellator,
x0 = x.toDouble(),
y0 = y.toDouble(),
x1 = x + 16.0,
y1 = y + 16.0,
u0 = overlay.minU.toDouble(), v0 = overlay.minV.toDouble(),
u1 = overlay.maxU.toDouble(), v1 = overlay.maxV.toDouble())
GL11.glPopAttrib()
}
}
@@ -5,16 +5,17 @@ import appeng.core.CreativeTab
import appeng.parts.p2p.PartP2PTunnel
import com.projecturanus.betterp2p.MODID
import com.projecturanus.betterp2p.capability.MemoryInfo
import com.projecturanus.betterp2p.capability.TUNNEL_ANY
import com.projecturanus.betterp2p.client.ClientCache
import com.projecturanus.betterp2p.client.gui.widget.GuiScale
import com.projecturanus.betterp2p.network.ModNetwork
import com.projecturanus.betterp2p.network.NONE
import com.projecturanus.betterp2p.network.NONE_SELECTED
import com.projecturanus.betterp2p.network.S2CListP2P
import com.projecturanus.betterp2p.network.hashP2P
import com.projecturanus.betterp2p.util.getPart
import com.projecturanus.betterp2p.util.p2p.P2PCache
import com.projecturanus.betterp2p.util.p2p.P2PStatus
import com.projecturanus.betterp2p.util.p2p.areP2PEqual
import com.projecturanus.betterp2p.util.p2p.getTypeIndex
import com.projecturanus.betterp2p.util.p2p.toInfo
import cpw.mods.fml.relauncher.Side
import cpw.mods.fml.relauncher.SideOnly
@@ -45,9 +46,8 @@ object ItemAdvancedMemoryCard : Item() {
private fun sendStatus(status: P2PStatus, info: MemoryInfo, player: EntityPlayerMP) {
P2PCache.statusMap[player.uniqueID] = status
ModNetwork.channel.sendTo(
S2CListP2P(status.listP2P.values.map { p2p -> p2p.toInfo() }, info),
player
)
S2CListP2P(status.refresh(info.type).map { it.toInfo() }, info),
player)
}
@SideOnly(Side.CLIENT)
@@ -75,22 +75,20 @@ object ItemAdvancedMemoryCard : Item() {
val part = getPart(w, x, y, z, hx, hy, hz)
val stack = player.heldItem
val info = getInfo(stack)
val type: Int
val status: P2PStatus
if (part is PartP2PTunnel<*>) {
val status = P2PStatus(player, part.gridNode.grid, part)
val p2p = status.listP2P.values.firstOrNull { areP2PEqual(it, status.targetP2P) }
if (p2p != null) {
info.selectedEntry = hashP2P(p2p)
writeInfo(stack, info)
sendStatus(status, info, player as EntityPlayerMP)
return true
}
type = part.getTypeIndex()
status = P2PStatus(part.gridNode.grid, player, type)
info.selectedEntry = hashP2P(part)
} else {
type = TUNNEL_ANY
status = P2PStatus(te.getGridNode(ForgeDirection.getOrientation(side)).grid, player, type)
info.selectedEntry = NONE_SELECTED
}
// Fallback to sending the whole network
val node = te.getGridNode(ForgeDirection.getOrientation(side))!!
info.selectedEntry = NONE
info.type = type
writeInfo(stack, info)
sendStatus(P2PStatus(player, node.grid), info, player as EntityPlayerMP)
sendStatus(status, info, player as EntityPlayerMP)
return true
}
}
@@ -112,7 +110,7 @@ object ItemAdvancedMemoryCard : Item() {
if (stack.tagCompound == null) stack.tagCompound = NBTTagCompound()
val compound = stack.tagCompound!!
if (!compound.hasKey("gui")) compound.setByte("gui", GuiScale.DYNAMIC.ordinal.toByte())
if (!compound.hasKey("selectedIndex", Constants.NBT.TAG_LONG)) compound.setLong("selectedIndex", NONE)
if (!compound.hasKey("selectedIndex", Constants.NBT.TAG_LONG)) compound.setLong("selectedIndex", NONE_SELECTED)
return MemoryInfo(compound.getLong("selectedIndex"), compound.getLong("frequency"), BetterMemoryCardModes.values()[compound.getInteger("mode")], GuiScale.values()[compound.getByte("gui").toInt()])
}
@@ -3,7 +3,7 @@ package com.projecturanus.betterp2p.network
import cpw.mods.fml.common.network.simpleimpl.IMessage
import io.netty.buffer.ByteBuf
class C2SLinkP2P(var input: Long = NONE, var output: Long = NONE): IMessage {
class C2SLinkP2P(var input: Long = NONE_SELECTED, var output: Long = NONE_SELECTED): IMessage {
override fun fromBytes(buf: ByteBuf) {
input = buf.readLong()
output = buf.readLong()
@@ -0,0 +1,46 @@
package com.projecturanus.betterp2p.network
import com.projecturanus.betterp2p.BetterP2P
import com.projecturanus.betterp2p.capability.TUNNEL_ANY
import com.projecturanus.betterp2p.util.listAllGridP2P
import com.projecturanus.betterp2p.util.listTargetGridP2P
import com.projecturanus.betterp2p.util.p2p.P2PCache
import com.projecturanus.betterp2p.util.p2p.toInfo
import cpw.mods.fml.common.network.simpleimpl.IMessage
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler
import cpw.mods.fml.common.network.simpleimpl.MessageContext
import io.netty.buffer.ByteBuf
/**
* Send a request to the server to refresh the p2p list with the
* given type.
*/
class C2SRefreshP2PList(var type: Int = TUNNEL_ANY): IMessage {
override fun fromBytes(buf: ByteBuf) {
type = buf.readByte().toInt()
}
override fun toBytes(buf: ByteBuf) {
buf.writeByte(type)
}
}
/**
* Client -> C2SRefreshP2P -> Server
* Handler on server side
*/
class ServerRefreshP2PListHandler : IMessageHandler<C2SRefreshP2PList, IMessage?> {
override fun onMessage(message: C2SRefreshP2PList, ctx: MessageContext): IMessage? {
if (!P2PCache.statusMap.containsKey(ctx.serverHandler.playerEntity.uniqueID)) return null
val status = P2PCache.statusMap[ctx.serverHandler.playerEntity.uniqueID]!!
status.lastP2PType = message.type
val tunnelType = BetterP2P.proxy.getP2PFromIndex(message.type)
if (tunnelType != null) {
listTargetGridP2P(status.grid, status.player, tunnelType.clazz)
} else {
listAllGridP2P(status.grid, status.player)
}
return S2CListP2P(status.refresh(status.lastP2PType).map { it.toInfo() })
}
}
@@ -11,14 +11,29 @@ fun writeMemoryInfo(buf: ByteBuf, info: MemoryInfo) {
buf.writeLong(info.frequency)
buf.writeInt(info.mode.ordinal)
buf.writeByte(info.gui.ordinal)
buf.writeByte(info.type)
}
fun readMemoryInfo(buf: ByteBuf): MemoryInfo {
return MemoryInfo(buf.readLong(), buf.readLong(),
BetterMemoryCardModes.values()[buf.readInt()],
GuiScale.values()[buf.readByte().toInt()])
val selectedEntry = buf.readLong()
val frequency = buf.readLong()
val mode = try {
BetterMemoryCardModes.values()[buf.readInt()]
} catch (e: Exception) {
BetterMemoryCardModes.OUTPUT
}
val gui = try {
GuiScale.values()[buf.readByte().toInt()]
} catch (e: ArrayIndexOutOfBoundsException) {
GuiScale.DYNAMIC
}
val type = buf.readByte().toInt()
return MemoryInfo(selectedEntry, frequency, mode, gui, type)
}
/**
* Request from client -> server
*/
class C2SUpdateInfo(var info: MemoryInfo = MemoryInfo()) : IMessage {
override fun fromBytes(buf: ByteBuf) {
info = readMemoryInfo(buf)
@@ -47,4 +47,4 @@ private fun xorCollapse12(input: Int): Int {
/**
* Using `0x80000000` to represent none is selected (aka MSB set)
*/
const val NONE: Long = Long.MIN_VALUE
const val NONE_SELECTED: Long = Long.MIN_VALUE
@@ -14,7 +14,8 @@ object ModNetwork {
channel.registerMessage(ServerLinkP2PHandler::class.java, C2SLinkP2P::class.java, 2, Side.SERVER)
channel.registerMessage(ServerCloseGuiHandler::class.java, C2SCloseGui::class.java, 3, Side.SERVER)
channel.registerMessage(ServerUpdateInfoHandler::class.java, C2SUpdateInfo::class.java, 4, Side.SERVER)
channel.registerMessage(ServerTransportHandler::class.java,C2STransportPlayer::class.java,5,Side.SERVER)
channel.registerMessage(ServerRenameP2PTunnel::class.java,C2SP2PTunnelInfo::class.java,6,Side.SERVER)
channel.registerMessage(ServerTransportHandler::class.java, C2STransportPlayer::class.java, 5, Side.SERVER)
channel.registerMessage(ServerRenameP2PTunnel::class.java, C2SP2PTunnelInfo::class.java, 6, Side.SERVER)
channel.registerMessage(ServerRefreshP2PListHandler::class.java, C2SRefreshP2PList::class.java, 7, Side.SERVER)
}
}
@@ -1,7 +1,6 @@
package com.projecturanus.betterp2p.network
import com.projecturanus.betterp2p.client.gui.InfoWrapper
import net.minecraft.item.ItemStack
import net.minecraftforge.common.util.ForgeDirection
class P2PInfo(val frequency: Long,
@@ -13,12 +12,15 @@ class P2PInfo(val frequency: Long,
val name: String,
val output: Boolean,
val hasChannel: Boolean,
val channels: Int, //# of channels if ME P2P, or -1 else
val stack: ItemStack) {
// # of channels if ME P2P, or -1 else
val channels: Int,
// type of p2p, corresponds to registry in proxy
val type: Int) {
override fun hashCode(): Int {
return hashP2P(posX, posY, posZ, facing.ordinal, world).hashCode()
}
override fun equals(other: Any?): Boolean {
return if (other is InfoWrapper) {
this.posX == other.posX &&
@@ -29,5 +31,4 @@ class P2PInfo(val frequency: Long,
false
}
}
}
@@ -2,8 +2,6 @@ package com.projecturanus.betterp2p.network
import cpw.mods.fml.common.network.simpleimpl.IMessage
import io.netty.buffer.ByteBuf
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection
fun readInfo(buf: ByteBuf): P2PInfo {
@@ -20,13 +18,9 @@ fun readInfo(buf: ByteBuf): P2PInfo {
}
val output = buf.readBoolean()
val hasChannel = buf.readBoolean()
val channels = buf.readInt()
val compound = NBTTagCompound()
compound.setShort("id", buf.readShort())
compound.setShort("Damage", buf.readShort())
compound.setShort("Count", 1)
val stack = ItemStack.loadItemStackFromNBT(compound);
return P2PInfo(freq, posX, posY, posZ,world, facing, name, output, hasChannel, channels, stack)
val channels = buf.readByte().toInt()
val type = buf.readByte().toInt()
return P2PInfo(freq, posX, posY, posZ,world, facing, name, output, hasChannel, channels, type)
}
fun writeInfo(buf: ByteBuf, info: P2PInfo) {
@@ -42,11 +36,8 @@ fun writeInfo(buf: ByteBuf, info: P2PInfo) {
}
buf.writeBoolean(info.output)
buf.writeBoolean(info.hasChannel)
buf.writeInt(info.channels)
val compound = NBTTagCompound()
info.stack.writeToNBT(compound)
buf.writeShort(compound.getShort("id").toInt())
buf.writeShort(compound.getShort("Damage").toInt())
buf.writeByte(info.channels)
buf.writeByte(info.type)
}
class S2CRefreshInfo(var infos: List<P2PInfo> = emptyList()) : IMessage {
@@ -9,14 +9,15 @@ import cpw.mods.fml.common.network.simpleimpl.MessageContext
class ServerLinkP2PHandler : IMessageHandler<C2SLinkP2P, IMessage?> {
override fun onMessage(message: C2SLinkP2P, ctx: MessageContext): IMessage? {
if (!P2PCache.statusMap.containsKey(ctx.serverHandler.playerEntity.uniqueID)) return null
val status = P2PCache.statusMap[ctx.serverHandler.playerEntity.uniqueID]!!
val status = P2PCache.statusMap[ctx.serverHandler.playerEntity.uniqueID] ?: return null
val result = linkP2P(ctx.serverHandler.playerEntity, message.input, message.output, status)
if (result != null) {
status.listP2P[message.input] = result.first
status.listP2P[message.output] = result.second
ModNetwork.channel.sendTo(S2CRefreshInfo(status.listP2P.values.map { it.toInfo() }), ctx.serverHandler.playerEntity)
ModNetwork.channel.sendTo(
S2CRefreshInfo(status.listP2P.values.map { it.toInfo() }),
ctx.serverHandler.playerEntity)
}
return null
}
@@ -3,28 +3,32 @@ import appeng.api.networking.IGridHost
import appeng.api.parts.IPartHost
import appeng.parts.p2p.PartP2PTunnel
import com.projecturanus.betterp2p.item.ItemAdvancedMemoryCard
import com.projecturanus.betterp2p.util.p2p.P2PStatus
import com.projecturanus.betterp2p.util.p2p.P2PCache
import com.projecturanus.betterp2p.util.p2p.toInfo
import cpw.mods.fml.common.network.simpleimpl.IMessage
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler
import cpw.mods.fml.common.network.simpleimpl.MessageContext
import net.minecraft.entity.player.EntityPlayerMP
import net.minecraft.tileentity.TileEntity
import net.minecraft.world.World
import net.minecraftforge.common.DimensionManager
import net.minecraftforge.common.util.ForgeDirection
/**
* Handler for renaming p2p tunnels.
*/
class ServerRenameP2PTunnel : IMessageHandler<C2SP2PTunnelInfo, IMessage?> {
override fun onMessage(message: C2SP2PTunnelInfo, ctx: MessageContext): IMessage? {
val world: World = DimensionManager.getWorld(message.info.world)
val te: TileEntity = world.getTileEntity(message.info.posX,message.info.posY,message.info.posZ)
val player = ctx.serverHandler.playerEntity
val te: TileEntity = world.getTileEntity(message.info.posX, message.info.posY, message.info.posZ)
val cache = P2PCache.statusMap[ctx.serverHandler.playerEntity.uniqueID] ?: return null
if (te is IGridHost && te.getGridNode(ForgeDirection.getOrientation(message.info.side)) != null) {
val p = (te as IPartHost).getPart(ForgeDirection.getOrientation(message.info.side)) as PartP2PTunnel<*>
val p = (te as IPartHost).getPart(ForgeDirection.getOrientation(message.info.side)) as PartP2PTunnel<*>
p.customName = message.info.name
ModNetwork.channel.sendTo(S2CListP2P(
P2PStatus(player, p.gridNode.grid,p).listP2P.values.map { it.toInfo() },
ItemAdvancedMemoryCard.getInfo(player.heldItem)
),player)
ModNetwork.channel.sendTo(
S2CListP2P(cache.refresh(cache.lastP2PType).map { it.toInfo() },
ItemAdvancedMemoryCard.getInfo(cache.player.heldItem)),
cache.player as EntityPlayerMP)
}
return null
}
@@ -2,16 +2,13 @@ package com.projecturanus.betterp2p.util
import appeng.api.config.SecurityPermissions
import appeng.api.networking.IGrid
import appeng.api.networking.IGridHost
import appeng.api.networking.security.ISecurityGrid
import appeng.api.parts.IPart
import appeng.api.parts.IPartHost
import appeng.api.parts.SelectedPart
import appeng.api.util.IReadOnlyCollection
import appeng.parts.AEBasePart
import appeng.parts.ICableBusContainer
import appeng.parts.p2p.PartP2PTunnel
import appeng.parts.p2p.PartP2PTunnelME
import appeng.tile.networking.TileCableBus
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.tileentity.TileEntity
@@ -2,21 +2,50 @@ package com.projecturanus.betterp2p.util.p2p
import appeng.api.networking.IGrid
import appeng.parts.p2p.PartP2PTunnel
import appeng.parts.p2p.PartP2PTunnelME
import com.projecturanus.betterp2p.BetterP2P
import com.projecturanus.betterp2p.capability.TUNNEL_ANY
import com.projecturanus.betterp2p.network.hashP2P
import com.projecturanus.betterp2p.util.listAllGridP2P
import com.projecturanus.betterp2p.util.listTargetGridP2P
import net.minecraft.entity.player.EntityPlayer
class P2PStatus(player: EntityPlayer, grid: IGrid, val targetP2P: PartP2PTunnel<*>? = null) {
/**
* When the player uses the adv memory card, this is cached on the server side
* to provide access to the Grid when the player performs actions in the GUI.
*/
class P2PStatus(val grid: IGrid, val player: EntityPlayer, type: Int) {
/**
* The P2P list. This is a list of all P2Ps, and only the requested
* ones are sent.
*/
val listP2P: MutableMap<Long, PartP2PTunnel<*>> = mutableMapOf()
init {
if (targetP2P == null) {
listAllGridP2P(grid, player).forEach { listP2P[hashP2P(it)] = it }
/**
* Server copy of the p2p currently selected in client
*/
var lastP2PType: Int = type
/**
* Refreshes the p2p list
*/
private fun rebuildList() {
listP2P.clear()
listAllGridP2P(grid, player).forEach { listP2P[hashP2P(it)] = it }
}
/**
* Refreshes and gets the p2p list of the targeted type
* @param type if TUNNEL_ANY or invalid, returns the full list; else
* filters the list to the targeted type
*/
fun refresh(type: Int): List<PartP2PTunnel<*>> {
rebuildList()
return if (type == TUNNEL_ANY) {
listP2P.values.toList()
} else {
listTargetGridP2P(grid, player, targetP2P.javaClass)
.forEach { listP2P[hashP2P(it)] = it }
listP2P.values.filter {
(BetterP2P.proxy.getP2PFromClass(it.javaClass)?.index ?: TUNNEL_ANY) == type
}.toList()
}
}
}
@@ -5,7 +5,6 @@ import appeng.api.networking.IGrid
import appeng.api.networking.security.ISecurityGrid
import appeng.api.parts.IPart
import appeng.api.parts.PartItemStack
import appeng.helpers.DualityInterface
import appeng.me.GridAccessException
import appeng.me.GridNode
import appeng.parts.automation.UpgradeInventory
@@ -13,6 +12,8 @@ import appeng.parts.p2p.PartP2PInterface
import appeng.parts.p2p.PartP2PTunnel
import appeng.tile.inventory.AppEngInternalInventory
import appeng.util.Platform
import com.projecturanus.betterp2p.BetterP2P
import com.projecturanus.betterp2p.capability.TUNNEL_ANY
import com.projecturanus.betterp2p.network.P2PInfo
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
@@ -146,4 +147,11 @@ val PartP2PTunnel<*>.hasChannel
fun PartP2PTunnel<*>.toInfo()
= P2PInfo(frequency, location.x, location.y, location.z, location.dimension, side,
customName, isOutput, hasChannel, (externalFacingNode as? GridNode)?.usedChannels() ?: -1,
getItemStack(PartItemStack.Wrench))
getTypeIndex())
/**
* Get the type index or use TUNNEL_ANY
*/
fun PartP2PTunnel<*>.getTypeIndex()
= BetterP2P.proxy.getP2PFromClass(this.javaClass)?.index ?: TUNNEL_ANY