Calculate terminal displayed items on the server
Avoids sending giant S2C packets containing all items in the network when the network contains a great variety of different items
This commit is contained in:
parent
3ebafc062f
commit
f9befe9549
|
@ -7,6 +7,7 @@ import net.shadowfacts.phycon.init.PhyBlocks
|
||||||
import net.shadowfacts.phycon.init.PhyItems
|
import net.shadowfacts.phycon.init.PhyItems
|
||||||
import net.shadowfacts.phycon.init.PhyScreens
|
import net.shadowfacts.phycon.init.PhyScreens
|
||||||
import net.shadowfacts.phycon.networking.C2STerminalRequestItem
|
import net.shadowfacts.phycon.networking.C2STerminalRequestItem
|
||||||
|
import net.shadowfacts.phycon.networking.C2STerminalUpdateDisplayedItems
|
||||||
import net.shadowfacts.phycon.networking.ServerReceiver
|
import net.shadowfacts.phycon.networking.ServerReceiver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,6 +24,7 @@ object PhysicalConnectivity: ModInitializer {
|
||||||
PhyScreens.init()
|
PhyScreens.init()
|
||||||
|
|
||||||
registerGlobalReceiver(C2STerminalRequestItem)
|
registerGlobalReceiver(C2STerminalRequestItem)
|
||||||
|
registerGlobalReceiver(C2STerminalUpdateDisplayedItems)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerGlobalReceiver(receiver: ServerReceiver) {
|
private fun registerGlobalReceiver(receiver: ServerReceiver) {
|
||||||
|
|
|
@ -2,19 +2,30 @@ package net.shadowfacts.phycon
|
||||||
|
|
||||||
import net.fabricmc.api.ClientModInitializer
|
import net.fabricmc.api.ClientModInitializer
|
||||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap
|
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
|
||||||
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry
|
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry
|
||||||
import net.minecraft.client.render.RenderLayer
|
import net.minecraft.client.render.RenderLayer
|
||||||
import net.shadowfacts.phycon.init.PhyBlocks
|
import net.shadowfacts.phycon.init.PhyBlocks
|
||||||
import net.shadowfacts.phycon.init.PhyScreens
|
import net.shadowfacts.phycon.init.PhyScreens
|
||||||
import net.shadowfacts.phycon.network.block.terminal.TerminalScreen
|
import net.shadowfacts.phycon.network.block.terminal.TerminalScreen
|
||||||
|
import net.shadowfacts.phycon.networking.ClientReceiver
|
||||||
|
import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
object PhysicalConnectivityClient: ClientModInitializer {
|
object PhysicalConnectivityClient: ClientModInitializer {
|
||||||
|
|
||||||
override fun onInitializeClient() {
|
override fun onInitializeClient() {
|
||||||
BlockRenderLayerMap.INSTANCE.putBlock(PhyBlocks.CABLE, RenderLayer.getTranslucent())
|
BlockRenderLayerMap.INSTANCE.putBlock(PhyBlocks.CABLE, RenderLayer.getTranslucent())
|
||||||
|
|
||||||
ScreenRegistry.register(PhyScreens.TERMINAL_SCREEN_HANDLER, ::TerminalScreen)
|
ScreenRegistry.register(PhyScreens.TERMINAL_SCREEN_HANDLER, ::TerminalScreen)
|
||||||
|
|
||||||
|
registerGlobalReceiver(S2CTerminalUpdateDisplayedItems)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun registerGlobalReceiver(receiver: ClientReceiver) {
|
||||||
|
ClientPlayNetworking.registerGlobalReceiver(receiver.CHANNEL, receiver)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
||||||
|
|
||||||
private var observers = 0
|
private var observers = 0
|
||||||
val cachedNetItems = ItemStackCollections.intMap()
|
val cachedNetItems = ItemStackCollections.intMap()
|
||||||
var cachedSortedNetItems = listOf<ItemStack>()
|
// var cachedSortedNetItems = listOf<ItemStack>()
|
||||||
|
|
||||||
var netItemObserver: WeakReference<NetItemObserver>? = null
|
var netItemObserver: WeakReference<NetItemObserver>? = null
|
||||||
|
|
||||||
|
@ -86,14 +86,12 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
||||||
|
|
||||||
private fun handleReadInventory(packet: ReadInventoryPacket) {
|
private fun handleReadInventory(packet: ReadInventoryPacket) {
|
||||||
inventoryCache[packet.source] = packet.inventory
|
inventoryCache[packet.source] = packet.inventory
|
||||||
updateNetItems()
|
updateAndSync()
|
||||||
sync()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDeviceRemoved(packet: DeviceRemovedPacket) {
|
private fun handleDeviceRemoved(packet: DeviceRemovedPacket) {
|
||||||
inventoryCache.remove(packet.source)
|
inventoryCache.remove(packet.source)
|
||||||
updateNetItems()
|
updateAndSync()
|
||||||
sync()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleStackLocation(packet: StackLocationPacket) {
|
private fun handleStackLocation(packet: StackLocationPacket) {
|
||||||
|
@ -113,12 +111,17 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
||||||
|
|
||||||
// this happens outside the normal update loop because by receiving the item stack packet
|
// this happens outside the normal update loop because by receiving the item stack packet
|
||||||
// we "know" how much the count in the source inventory has changed
|
// we "know" how much the count in the source inventory has changed
|
||||||
updateNetItems()
|
updateAndSync()
|
||||||
sync()
|
|
||||||
|
|
||||||
return remaining
|
return remaining
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateAndSync() {
|
||||||
|
updateNetItems()
|
||||||
|
sync()
|
||||||
|
netItemObserver?.get()?.netItemsChanged()
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateNetItems() {
|
private fun updateNetItems() {
|
||||||
cachedNetItems.clear()
|
cachedNetItems.clear()
|
||||||
for (inventory in inventoryCache.values) {
|
for (inventory in inventoryCache.values) {
|
||||||
|
@ -127,12 +130,12 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
||||||
cachedNetItems.mergeInt(stack, amount) { a, b -> a + b }
|
cachedNetItems.mergeInt(stack, amount) { a, b -> a + b }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// todo: is the map necessary or is just the sorted list enough?
|
// // todo: is the map necessary or is just the sorted list enough?
|
||||||
cachedSortedNetItems = cachedNetItems.object2IntEntrySet().sortedByDescending { it.intValue }.map {
|
// cachedSortedNetItems = cachedNetItems.object2IntEntrySet().sortedByDescending { it.intValue }.map {
|
||||||
val stack = it.key.copy()
|
// val stack = it.key.copy()
|
||||||
stack.count = it.intValue
|
// stack.count = it.intValue
|
||||||
stack
|
// stack
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun beginInsertions() {
|
private fun beginInsertions() {
|
||||||
|
@ -175,21 +178,15 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
||||||
finishTimedOutPendingInsertions()
|
finishTimedOutPendingInsertions()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (observers > 0) {
|
if (observers > 0 && !world!!.isClient) {
|
||||||
if (world!!.isClient) {
|
updateAndSync()
|
||||||
println(cachedNetItems)
|
|
||||||
} else {
|
|
||||||
updateNetItems()
|
|
||||||
sync()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onActivate(player: PlayerEntity) {
|
fun onActivate(player: PlayerEntity) {
|
||||||
if (!world!!.isClient) {
|
if (!world!!.isClient) {
|
||||||
updateNetItems()
|
updateAndSync()
|
||||||
sync()
|
|
||||||
|
|
||||||
inventoryCache.clear()
|
inventoryCache.clear()
|
||||||
sendPacket(RequestInventoryPacket(ipAddress))
|
sendPacket(RequestInventoryPacket(ipAddress))
|
||||||
|
@ -238,8 +235,7 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
||||||
internalBuffer.setStack(insertion.bufferSlot, remaining)
|
internalBuffer.setStack(insertion.bufferSlot, remaining)
|
||||||
|
|
||||||
// as with extracting, we "know" the new amounts and so can update instantly without actually sending out packets
|
// as with extracting, we "know" the new amounts and so can update instantly without actually sending out packets
|
||||||
updateNetItems()
|
updateAndSync()
|
||||||
sync()
|
|
||||||
|
|
||||||
return remaining
|
return remaining
|
||||||
}
|
}
|
||||||
|
@ -263,31 +259,31 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
||||||
|
|
||||||
override fun toClientTag(tag: CompoundTag): CompoundTag {
|
override fun toClientTag(tag: CompoundTag): CompoundTag {
|
||||||
tag.put("InternalBuffer", internalBuffer.toTag())
|
tag.put("InternalBuffer", internalBuffer.toTag())
|
||||||
val list = ListTag()
|
// val list = ListTag()
|
||||||
tag.put("CachedNetItems", list)
|
// tag.put("CachedNetItems", list)
|
||||||
for ((stack, amount) in cachedNetItems) {
|
// for ((stack, amount) in cachedNetItems) {
|
||||||
val entryTag = stack.toTag(CompoundTag())
|
// val entryTag = stack.toTag(CompoundTag())
|
||||||
entryTag.putInt("NetAmount", amount)
|
// entryTag.putInt("NetAmount", amount)
|
||||||
list.add(entryTag)
|
// list.add(entryTag)
|
||||||
}
|
// }
|
||||||
return tag
|
return tag
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fromClientTag(tag: CompoundTag) {
|
override fun fromClientTag(tag: CompoundTag) {
|
||||||
internalBuffer.fromTag(tag.getCompound("InternalBuffer"))
|
internalBuffer.fromTag(tag.getCompound("InternalBuffer"))
|
||||||
val list = tag.getList("CachedNetItems", 10)
|
// val list = tag.getList("CachedNetItems", 10)
|
||||||
cachedNetItems.clear()
|
// cachedNetItems.clear()
|
||||||
for (entryTag in list) {
|
// for (entryTag in list) {
|
||||||
val stack = ItemStack.fromTag(entryTag as CompoundTag)
|
// val stack = ItemStack.fromTag(entryTag as CompoundTag)
|
||||||
val netAmount = entryTag.getInt("NetAmount")
|
// val netAmount = entryTag.getInt("NetAmount")
|
||||||
cachedNetItems[stack] = netAmount
|
// cachedNetItems[stack] = netAmount
|
||||||
}
|
// }
|
||||||
netItemObserver?.get()?.netItemsChanged()
|
// netItemObserver?.get()?.netItemsChanged()
|
||||||
cachedSortedNetItems = cachedNetItems.object2IntEntrySet().sortedByDescending { it.intValue }.map {
|
// cachedSortedNetItems = cachedNetItems.object2IntEntrySet().sortedByDescending { it.intValue }.map {
|
||||||
val stack = it.key.copy()
|
// val stack = it.key.copy()
|
||||||
stack.count = it.intValue
|
// stack.count = it.intValue
|
||||||
stack
|
// stack
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NetItemObserver {
|
interface NetItemObserver {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import net.minecraft.text.LiteralText
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
import net.shadowfacts.phycon.PhysicalConnectivity
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||||
|
import net.shadowfacts.phycon.networking.C2STerminalUpdateDisplayedItems
|
||||||
import net.shadowfacts.phycon.util.SortMode
|
import net.shadowfacts.phycon.util.SortMode
|
||||||
import org.lwjgl.glfw.GLFW
|
import org.lwjgl.glfw.GLFW
|
||||||
import java.lang.NumberFormatException
|
import java.lang.NumberFormatException
|
||||||
|
@ -34,6 +35,7 @@ class TerminalScreen(handler: TerminalScreenHandler, playerInv: PlayerInventory,
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var searchBox: TextFieldWidget
|
private lateinit var searchBox: TextFieldWidget
|
||||||
|
private lateinit var sortButton: SortButton
|
||||||
private lateinit var amountBox: TextFieldWidget
|
private lateinit var amountBox: TextFieldWidget
|
||||||
private var dialogStack = ItemStack.EMPTY
|
private var dialogStack = ItemStack.EMPTY
|
||||||
private var showingAmountDialog = false
|
private var showingAmountDialog = false
|
||||||
|
@ -77,9 +79,8 @@ class TerminalScreen(handler: TerminalScreenHandler, playerInv: PlayerInventory,
|
||||||
searchBox.setEditableColor(0xffffff)
|
searchBox.setEditableColor(0xffffff)
|
||||||
addChild(searchBox)
|
addChild(searchBox)
|
||||||
|
|
||||||
val sortButton = SortButton(x + 256, y + 0, handler.sortMode, {
|
sortButton = SortButton(x + 256, y + 0, handler.sortMode, {
|
||||||
handler.sortMode = it
|
requestUpdatedItems()
|
||||||
handler.netItemsChanged()
|
|
||||||
}, ::renderTooltip)
|
}, ::renderTooltip)
|
||||||
addButton(sortButton)
|
addButton(sortButton)
|
||||||
|
|
||||||
|
@ -138,6 +139,13 @@ class TerminalScreen(handler: TerminalScreenHandler, playerInv: PlayerInventory,
|
||||||
doDialogRequest()
|
doDialogRequest()
|
||||||
}
|
}
|
||||||
dialogChildren.add(request)
|
dialogChildren.add(request)
|
||||||
|
|
||||||
|
requestUpdatedItems()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestUpdatedItems() {
|
||||||
|
val player = MinecraftClient.getInstance().player!!
|
||||||
|
player.networkHandler.sendPacket(C2STerminalUpdateDisplayedItems(handler.terminal, searchBox.text, sortButton.mode))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
|
@ -279,7 +287,7 @@ class TerminalScreen(handler: TerminalScreenHandler, playerInv: PlayerInventory,
|
||||||
val oldText = searchBox.text
|
val oldText = searchBox.text
|
||||||
if (searchBox.charTyped(c, i)) {
|
if (searchBox.charTyped(c, i)) {
|
||||||
if (searchBox.text != oldText) {
|
if (searchBox.text != oldText) {
|
||||||
search()
|
requestUpdatedItems()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -307,7 +315,7 @@ class TerminalScreen(handler: TerminalScreenHandler, playerInv: PlayerInventory,
|
||||||
val oldText = searchBox.text
|
val oldText = searchBox.text
|
||||||
if (searchBox.keyPressed(key, j, k)) {
|
if (searchBox.keyPressed(key, j, k)) {
|
||||||
if (searchBox.text != oldText) {
|
if (searchBox.text != oldText) {
|
||||||
search()
|
requestUpdatedItems()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -319,10 +327,6 @@ class TerminalScreen(handler: TerminalScreenHandler, playerInv: PlayerInventory,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun search() {
|
|
||||||
screenHandler.search(searchBox.text)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doDialogRequest() {
|
private fun doDialogRequest() {
|
||||||
showingAmountDialog = false
|
showingAmountDialog = false
|
||||||
handler.requestItem(client!!.player!!, dialogStack, amountBox.intValue)
|
handler.requestItem(client!!.player!!, dialogStack, amountBox.intValue)
|
||||||
|
|
|
@ -8,12 +8,14 @@ import net.minecraft.entity.player.PlayerInventory
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.network.PacketByteBuf
|
import net.minecraft.network.PacketByteBuf
|
||||||
import net.minecraft.screen.ScreenHandler
|
import net.minecraft.screen.ScreenHandler
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
import net.minecraft.util.registry.Registry
|
import net.minecraft.util.registry.Registry
|
||||||
import net.shadowfacts.phycon.PhysicalConnectivity
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||||
import net.shadowfacts.phycon.init.PhyBlocks
|
import net.shadowfacts.phycon.init.PhyBlocks
|
||||||
import net.shadowfacts.phycon.init.PhyScreens
|
import net.shadowfacts.phycon.init.PhyScreens
|
||||||
import net.shadowfacts.phycon.networking.C2STerminalRequestItem
|
import net.shadowfacts.phycon.networking.C2STerminalRequestItem
|
||||||
|
import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems
|
||||||
import net.shadowfacts.phycon.util.SortMode
|
import net.shadowfacts.phycon.util.SortMode
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
|
@ -22,7 +24,7 @@ import kotlin.math.min
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
class TerminalScreenHandler(syncId: Int, playerInv: PlayerInventory, val terminal: TerminalBlockEntity): ScreenHandler(PhyScreens.TERMINAL_SCREEN_HANDLER, syncId),
|
class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val terminal: TerminalBlockEntity): ScreenHandler(PhyScreens.TERMINAL_SCREEN_HANDLER, syncId),
|
||||||
TerminalBlockEntity.NetItemObserver {
|
TerminalBlockEntity.NetItemObserver {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -32,6 +34,18 @@ class TerminalScreenHandler(syncId: Int, playerInv: PlayerInventory, val termina
|
||||||
private val fakeInv = FakeInventory(this)
|
private val fakeInv = FakeInventory(this)
|
||||||
private var searchQuery: String = ""
|
private var searchQuery: String = ""
|
||||||
var sortMode = SortMode.COUNT_HIGH_FIRST
|
var sortMode = SortMode.COUNT_HIGH_FIRST
|
||||||
|
private set
|
||||||
|
private var itemEntries = listOf<Entry>()
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
if (terminal.world!!.isClient) {
|
||||||
|
itemsForDisplay = value.map {
|
||||||
|
val stack = it.stack.copy()
|
||||||
|
stack.count = it.amount
|
||||||
|
stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
var itemsForDisplay = listOf<ItemStack>()
|
var itemsForDisplay = listOf<ItemStack>()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
@ -39,8 +53,10 @@ class TerminalScreenHandler(syncId: Int, playerInv: PlayerInventory, val termina
|
||||||
this(syncId, playerInv, PhyBlocks.TERMINAL.getBlockEntity(playerInv.player.world, buf.readBlockPos())!!)
|
this(syncId, playerInv, PhyBlocks.TERMINAL.getBlockEntity(playerInv.player.world, buf.readBlockPos())!!)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
terminal.netItemObserver = WeakReference(this)
|
if (!terminal.world!!.isClient) {
|
||||||
netItemsChanged()
|
terminal.netItemObserver = WeakReference(this)
|
||||||
|
netItemsChanged()
|
||||||
|
}
|
||||||
|
|
||||||
// network
|
// network
|
||||||
for (y in 0 until 6) {
|
for (y in 0 until 6) {
|
||||||
|
@ -69,6 +85,9 @@ class TerminalScreenHandler(syncId: Int, playerInv: PlayerInventory, val termina
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun netItemsChanged() {
|
override fun netItemsChanged() {
|
||||||
|
val player = playerInv.player
|
||||||
|
assert(player is ServerPlayerEntity)
|
||||||
|
|
||||||
val filtered = terminal.cachedNetItems.object2IntEntrySet().filter {
|
val filtered = terminal.cachedNetItems.object2IntEntrySet().filter {
|
||||||
if (searchQuery.isBlank()) return@filter true
|
if (searchQuery.isBlank()) return@filter true
|
||||||
if (searchQuery.startsWith('@')) {
|
if (searchQuery.startsWith('@')) {
|
||||||
|
@ -88,18 +107,25 @@ class TerminalScreenHandler(syncId: Int, playerInv: PlayerInventory, val termina
|
||||||
SortMode.ALPHABETICAL -> filtered.sortedBy { it.key.name.string }
|
SortMode.ALPHABETICAL -> filtered.sortedBy { it.key.name.string }
|
||||||
}
|
}
|
||||||
|
|
||||||
itemsForDisplay = sorted.map {
|
itemEntries = sorted.map { Entry(it.key, it.intValue) }
|
||||||
val stack = it.key.copy()
|
|
||||||
stack.count = it.intValue
|
(player as ServerPlayerEntity).networkHandler.sendPacket(S2CTerminalUpdateDisplayedItems(terminal, itemEntries, searchQuery, sortMode))
|
||||||
stack
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun search(query: String) {
|
fun sendUpdatedItemsToClient(player: ServerPlayerEntity, query: String, sortMode: SortMode) {
|
||||||
searchQuery = query
|
this.searchQuery = query
|
||||||
|
this.sortMode = sortMode
|
||||||
netItemsChanged()
|
netItemsChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun receivedUpdatedItemsFromServer(entries: List<Entry>, query: String, sortMode: SortMode) {
|
||||||
|
assert(playerInv.player.world.isClient)
|
||||||
|
|
||||||
|
this.searchQuery = query
|
||||||
|
this.sortMode = sortMode
|
||||||
|
itemEntries = entries
|
||||||
|
}
|
||||||
|
|
||||||
override fun canUse(player: PlayerEntity): Boolean {
|
override fun canUse(player: PlayerEntity): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -214,4 +240,6 @@ class TerminalScreenHandler(syncId: Int, playerInv: PlayerInventory, val termina
|
||||||
fun isNetworkSlot(id: Int) = id in 0 until bufferSlotsStart
|
fun isNetworkSlot(id: Int) = id in 0 until bufferSlotsStart
|
||||||
fun isBufferSlot(id: Int) = id in bufferSlotsStart until playerSlotsStart
|
fun isBufferSlot(id: Int) = id in bufferSlotsStart until playerSlotsStart
|
||||||
fun isPlayerSlot(id: Int) = id >= playerSlotsStart
|
fun isPlayerSlot(id: Int) = id >= playerSlotsStart
|
||||||
|
|
||||||
|
data class Entry(val stack: ItemStack, val amount: Int)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package net.shadowfacts.phycon.networking
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketSender
|
||||||
|
import net.minecraft.network.Packet
|
||||||
|
import net.minecraft.network.PacketByteBuf
|
||||||
|
import net.minecraft.server.MinecraftServer
|
||||||
|
import net.minecraft.server.network.ServerPlayNetworkHandler
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||||
|
import net.shadowfacts.phycon.network.block.terminal.TerminalBlockEntity
|
||||||
|
import net.shadowfacts.phycon.network.block.terminal.TerminalScreenHandler
|
||||||
|
import net.shadowfacts.phycon.util.SortMode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
object C2STerminalUpdateDisplayedItems: ServerReceiver {
|
||||||
|
|
||||||
|
override val CHANNEL = Identifier(PhysicalConnectivity.MODID, "terminal_update_displayed")
|
||||||
|
|
||||||
|
operator fun invoke(terminal: TerminalBlockEntity, query: String, sortMode: SortMode): Packet<*> {
|
||||||
|
val buf = PacketByteBufs.create()
|
||||||
|
|
||||||
|
buf.writeIdentifier(terminal.world!!.registryKey.value)
|
||||||
|
buf.writeBlockPos(terminal.pos)
|
||||||
|
|
||||||
|
buf.writeString(query)
|
||||||
|
buf.writeVarInt(sortMode.ordinal)
|
||||||
|
|
||||||
|
return ClientPlayNetworking.createC2SPacket(CHANNEL, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun receive(server: MinecraftServer, player: ServerPlayerEntity, handler: ServerPlayNetworkHandler, buf: PacketByteBuf, responseSender: PacketSender) {
|
||||||
|
val dimID = buf.readIdentifier()
|
||||||
|
val pos = buf.readBlockPos()
|
||||||
|
val query = buf.readString()
|
||||||
|
val sortMode = SortMode.values()[buf.readVarInt()]
|
||||||
|
|
||||||
|
server.execute {
|
||||||
|
if (player.world.registryKey.value != dimID) return@execute
|
||||||
|
val screenHandler = player.currentScreenHandler
|
||||||
|
if (screenHandler !is TerminalScreenHandler) return@execute
|
||||||
|
if (screenHandler.terminal.pos != pos) return@execute
|
||||||
|
screenHandler.sendUpdatedItemsToClient(player, query, sortMode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package net.shadowfacts.phycon.networking
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
interface ClientReceiver: ClientPlayNetworking.PlayChannelHandler {
|
||||||
|
val CHANNEL: Identifier
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package net.shadowfacts.phycon.networking
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketSender
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.network.ClientPlayNetworkHandler
|
||||||
|
import net.minecraft.network.Packet
|
||||||
|
import net.minecraft.network.PacketByteBuf
|
||||||
|
import net.shadowfacts.phycon.network.block.terminal.TerminalBlockEntity
|
||||||
|
import net.shadowfacts.phycon.network.block.terminal.TerminalScreenHandler
|
||||||
|
import net.shadowfacts.phycon.util.SortMode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
object S2CTerminalUpdateDisplayedItems: ClientReceiver {
|
||||||
|
override val CHANNEL = C2STerminalUpdateDisplayedItems.CHANNEL
|
||||||
|
|
||||||
|
operator fun invoke(terminal: TerminalBlockEntity, entries: List<TerminalScreenHandler.Entry>, query: String, sortMode: SortMode): Packet<*> {
|
||||||
|
val buf = PacketByteBufs.create()
|
||||||
|
|
||||||
|
buf.writeIdentifier(terminal.world!!.registryKey.value)
|
||||||
|
buf.writeBlockPos(terminal.pos)
|
||||||
|
|
||||||
|
buf.writeVarInt(entries.size)
|
||||||
|
for (e in entries) {
|
||||||
|
buf.writeItemStack(e.stack)
|
||||||
|
buf.writeVarInt(e.amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.writeString(query)
|
||||||
|
buf.writeVarInt(sortMode.ordinal)
|
||||||
|
|
||||||
|
return ServerPlayNetworking.createS2CPacket(CHANNEL, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun receive(client: MinecraftClient, handler: ClientPlayNetworkHandler, buf: PacketByteBuf, responseSender: PacketSender) {
|
||||||
|
val dimID = buf.readIdentifier()
|
||||||
|
val pos = buf.readBlockPos()
|
||||||
|
val entryCount = buf.readVarInt()
|
||||||
|
val entries = ArrayList<TerminalScreenHandler.Entry>(entryCount)
|
||||||
|
for (i in 0 until entryCount) {
|
||||||
|
entries.add(TerminalScreenHandler.Entry(buf.readItemStack(), buf.readVarInt()))
|
||||||
|
}
|
||||||
|
val query = buf.readString()
|
||||||
|
val sortMode = SortMode.values()[buf.readVarInt()]
|
||||||
|
|
||||||
|
client.execute {
|
||||||
|
if (client.player!!.world.registryKey.value != dimID) return@execute
|
||||||
|
val screenHandler = client.player!!.currentScreenHandler
|
||||||
|
if (screenHandler !is TerminalScreenHandler) return@execute
|
||||||
|
if (screenHandler.terminal.pos != pos) return@execute
|
||||||
|
screenHandler.receivedUpdatedItemsFromServer(entries, query, sortMode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ enum class SortMode {
|
||||||
ALPHABETICAL;
|
ALPHABETICAL;
|
||||||
|
|
||||||
val prev: SortMode
|
val prev: SortMode
|
||||||
get() = values()[(ordinal - 1) % values().size]
|
get() = values()[(ordinal - 1 + values().size) % values().size]
|
||||||
|
|
||||||
val next: SortMode
|
val next: SortMode
|
||||||
get() = values()[(ordinal + 1) % values().size]
|
get() = values()[(ordinal + 1) % values().size]
|
||||||
|
|
Loading…
Reference in New Issue