Revert "DBot — Сегодня, в 7:53"
This reverts commit8abb4e1598
. Revert "бакпорт изменений curios под смачный пердёж" This reverts commit1cbf73cdfd
. Revert "помогите" This reverts commitb97e18ca5f
. Revert "DBotThePony — Сегодня, в 17:11" This reverts commit0da87980f7
. Revert "android health bar + 1px wider energy bar" This reverts commitcbaf89d4a7
. Revert "Resolve conflicts between 1.19.3 code and 1.19.2 code" This reverts commit006cbc75e3
. Revert "Add missing import" This reverts commit275e340243
. Revert "Multi packet mattery registry sync" This reverts commit3dcaed64cd
. Revert "Increase (de)compress buffer sizes" This reverts commit04a5e87fec
. Revert "Compress matter registry packet" This reverts commit36c14be025
. Revert "Payload may not be larger than 1048576 bytes" This reverts commit26a064fbe2
.
This commit is contained in:
parent
8abb4e1598
commit
036de121c7
@ -321,6 +321,7 @@ repositories {
|
||||
url = uri("https://maven.dbotthepony.ru")
|
||||
|
||||
content {
|
||||
includeGroup("top.theillusivec4.curios")
|
||||
includeGroup("yalter.mousetweaks")
|
||||
includeGroup("mekanism")
|
||||
includeGroup("lain.mods.cos")
|
||||
@ -356,14 +357,6 @@ repositories {
|
||||
}
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri("https://maven.theillusivec4.top/")
|
||||
|
||||
content {
|
||||
includeGroup("top.theillusivec4.curios")
|
||||
}
|
||||
}
|
||||
|
||||
// mavenCentral()
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ mixin_version=0.8.5
|
||||
jei_version=11.3.0.262
|
||||
jupiter_version=5.8.2
|
||||
mekanism_version=10.3.5.homebaked
|
||||
curios_version=5.1.4.1
|
||||
curios_version=5.1.1.0
|
||||
cosmetic_armor_reworked_version=v1
|
||||
jade_id=4010505
|
||||
configured_id=4011355
|
||||
|
@ -34,7 +34,6 @@ import ru.dbotthepony.mc.otm.client.model.GravitationStabilizerModel;
|
||||
import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel;
|
||||
import ru.dbotthepony.mc.otm.client.render.ShockwaveRenderer;
|
||||
import ru.dbotthepony.mc.otm.client.render.WidgetAtlasHolder;
|
||||
import ru.dbotthepony.mc.otm.compat.curios.CuriosCompatKt;
|
||||
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
|
||||
import ru.dbotthepony.mc.otm.compat.mekanism.TooltipsKt;
|
||||
import ru.dbotthepony.mc.otm.core.Decimal;
|
||||
@ -198,10 +197,6 @@ public final class OverdriveThatMatters {
|
||||
EVENT_BUS.addGenericListener(BlockEntity.class, EventPriority.NORMAL, QIOKt::attachCapabilities);
|
||||
}
|
||||
|
||||
if (ModList.get().isLoaded("curios")) {
|
||||
EVENT_BUS.addListener(EventPriority.NORMAL, CuriosCompatKt::onCuriosSlotModifiersUpdated);
|
||||
}
|
||||
|
||||
OreGen.INSTANCE.register();
|
||||
}
|
||||
|
||||
|
@ -22,10 +22,6 @@ object ClientConfig {
|
||||
.comment("Allow to scroll Exopack inventory in non OTM inventories when hovering just over inventory slots, not only scrollbar")
|
||||
.define("exopackFreeScroll", true)
|
||||
|
||||
var ANDROID_HEALTH_HUD: Boolean by specBuilder
|
||||
.comment("Replace hearts with health bar on HUD when you are an android")
|
||||
.define("ANDROID_HEALTH_HUD", true)
|
||||
|
||||
init {
|
||||
spec = specBuilder.build()
|
||||
}
|
||||
|
@ -18,17 +18,14 @@ import ru.dbotthepony.mc.otm.triggers.NanobotsArmorTrigger
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class NanobotsArmorFeature(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_ARMOR, android) {
|
||||
var strength by synchronizer.int(
|
||||
setter = setter@{
|
||||
value, access, _ -> access.write(value.coerceIn(0 .. 3))
|
||||
}
|
||||
)
|
||||
var strength: Int = 0
|
||||
set(value) { field = value.coerceIn(0 .. 3) }
|
||||
|
||||
var speed: Int = 0
|
||||
set(value) { field = value.coerceIn(0 .. 3) }
|
||||
|
||||
private var ticksPassed = 0
|
||||
var layers by synchronizer.int()
|
||||
private var layers = 0
|
||||
|
||||
override fun tickServer() {
|
||||
if (layers < strength + 1 && android.androidEnergy.extractEnergyInnerExact(ENERGY_PER_LAYER, true).isPositive) {
|
||||
|
@ -165,10 +165,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
|
||||
return _exoPackMenu!!
|
||||
}
|
||||
|
||||
fun recreateExoPackMenu() {
|
||||
_exoPackMenu = ExoPackInventoryMenu(this)
|
||||
}
|
||||
|
||||
private var shouldSendIteration = false
|
||||
var iteration = 0
|
||||
private set
|
||||
|
@ -17,9 +17,7 @@ import net.minecraftforge.client.event.RenderLevelStageEvent
|
||||
import net.minecraftforge.client.event.ScreenEvent
|
||||
import net.minecraftforge.client.gui.overlay.ForgeGui
|
||||
import net.minecraftforge.client.gui.overlay.GuiOverlayManager
|
||||
import ru.dbotthepony.mc.otm.ClientConfig
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
@ -28,29 +26,17 @@ import ru.dbotthepony.mc.otm.client.render.*
|
||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.core.formatPower
|
||||
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
import java.util.*
|
||||
import kotlin.math.ceil
|
||||
|
||||
object MatteryGUI {
|
||||
private val BARS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "player_bars"), 81f, 36f)
|
||||
private val BARS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "player_bars"), 80f, 36f)
|
||||
val CHARGE = BARS.subElement(height = 9f)
|
||||
val CHARGE_BG = BARS.subElement(y = 9f, height = 9f)
|
||||
|
||||
val CHARGE_HUNGER = BARS.subElement(y = 18f, height = 9f)
|
||||
val CHARGE_HUNGER_BG = BARS.subElement(y = 27f, height = 9f)
|
||||
|
||||
private val BARS_HP = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "player_bars_health"), 81f, 63f)
|
||||
|
||||
val HEALTH = BARS_HP.subElement(height = 9f)
|
||||
val HEALTH_BG = BARS_HP.subElement(y = 9f, height = 9f)
|
||||
val HEALTH_BG_NANOBOTS = BARS_HP.subElement(y = 18f, height = 9f)
|
||||
|
||||
val HEALTH_POISON = BARS_HP.subElement(y = 27f, height = 9f)
|
||||
val HEALTH_WITHER = BARS_HP.subElement(y = 36f, height = 9f)
|
||||
val HEALTH_ABSORB = BARS_HP.subElement(y = 45f, height = 9f)
|
||||
val HEALTH_FROZEN = BARS_HP.subElement(y = 54f, height = 9f)
|
||||
|
||||
private var originalBedButtonX = -1
|
||||
private var originalBedButtonY = -1
|
||||
|
||||
@ -113,10 +99,6 @@ object MatteryGUI {
|
||||
GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "air_level"))
|
||||
}
|
||||
|
||||
private val PLAYER_HEALTH_ELEMENT by lazy {
|
||||
GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "player_health"))
|
||||
}
|
||||
|
||||
var iteration = 0
|
||||
var showIterationUntil = 0L
|
||||
var showIterationUntilFade = 0L
|
||||
@ -195,7 +177,7 @@ object MatteryGUI {
|
||||
showIteration(event)
|
||||
}
|
||||
|
||||
private fun renderFoodAndAir(event: RenderGuiOverlayEvent.Pre) {
|
||||
fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) {
|
||||
if (event.overlay != FOOD_LEVEL_ELEMENT && event.overlay != AIR_LEVEL_ELEMENT) {
|
||||
return
|
||||
}
|
||||
@ -226,8 +208,6 @@ object MatteryGUI {
|
||||
return
|
||||
}
|
||||
|
||||
if (!gui.shouldDrawSurvivalElements()) return
|
||||
|
||||
var level: Float
|
||||
|
||||
if (mattery.androidEnergy.maxBatteryLevel.isZero) {
|
||||
@ -248,14 +228,14 @@ object MatteryGUI {
|
||||
val top: Int = height - gui.rightHeight
|
||||
gui.rightHeight += 10
|
||||
|
||||
val leftPadding = ceil(level * 80f - 0.5f)
|
||||
val leftPadding = ceil(level * 79f - 0.5f)
|
||||
|
||||
if (ply.hasEffect(MobEffects.HUNGER)) {
|
||||
CHARGE_HUNGER_BG.render(event.poseStack, left.toFloat(), top.toFloat())
|
||||
CHARGE_HUNGER.renderPartial(event.poseStack, left.toFloat() - leftPadding + 80f, top.toFloat(), width = leftPadding)
|
||||
CHARGE_HUNGER.renderPartial(event.poseStack, left.toFloat() - leftPadding + 79f, top.toFloat(), width = leftPadding)
|
||||
} else {
|
||||
CHARGE_BG.render(event.poseStack, left.toFloat(), top.toFloat())
|
||||
CHARGE.renderPartial(event.poseStack, left.toFloat() - leftPadding + 80f, top.toFloat(), width = leftPadding)
|
||||
CHARGE.renderPartial(event.poseStack, left.toFloat() - leftPadding + 79f, top.toFloat(), width = leftPadding)
|
||||
}
|
||||
|
||||
val formattedPower = mattery.androidEnergy.batteryLevel.formatPower()
|
||||
@ -269,95 +249,4 @@ object MatteryGUI {
|
||||
event.poseStack.popPose()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSpriteForPlayer(player: Player): SubSkinElement {
|
||||
if (player.hasEffect(MobEffects.POISON)) {
|
||||
return HEALTH_POISON
|
||||
} else if (player.hasEffect(MobEffects.WITHER)) {
|
||||
return HEALTH_WITHER
|
||||
} else if (player.isFullyFrozen()) {
|
||||
return HEALTH_FROZEN
|
||||
}
|
||||
|
||||
return HEALTH
|
||||
}
|
||||
|
||||
private fun getHealthColorForPlayer(player: Player): Int {
|
||||
if (player.hasEffect(MobEffects.POISON)) {
|
||||
return RGBAColor.DARK_GREEN.toInt()
|
||||
} else if (player.hasEffect(MobEffects.WITHER)) {
|
||||
return RGBAColor.WHITE.toInt()
|
||||
} else if (player.isFullyFrozen()) {
|
||||
return RGBAColor.AQUA.toInt()
|
||||
}
|
||||
|
||||
return RGBAColor.RED.toInt()
|
||||
} // можно вынести в конфиг, но для этого нужен селектор цвета
|
||||
|
||||
private fun renderPlayerHealth(event: RenderGuiOverlayEvent.Pre) {
|
||||
if (!ClientConfig.ANDROID_HEALTH_HUD) return
|
||||
|
||||
val ply: LocalPlayer = minecraft.player ?: return
|
||||
|
||||
var mattery = ply.matteryPlayer
|
||||
|
||||
if (!ply.isAlive && mattery == null) {
|
||||
mattery = lastState
|
||||
}
|
||||
|
||||
val gui = minecraft.gui as? ForgeGui ?: return
|
||||
|
||||
if (mattery != null && mattery.isAndroid) {
|
||||
event.isCanceled = true
|
||||
lastState = mattery
|
||||
|
||||
if (!gui.shouldDrawSurvivalElements()) return
|
||||
|
||||
val level: Float = (ply.health / ply.maxHealth).coerceIn(0.0f .. 1.0f)
|
||||
val levelAbsorb: Float = (ply.absorptionAmount / ply.maxHealth).coerceIn(0.0f .. 1.0f)
|
||||
|
||||
gui.setupOverlayRenderState(true, false)
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
|
||||
val width = event.window.guiScaledWidth
|
||||
val height = event.window.guiScaledHeight
|
||||
val left = width / 2 - 10 - 81
|
||||
val top: Int = height - gui.leftHeight
|
||||
gui.leftHeight += 10
|
||||
|
||||
HEALTH_BG.render(event.poseStack, left.toFloat(), top.toFloat())
|
||||
|
||||
if (mattery.hasFeature(AndroidFeatures.NANOBOTS_ARMOR)) {
|
||||
val featArmor = mattery.getFeature(AndroidFeatures.NANOBOTS_ARMOR) as NanobotsArmorFeature
|
||||
val levelArmor: Float = (featArmor.layers.toFloat() / (featArmor.strength + 1).toFloat()).coerceIn(0.0f .. 1.0f)
|
||||
|
||||
HEALTH_BG_NANOBOTS.renderPartial(event.poseStack, left.toFloat(), top.toFloat(), width = ceil(levelArmor * 81f))
|
||||
}
|
||||
|
||||
getSpriteForPlayer(ply).renderPartial(event.poseStack, left.toFloat(), top.toFloat(), width = ceil(level * 80f - 0.5f))
|
||||
if (levelAbsorb > 0) {
|
||||
HEALTH_ABSORB.renderPartial(event.poseStack, left.toFloat(), top.toFloat(), width = ceil(levelAbsorb * 80f - 0.5f))
|
||||
}
|
||||
|
||||
var formattedHealth = "%d/%d".format(ply.health.toInt(), ply.maxHealth.toInt())
|
||||
if (ply.absorptionAmount > 0)
|
||||
formattedHealth = "%d+%d/%d".format(ply.health.toInt(), ply.absorptionAmount.toInt(), ply.maxHealth.toInt())
|
||||
|
||||
event.poseStack.pushPose()
|
||||
event.poseStack.scale(0.5f, 0.5f, 0.5f)
|
||||
|
||||
minecraft.font.drawAligned(event.poseStack, formattedHealth, TextAlign.CENTER_RIGHT, (left - 1f) * 2f, (top + 5.5f) * 2f, RGBAColor.BLACK.toInt())
|
||||
minecraft.font.drawAligned(event.poseStack, formattedHealth, TextAlign.CENTER_RIGHT, (left - 2f) * 2f, (top + 4.5f) * 2f, getHealthColorForPlayer(ply))
|
||||
|
||||
event.poseStack.popPose()
|
||||
}
|
||||
}
|
||||
|
||||
fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) {
|
||||
if (event.overlay == FOOD_LEVEL_ELEMENT || event.overlay == AIR_LEVEL_ELEMENT) {
|
||||
renderFoodAndAir(event)
|
||||
} else if (event.overlay == PLAYER_HEALTH_ELEMENT) {
|
||||
renderPlayerHealth(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,26 +6,20 @@ import net.minecraft.world.inventory.Slot
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.fml.ModList
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.container.awareStream
|
||||
import ru.dbotthepony.mc.otm.container.stream
|
||||
import ru.dbotthepony.mc.otm.core.AwareItemStack
|
||||
import ru.dbotthepony.mc.otm.core.orNull
|
||||
import top.theillusivec4.curios.api.CuriosApi
|
||||
import top.theillusivec4.curios.api.event.SlotModifiersUpdatedEvent
|
||||
import top.theillusivec4.curios.common.inventory.CosmeticCurioSlot
|
||||
import top.theillusivec4.curios.common.inventory.CurioSlot
|
||||
import java.util.*
|
||||
import java.util.stream.Stream
|
||||
|
||||
val isCuriosLoaded by lazy {
|
||||
ModList.get().isLoaded(CuriosApi.MODID)
|
||||
}
|
||||
|
||||
fun onCuriosSlotModifiersUpdated(event: SlotModifiersUpdatedEvent) {
|
||||
check(isCuriosLoaded) { "Curios is not loaded!" }
|
||||
event.entity.matteryPlayer?.recreateExoPackMenu()
|
||||
}
|
||||
|
||||
private fun Player.getCuriosSlotsImpl(): Collection<Pair<Slot, Slot?>> {
|
||||
val handler = getCapability(MatteryCapability.CURIOS_INVENTORY).orNull() ?: return listOf()
|
||||
|
||||
@ -34,9 +28,9 @@ private fun Player.getCuriosSlotsImpl(): Collection<Pair<Slot, Slot?>> {
|
||||
val sortedIdentifiers = ArrayList<String>(handler.curios.keys.size)
|
||||
sortedIdentifiers.addAll(handler.curios.keys)
|
||||
|
||||
//if (handler.curios !is LinkedHashMap) {
|
||||
// sortedIdentifiers.sort()
|
||||
//}
|
||||
if (handler.curios !is LinkedHashMap) {
|
||||
sortedIdentifiers.sort()
|
||||
}
|
||||
|
||||
for (identifier in sortedIdentifiers) {
|
||||
val curio = handler.curios[identifier]!!
|
||||
@ -75,7 +69,7 @@ val Player.curiosSlots: Collection<Pair<Slot, Slot?>> get() {
|
||||
private fun Player.curiosStreamImpl(includeCosmetics: Boolean): Stream<out ItemStack> {
|
||||
val handler = getCapability(MatteryCapability.CURIOS_INVENTORY).orNull() ?: return Stream.empty()
|
||||
|
||||
val result = ArrayList<Stream<out ItemStack>>()
|
||||
val result = LinkedList<Stream<out ItemStack>>()
|
||||
|
||||
for ((identifier, curio) in handler.curios) {
|
||||
result.add(curio.stacks.stream())
|
||||
@ -85,7 +79,7 @@ private fun Player.curiosStreamImpl(includeCosmetics: Boolean): Stream<out ItemS
|
||||
}
|
||||
}
|
||||
|
||||
return result.stream().flatMap { it }
|
||||
return Streams.concat(*result.toTypedArray())
|
||||
}
|
||||
|
||||
fun Player.curiosStream(includeCosmetics: Boolean = true): Stream<out ItemStack> {
|
||||
@ -99,7 +93,7 @@ fun Player.curiosStream(includeCosmetics: Boolean = true): Stream<out ItemStack>
|
||||
private fun Player.curiosAwareStreamImpl(includeCosmetics: Boolean): Stream<out AwareItemStack> {
|
||||
val handler = getCapability(MatteryCapability.CURIOS_INVENTORY).orNull() ?: return Stream.empty()
|
||||
|
||||
val result = ArrayList<Stream<out AwareItemStack>>()
|
||||
val result = LinkedList<Stream<out AwareItemStack>>()
|
||||
|
||||
for ((identifier, curio) in handler.curios) {
|
||||
result.add(curio.stacks.awareStream())
|
||||
|
@ -28,8 +28,8 @@ import net.minecraftforge.items.IItemHandler
|
||||
import net.minecraftforge.registries.ForgeRegistries
|
||||
import net.minecraftforge.registries.ForgeRegistry
|
||||
import net.minecraftforge.registries.IForgeRegistry
|
||||
import java.io.InputStream
|
||||
import java.lang.ref.Reference
|
||||
import java.lang.ref.WeakReference
|
||||
import java.math.BigInteger
|
||||
import java.util.Arrays
|
||||
import java.util.Spliterators
|
||||
@ -344,10 +344,6 @@ fun FriendlyByteBuf.readItemType(): Item? {
|
||||
return ForgeRegistries.ITEMS.getValue(readInt())
|
||||
}
|
||||
|
||||
fun InputStream.readItemType(): Item? {
|
||||
return ForgeRegistries.ITEMS.getValue(readInt())
|
||||
}
|
||||
|
||||
operator fun <T : Comparable<T>> StateHolder<*, *>.get(property: Property<T>): T {
|
||||
return getValue(property)
|
||||
}
|
||||
|
@ -1,310 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.core.util
|
||||
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonNull
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParseException
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import io.netty.buffer.ByteBufInputStream
|
||||
import io.netty.buffer.ByteBufOutputStream
|
||||
import io.netty.handler.codec.EncoderException
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.NbtAccounter
|
||||
import net.minecraft.nbt.NbtIo
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.registries.ForgeRegistries
|
||||
import net.minecraftforge.registries.ForgeRegistry
|
||||
import ru.dbotthepony.mc.otm.core.readDouble
|
||||
import ru.dbotthepony.mc.otm.core.readInt
|
||||
import ru.dbotthepony.mc.otm.core.readVarIntLE
|
||||
import ru.dbotthepony.mc.otm.core.readVarLongLE
|
||||
import ru.dbotthepony.mc.otm.core.writeDouble
|
||||
import ru.dbotthepony.mc.otm.core.writeInt
|
||||
import ru.dbotthepony.mc.otm.core.writeVarIntLE
|
||||
import ru.dbotthepony.mc.otm.core.writeVarLongLE
|
||||
import java.io.*
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
// But seriously, Mojang, why would you need to derive from ByteBuf directly, when you can implement
|
||||
// your own InputStream and OutputStream, since ByteBuf is meant to be operated on most time like a stream anyway?
|
||||
|
||||
// netty ByteBuf -> netty ByteBufInputStream -> Minecraft FriendlyInputStream
|
||||
|
||||
fun OutputStream.writeNbt(value: CompoundTag) {
|
||||
try {
|
||||
NbtIo.write(value, if (this is DataOutputStream) this else DataOutputStream(this))
|
||||
} catch (ioexception: IOException) {
|
||||
throw EncoderException(ioexception)
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream.readBinaryString(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): String {
|
||||
val size = readVarIntLE()
|
||||
require(size >= 0) { "Negative payload size: $size" }
|
||||
sizeLimit.accountBytes(size.toLong())
|
||||
val bytes = ByteArray(size)
|
||||
read(bytes)
|
||||
return bytes.decodeToString()
|
||||
}
|
||||
|
||||
fun OutputStream.writeBinaryString(input: String) {
|
||||
val bytes = input.encodeToByteArray()
|
||||
writeVarIntLE(bytes.size)
|
||||
write(bytes)
|
||||
}
|
||||
|
||||
fun InputStream.readNbt(accounter: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): CompoundTag {
|
||||
return try {
|
||||
NbtIo.read(if (this is DataInputStream) this else DataInputStream(this), accounter)
|
||||
} catch (ioexception: IOException) {
|
||||
throw EncoderException(ioexception)
|
||||
}
|
||||
}
|
||||
|
||||
fun OutputStream.writeItem(itemStack: ItemStack, limitedTag: Boolean = true) {
|
||||
if (itemStack.isEmpty) {
|
||||
write(0)
|
||||
} else {
|
||||
write(1)
|
||||
val id = (ForgeRegistries.ITEMS as ForgeRegistry<Item>).getID(itemStack.item)
|
||||
|
||||
writeInt(id)
|
||||
writeInt(itemStack.count)
|
||||
|
||||
var compoundtag: CompoundTag? = null
|
||||
|
||||
if (itemStack.item.isDamageable(itemStack) || itemStack.item.shouldOverrideMultiplayerNbt()) {
|
||||
compoundtag = if (limitedTag) itemStack.shareTag else itemStack.tag
|
||||
}
|
||||
|
||||
write(if (compoundtag != null) 1 else 0)
|
||||
|
||||
if (compoundtag != null) {
|
||||
writeNbt(compoundtag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun NbtAccounter.accountBytes(bytes: Long) = accountBits(bytes * 8L)
|
||||
|
||||
fun InputStream.readItem(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): ItemStack {
|
||||
sizeLimit.accountBytes(1L)
|
||||
|
||||
if (read() == 0) {
|
||||
return ItemStack.EMPTY
|
||||
}
|
||||
|
||||
sizeLimit.accountBytes(9L)
|
||||
val item = (ForgeRegistries.ITEMS as ForgeRegistry<Item>).getValue(readInt())
|
||||
val itemStack = ItemStack(item, readInt())
|
||||
|
||||
if (read() != 0) {
|
||||
itemStack.readShareTag(readNbt(sizeLimit))
|
||||
}
|
||||
|
||||
return itemStack
|
||||
}
|
||||
|
||||
fun OutputStream.writeBigDecimal(value: BigDecimal) {
|
||||
writeInt(value.scale())
|
||||
val bytes = value.unscaledValue().toByteArray()
|
||||
writeVarIntLE(bytes.size)
|
||||
write(bytes)
|
||||
}
|
||||
|
||||
fun InputStream.readBigDecimal(sizeLimit: NbtAccounter = NbtAccounter(512L)): BigDecimal {
|
||||
val scale = readInt()
|
||||
val size = readVarIntLE()
|
||||
require(size >= 0) { "Negative payload size: $size" }
|
||||
sizeLimit.accountBytes(size.toLong() + 4L)
|
||||
val bytes = ByteArray(size)
|
||||
read(bytes)
|
||||
return BigDecimal(BigInteger(bytes), scale)
|
||||
}
|
||||
|
||||
private const val TYPE_NULL = 0x01
|
||||
private const val TYPE_DOUBLE = 0x02
|
||||
private const val TYPE_BOOLEAN = 0x03
|
||||
private const val TYPE_INT = 0x04
|
||||
private const val TYPE_STRING = 0x05
|
||||
private const val TYPE_ARRAY = 0x06
|
||||
private const val TYPE_OBJECT = 0x07
|
||||
|
||||
private fun fixSignedInt(read: Long): Long {
|
||||
val sign = read and 0x1L
|
||||
@Suppress("name_shadowing")
|
||||
val read = read ushr 1
|
||||
|
||||
if (sign == 1L) {
|
||||
return -read - 1L
|
||||
} else {
|
||||
return read
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes binary json to stream in Starbound Object Notation format
|
||||
*
|
||||
* just copy pasted this code from my another project because i was lazy
|
||||
*/
|
||||
fun OutputStream.writeJson(element: JsonElement) {
|
||||
if (element is JsonObject) {
|
||||
write(TYPE_OBJECT)
|
||||
writeVarIntLE(element.size())
|
||||
|
||||
for ((k, v) in element.entrySet()) {
|
||||
writeBinaryString(k)
|
||||
writeJson(v)
|
||||
}
|
||||
} else if (element is JsonArray) {
|
||||
write(TYPE_ARRAY)
|
||||
writeVarIntLE(element.size())
|
||||
|
||||
for (v in element) {
|
||||
writeJson(v)
|
||||
}
|
||||
} else if (element is JsonPrimitive) {
|
||||
if (element.isNumber) {
|
||||
val num = element.asNumber
|
||||
|
||||
if (num is Int || num is Long) {
|
||||
write(TYPE_INT)
|
||||
var int = num.toLong()
|
||||
|
||||
if (int < 0) {
|
||||
int = int.absoluteValue.shl(1).or(1)
|
||||
} else {
|
||||
int.shl(1)
|
||||
}
|
||||
|
||||
writeVarLongLE(int)
|
||||
} else if (num is Float || num is Double) {
|
||||
write(TYPE_DOUBLE)
|
||||
writeDouble(num.toDouble())
|
||||
} else {
|
||||
throw IllegalArgumentException("Unknown number type: ${num::class.qualifiedName}")
|
||||
}
|
||||
} else if (element.isString) {
|
||||
write(TYPE_STRING)
|
||||
writeBinaryString(element.asString)
|
||||
} else if (element.isBoolean) {
|
||||
write(TYPE_BOOLEAN)
|
||||
write(if (element.asBoolean) 1 else 0)
|
||||
} else {
|
||||
write(TYPE_NULL)
|
||||
}
|
||||
} else {
|
||||
throw IllegalArgumentException("Unknown element type: ${element::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads binary json from stream in Starbound Object Notation format
|
||||
*
|
||||
* just copy pasted this code from my another project because i was lazy
|
||||
*/
|
||||
fun InputStream.readJson(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): JsonElement {
|
||||
sizeLimit.accountBytes(1L)
|
||||
|
||||
return when (val id = read()) {
|
||||
TYPE_NULL -> JsonNull.INSTANCE
|
||||
TYPE_DOUBLE -> {
|
||||
sizeLimit.accountBytes(8L)
|
||||
JsonPrimitive(readDouble())
|
||||
}
|
||||
TYPE_BOOLEAN -> {
|
||||
sizeLimit.accountBytes(1L)
|
||||
JsonPrimitive(read() > 1)
|
||||
}
|
||||
TYPE_INT -> JsonPrimitive(fixSignedInt(readVarLongLE()))
|
||||
TYPE_STRING -> JsonPrimitive(readBinaryString(sizeLimit))
|
||||
TYPE_ARRAY -> {
|
||||
val values = readVarIntLE()
|
||||
|
||||
if (values == 0) return JsonArray()
|
||||
if (values < 0) throw JsonSyntaxException("Tried to read json array with $values elements in it")
|
||||
|
||||
val build = JsonArray(values)
|
||||
for (i in 0 until values) build.add(readJson(sizeLimit))
|
||||
return build
|
||||
}
|
||||
TYPE_OBJECT -> {
|
||||
val values = readVarIntLE()
|
||||
if (values == 0) return JsonObject()
|
||||
if (values < 0) throw JsonSyntaxException("Tried to read json object with $values elements in it")
|
||||
|
||||
val build = JsonObject()
|
||||
|
||||
for (i in 0 until values) {
|
||||
val key: String
|
||||
|
||||
try {
|
||||
key = readBinaryString(sizeLimit)
|
||||
} catch(err: Throwable) {
|
||||
throw JsonSyntaxException("Reading json object at $i", err)
|
||||
}
|
||||
|
||||
try {
|
||||
build.add(key, readJson(sizeLimit))
|
||||
} catch(err: Throwable) {
|
||||
throw JsonSyntaxException("Reading json object at $i with name $key", err)
|
||||
}
|
||||
}
|
||||
|
||||
return build
|
||||
}
|
||||
else -> throw JsonParseException("Unknown element type $id")
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream.readBinaryComponent(): Component? {
|
||||
return Component.Serializer.fromJson(readJson())
|
||||
}
|
||||
|
||||
fun OutputStream.writeBinaryComponent(component: Component) {
|
||||
writeJson(Component.Serializer.toJsonTree(component))
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.readJson(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18)): JsonElement {
|
||||
return ByteBufInputStream(this).readJson(sizeLimit)
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.writeJson(value: JsonElement) {
|
||||
ByteBufOutputStream(this).writeJson(value)
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.readBinaryComponent(): Component {
|
||||
return Component.Serializer.fromJson(readJson()) ?: throw NullPointerException("Received null component")
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.writeBinaryComponent(component: Component) {
|
||||
writeJson(Component.Serializer.toJsonTree(component))
|
||||
}
|
||||
|
||||
fun <S : OutputStream, V> S.writeCollection(collection: Collection<V>, writer: S.(V) -> Unit) {
|
||||
writeVarIntLE(collection.size)
|
||||
|
||||
for (value in collection) {
|
||||
writer(this, value)
|
||||
}
|
||||
}
|
||||
|
||||
fun <S : InputStream, V, C : MutableCollection<V>> S.readCollection(reader: S.() -> V, factory: (Int) -> C): C {
|
||||
val size = readVarIntLE()
|
||||
val collection = factory.invoke(size)
|
||||
|
||||
for (i in 0 until size) {
|
||||
collection.add(reader(this))
|
||||
}
|
||||
|
||||
return collection
|
||||
}
|
||||
|
||||
fun <S : InputStream, V> S.readCollection(reader: S.() -> V) = readCollection(reader, ::ArrayList)
|
@ -3,11 +3,7 @@ package ru.dbotthepony.mc.otm.matter
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import ru.dbotthepony.mc.otm.core.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.readDecimal
|
||||
import ru.dbotthepony.mc.otm.core.readDouble
|
||||
import ru.dbotthepony.mc.otm.core.writeDecimal
|
||||
import ru.dbotthepony.mc.otm.core.writeDouble
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
interface IMatterValue : Comparable<IMatterValue> {
|
||||
val matter: Decimal
|
||||
@ -55,11 +51,6 @@ fun FriendlyByteBuf.writeMatterValue(value: IMatterValue) {
|
||||
writeDouble(value.complexity)
|
||||
}
|
||||
|
||||
fun OutputStream.writeMatterValue(value: IMatterValue) {
|
||||
writeDecimal(value.matter)
|
||||
writeDouble(value.complexity)
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.readMatterValue(): IMatterValue {
|
||||
val matter = readDecimal()
|
||||
val complexity = readDouble()
|
||||
@ -71,17 +62,6 @@ fun FriendlyByteBuf.readMatterValue(): IMatterValue {
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream.readMatterValue(): IMatterValue {
|
||||
val matter = readDecimal()
|
||||
val complexity = readDouble()
|
||||
|
||||
if (matter.isZero && complexity == 0.0) {
|
||||
return IMatterValue.Companion
|
||||
} else {
|
||||
return MatterValue(matter, complexity)
|
||||
}
|
||||
}
|
||||
|
||||
data class MatterValue(
|
||||
override val matter: Decimal,
|
||||
override val complexity: Double
|
||||
|
@ -11,8 +11,6 @@ import com.google.gson.JsonSyntaxException
|
||||
import com.mojang.blaze3d.platform.InputConstants
|
||||
import com.mojang.brigadier.arguments.StringArgumentType
|
||||
import com.mojang.brigadier.context.CommandContext
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanFunction
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.Reference2BooleanFunction
|
||||
@ -72,7 +70,6 @@ import ru.dbotthepony.mc.otm.core.formatMatter
|
||||
import ru.dbotthepony.mc.otm.core.formatMatterFull
|
||||
import ru.dbotthepony.mc.otm.core.formatSiComponent
|
||||
import ru.dbotthepony.mc.otm.core.formatTickDuration
|
||||
import ru.dbotthepony.mc.otm.core.getID
|
||||
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||
import ru.dbotthepony.mc.otm.core.isActuallyEmpty
|
||||
import ru.dbotthepony.mc.otm.core.isZero
|
||||
@ -80,24 +77,16 @@ import ru.dbotthepony.mc.otm.core.orNull
|
||||
import ru.dbotthepony.mc.otm.core.readItemType
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.core.stream
|
||||
import ru.dbotthepony.mc.otm.core.util.readBinaryComponent
|
||||
import ru.dbotthepony.mc.otm.core.util.readCollection
|
||||
import ru.dbotthepony.mc.otm.core.util.writeBinaryComponent
|
||||
import ru.dbotthepony.mc.otm.core.util.writeCollection
|
||||
import ru.dbotthepony.mc.otm.core.writeItemType
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.network.RegistryNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.registry.RegistryDelegate
|
||||
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
|
||||
import java.io.DataInputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.io.File
|
||||
import java.io.OutputStream
|
||||
import java.math.BigInteger
|
||||
import java.util.*
|
||||
import java.util.function.Supplier
|
||||
import java.util.stream.Stream
|
||||
import java.util.zip.Deflater
|
||||
import java.util.zip.Inflater
|
||||
import kotlin.ConcurrentModificationException
|
||||
import kotlin.collections.ArrayDeque
|
||||
import kotlin.collections.ArrayList
|
||||
@ -479,7 +468,7 @@ object MatterManager {
|
||||
val ignoreDamageables = data["ignore_damageables"]?.asBoolean ?: false
|
||||
val allowBacktrack = data["allow_backtrack"]?.asBoolean ?: true
|
||||
|
||||
var stream = server.recipeManager.byType(findRecipeType).values.stream().filter { !it.isIncomplete }
|
||||
var stream = server.recipeManager.byType(findRecipeType).values.parallelStream().filter { !it.isIncomplete }
|
||||
|
||||
if (ignoreDamageables) {
|
||||
stream = stream.filter { it.ingredients.stream().flatMap { it.items.stream() }.noneMatch { it.isDamageableItem } }
|
||||
@ -1097,6 +1086,7 @@ object MatterManager {
|
||||
|
||||
fun tooltipEvent(event: ItemTooltipEvent) {
|
||||
val window = minecraft.window.window
|
||||
|
||||
if (InputConstants.isKeyDown(window, GLFW.GLFW_KEY_LEFT_SHIFT) || InputConstants.isKeyDown(window, GLFW.GLFW_KEY_RIGHT_SHIFT)) {
|
||||
val matter = get(event.itemStack, accountForStackSize = false)
|
||||
|
||||
@ -1376,7 +1366,7 @@ object MatterManager {
|
||||
matterValues[item] = value
|
||||
}
|
||||
|
||||
syncRegistry(PacketDistributor.ALL.noArg())
|
||||
RegistryNetworkChannel.send(PacketDistributor.ALL.noArg(), SyncPacket(matterValues, commentary))
|
||||
}
|
||||
|
||||
fun onDataPackSync(event: OnDatapackSyncEvent) {
|
||||
@ -1384,9 +1374,9 @@ object MatterManager {
|
||||
return
|
||||
|
||||
if (event.player == null) {
|
||||
syncRegistry(PacketDistributor.ALL.noArg())
|
||||
RegistryNetworkChannel.send(PacketDistributor.ALL.noArg(), SyncPacket(matterValues, commentary))
|
||||
} else {
|
||||
syncRegistry(PacketDistributor.PLAYER.with { event.player ?: throw ConcurrentModificationException() })
|
||||
RegistryNetworkChannel.send(PacketDistributor.PLAYER.with { event.player ?: throw ConcurrentModificationException() }, SyncPacket(matterValues, commentary))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1400,195 +1390,48 @@ object MatterManager {
|
||||
return matterValues[value] ?: IMatterValue.Companion
|
||||
}
|
||||
|
||||
private val receivedPackets = ArrayList<SyncPacket>()
|
||||
|
||||
private fun syncRegistry(distributor: PacketDistributor.PacketTarget) {
|
||||
val time = SystemTime()
|
||||
val stream = FastByteArrayOutputStream()
|
||||
val data = DataOutputStream(stream)
|
||||
|
||||
var commentsSize = commentary.size
|
||||
data.writeInt(matterValues.size)
|
||||
|
||||
for ((k, v) in matterValues) {
|
||||
data.writeInt(ForgeRegistries.ITEMS.getID(k))
|
||||
data.writeMatterValue(v)
|
||||
|
||||
val comment = commentary[k]
|
||||
|
||||
if (comment != null) {
|
||||
commentsSize--
|
||||
data.write(1)
|
||||
data.writeCollection(comment, OutputStream::writeBinaryComponent)
|
||||
} else {
|
||||
data.write(0)
|
||||
}
|
||||
}
|
||||
|
||||
data.writeInt(commentsSize)
|
||||
|
||||
for ((k, v) in commentary) {
|
||||
if (!matterValues.containsKey(k)) {
|
||||
data.writeInt(ForgeRegistries.ITEMS.getID(k))
|
||||
data.writeCollection(v, OutputStream::writeBinaryComponent)
|
||||
}
|
||||
}
|
||||
|
||||
val deflater = Deflater(5)
|
||||
deflater.setInput(stream.array, 0, stream.length)
|
||||
deflater.finish()
|
||||
|
||||
val chunks = ArrayList<SyncPacket>()
|
||||
var totalSize = 0
|
||||
var first = true
|
||||
|
||||
while (true) {
|
||||
val bytes = ByteArray(2 shl 20 - 1024)
|
||||
val written = deflater.deflate(bytes)
|
||||
|
||||
if (written == 0) {
|
||||
break
|
||||
} else {
|
||||
totalSize += written
|
||||
chunks.add(SyncPacket(bytes, written, if (first) { first = false; FIRST } else NORMAL))
|
||||
}
|
||||
}
|
||||
|
||||
if (chunks.size == 1) {
|
||||
chunks[0].mode = FIRST_AND_LAST
|
||||
} else if(chunks.size > 1) {
|
||||
chunks.last().mode = LAST
|
||||
}
|
||||
|
||||
LOGGER.debug("Encoding matter registry packet took ${time.millis}ms, (${stream.length} bytes total, $totalSize bytes compressed)")
|
||||
|
||||
for (chunk in chunks) {
|
||||
RegistryNetworkChannel.send(distributor, chunk)
|
||||
}
|
||||
}
|
||||
|
||||
private fun playRegistryPackets() {
|
||||
val time = SystemTime()
|
||||
var totalCompressedSize = 0
|
||||
|
||||
for (chunk in receivedPackets) {
|
||||
totalCompressedSize += chunk.length
|
||||
}
|
||||
|
||||
if (totalCompressedSize == 0) {
|
||||
return // what.
|
||||
}
|
||||
|
||||
val compressed = ByteArray(totalCompressedSize)
|
||||
var pointer = 0
|
||||
|
||||
for (chunk in receivedPackets) {
|
||||
for (i in 0 until chunk.length) {
|
||||
compressed[pointer++] = chunk.payload[i]
|
||||
}
|
||||
}
|
||||
|
||||
receivedPackets.clear()
|
||||
|
||||
val chunks = ArrayList<ByteArray>()
|
||||
var size = 0
|
||||
val inflater = Inflater()
|
||||
inflater.setInput(compressed)
|
||||
|
||||
while (!inflater.finished()) {
|
||||
val chunk = ByteArray(2 shl 16)
|
||||
val inflated = inflater.inflate(chunk)
|
||||
|
||||
if (inflated == 0) {
|
||||
break
|
||||
} else {
|
||||
size += inflated
|
||||
|
||||
if (size >= 1 shl 24 /* 16 MiB */) {
|
||||
throw IndexOutOfBoundsException("Pipe Bomb")
|
||||
}
|
||||
|
||||
if (inflated == 2 shl 16) {
|
||||
chunks.add(chunk)
|
||||
} else {
|
||||
chunks.add(chunk.copyOfRange(0, inflated))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val spliced = ByteArray(size)
|
||||
var pointer2 = 0
|
||||
|
||||
for (chunk in chunks) {
|
||||
for (i in chunk.indices) {
|
||||
spliced[pointer2++] = chunk[i]
|
||||
}
|
||||
}
|
||||
|
||||
val stream = FastByteArrayInputStream(spliced)
|
||||
val data = DataInputStream(stream)
|
||||
|
||||
val valuesSize = data.readInt()
|
||||
|
||||
matterValues.clear()
|
||||
commentary.clear()
|
||||
|
||||
for (i in 0 until valuesSize) {
|
||||
val type = data.readItemType()
|
||||
check(matterValues.put(type, data.readMatterValue()) == null) { "Duplicate item type $type" }
|
||||
|
||||
if (data.read() > 0) {
|
||||
commentary[type] = data.readCollection { readBinaryComponent()!! }
|
||||
}
|
||||
}
|
||||
|
||||
val commentsSize = data.readInt()
|
||||
|
||||
for (i in 0 until commentsSize) {
|
||||
val type = data.readItemType()
|
||||
check(commentary.put(type, data.readCollection { readBinaryComponent()!! }) == null) { "Duplicate commentary item type $type" }
|
||||
}
|
||||
|
||||
LOGGER.debug("Decoding matter registry packets took ${time.millis}ms ($totalCompressedSize bytes compressed, $size bytes total)")
|
||||
}
|
||||
|
||||
fun readSyncPacket(buff: FriendlyByteBuf): SyncPacket {
|
||||
LOGGER.info("Received matter registry packet, ${buff.readableBytes()} bytes in size")
|
||||
|
||||
val mode = buff.readByte()
|
||||
val bytes = ByteArray(buff.readableBytes())
|
||||
buff.readBytes(bytes)
|
||||
return SyncPacket(bytes, bytes.size, mode.toInt())
|
||||
val time = SystemTime()
|
||||
|
||||
val result = SyncPacket(
|
||||
buff.readMap(FriendlyByteBuf::readItemType, FriendlyByteBuf::readMatterValue),
|
||||
buff.readMap(FriendlyByteBuf::readItemType) { self -> self.readCollection(::ArrayList, FriendlyByteBuf::readComponent) }
|
||||
)
|
||||
|
||||
LOGGER.debug("Reading matter registry packet took ${time.millis}ms")
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private const val FIRST = 0
|
||||
private const val NORMAL = 1
|
||||
private const val LAST = 2
|
||||
private const val FIRST_AND_LAST = 3
|
||||
|
||||
class SyncPacket(val payload: ByteArray, val length: Int, var mode: Int) : MatteryPacket {
|
||||
class SyncPacket(
|
||||
val values: Map<Item, IMatterValue>,
|
||||
val comments: Map<Item, Collection<Component>>
|
||||
) : MatteryPacket {
|
||||
override fun write(buff: FriendlyByteBuf) {
|
||||
buff.writeByte(mode)
|
||||
buff.writeBytes(payload, 0, length)
|
||||
val time = SystemTime()
|
||||
buff.writeMap(values, FriendlyByteBuf::writeItemType, FriendlyByteBuf::writeMatterValue)
|
||||
buff.writeMap(comments, FriendlyByteBuf::writeItemType) { self, value -> self.writeCollection(value, FriendlyByteBuf::writeComponent) }
|
||||
LOGGER.debug("Encoding matter registry packet took ${time.millis}ms, written total ${buff.writerIndex() - 1} bytes")
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
if (SERVER_IS_LIVE)
|
||||
return // singleplayer or LAN host
|
||||
|
||||
if (mode == FIRST) {
|
||||
receivedPackets.clear()
|
||||
receivedPackets.add(this)
|
||||
} else if (mode == LAST) {
|
||||
receivedPackets.add(this)
|
||||
playRegistryPackets()
|
||||
} else if (mode == FIRST_AND_LAST) {
|
||||
receivedPackets.clear()
|
||||
receivedPackets.add(this)
|
||||
playRegistryPackets()
|
||||
} else {
|
||||
receivedPackets.add(this)
|
||||
val time = SystemTime()
|
||||
|
||||
matterValues.clear()
|
||||
matterValues.putAll(values)
|
||||
|
||||
commentary.clear()
|
||||
|
||||
for ((k, v) in comments) {
|
||||
commentary[k] = ArrayList<Component>(v.size).also { it.addAll(v) }
|
||||
}
|
||||
|
||||
LOGGER.debug("Updating matter registry from packet took ${time.millis}ms")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 348 B |
Binary file not shown.
Before Width: | Height: | Size: 367 B |
Loading…
Reference in New Issue
Block a user