From 036de121c7b32dcfee1345fe2d2caef4c69ff9d1 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 1 Jan 2024 23:05:36 +0700 Subject: [PATCH] =?UTF-8?q?Revert=20"DBot=20=E2=80=94=20=D0=A1=D0=B5=D0=B3?= =?UTF-8?q?=D0=BE=D0=B4=D0=BD=D1=8F,=20=D0=B2=207:53"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 8abb4e159827bd2c02e4c9d143179fe2098a7d1e. Revert "бакпорт изменений curios под смачный пердёж" This reverts commit 1cbf73cdfd783e591e746d4c37640a03ab4d1fc4. Revert "помогите" This reverts commit b97e18ca5f60c5072095c1d64c1a45406705618f. Revert "DBotThePony — Сегодня, в 17:11" This reverts commit 0da87980f7a62fd657391e67ecc3eea875f79622. Revert "android health bar + 1px wider energy bar" This reverts commit cbaf89d4a78e8e004ff712733987b1a54e39784f. Revert "Resolve conflicts between 1.19.3 code and 1.19.2 code" This reverts commit 006cbc75e39d865aa70526bc758e5600b349027b. Revert "Add missing import" This reverts commit 275e340243add074c8c3c1f49daf7c651d482d3e. Revert "Multi packet mattery registry sync" This reverts commit 3dcaed64cde42fa3593a992bba8d69ad9a329e70. Revert "Increase (de)compress buffer sizes" This reverts commit 04a5e87fec44e4b2763470e4c258f93030020de7. Revert "Compress matter registry packet" This reverts commit 36c14be025f5af8bd4ff974ba18d887a84e62487. Revert "Payload may not be larger than 1048576 bytes" This reverts commit 26a064fbe2fb456f1a9089bd239e3c95f7686262. --- build.gradle.kts | 9 +- gradle.properties | 2 +- .../mc/otm/OverdriveThatMatters.java | 5 - .../ru/dbotthepony/mc/otm/ClientConfig.kt | 4 - .../android/feature/NanobotsArmorFeature.kt | 9 +- .../otm/capability/MatteryPlayerCapability.kt | 4 - .../dbotthepony/mc/otm/client/MatteryGUI.kt | 121 +------ .../mc/otm/compat/curios/CuriosCompat.kt | 20 +- .../kotlin/ru/dbotthepony/mc/otm/core/Ext.kt | 6 +- .../mc/otm/core/util/FriendlyStreams.kt | 310 ------------------ .../dbotthepony/mc/otm/matter/IMatterValue.kt | 20 -- .../mc/otm/matter/MatterManager.kt | 227 ++----------- .../textures/gui/player_bars.png | Bin 282 -> 348 bytes .../textures/gui/player_bars_health.png | Bin 367 -> 0 bytes 14 files changed, 53 insertions(+), 684 deletions(-) delete mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt delete mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/player_bars_health.png diff --git a/build.gradle.kts b/build.gradle.kts index 99cb3bf6c..cbf11166a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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() } diff --git a/gradle.properties b/gradle.properties index a17051611..5890f6fe4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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 diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index ae34d147f..61fb44f29 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -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(); } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/ClientConfig.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/ClientConfig.kt index ebfcfc052..5f1638064 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/ClientConfig.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/ClientConfig.kt @@ -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() } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt index ef2f24fc4..f1f9723d9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NanobotsArmorFeature.kt @@ -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) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt index caef7fa8f..fd891abaa 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt @@ -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 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt index 1b714c5ca..bdca96c1e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt @@ -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) - } - } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/curios/CuriosCompat.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/curios/CuriosCompat.kt index d2c2b3a2e..ddda5ccb1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/curios/CuriosCompat.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/curios/CuriosCompat.kt @@ -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> { val handler = getCapability(MatteryCapability.CURIOS_INVENTORY).orNull() ?: return listOf() @@ -34,9 +28,9 @@ private fun Player.getCuriosSlotsImpl(): Collection> { val sortedIdentifiers = ArrayList(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> get() { private fun Player.curiosStreamImpl(includeCosmetics: Boolean): Stream { val handler = getCapability(MatteryCapability.CURIOS_INVENTORY).orNull() ?: return Stream.empty() - val result = ArrayList>() + val result = LinkedList>() for ((identifier, curio) in handler.curios) { result.add(curio.stacks.stream()) @@ -85,7 +79,7 @@ private fun Player.curiosStreamImpl(includeCosmetics: Boolean): Stream { @@ -99,7 +93,7 @@ fun Player.curiosStream(includeCosmetics: Boolean = true): Stream private fun Player.curiosAwareStreamImpl(includeCosmetics: Boolean): Stream { val handler = getCapability(MatteryCapability.CURIOS_INVENTORY).orNull() ?: return Stream.empty() - val result = ArrayList>() + val result = LinkedList>() for ((identifier, curio) in handler.curios) { result.add(curio.stacks.awareStream()) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt index c62fb5ac8..5466189c0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt @@ -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 > StateHolder<*, *>.get(property: Property): T { return getValue(property) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt deleted file mode 100644 index 770669beb..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt +++ /dev/null @@ -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).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).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.writeCollection(collection: Collection, writer: S.(V) -> Unit) { - writeVarIntLE(collection.size) - - for (value in collection) { - writer(this, value) - } -} - -fun > 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.readCollection(reader: S.() -> V) = readCollection(reader, ::ArrayList) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterValue.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterValue.kt index 3cf308558..7fc49dd3b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterValue.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterValue.kt @@ -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 { 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 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt index 4c5ca0d6c..d9d2f187c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt @@ -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() - - 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() - 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() - 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, + val comments: Map> + ) : 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) { 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(v.size).also { it.addAll(v) } } + + LOGGER.debug("Updating matter registry from packet took ${time.millis}ms") } } } diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/player_bars.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/player_bars.png index 8e35511c97fe8e852d6a18f44dd708b4bd564489..4c867588e72db77b743a676a3ee8de66f049f0b6 100644 GIT binary patch delta 304 zcmbQmbcbnzBnKM<1H+|j_4N}K73w()JR*x382I*sFrx))unJJ}qo<2wNJZS+8-`v- z9YoqLR!+Os(VCE$Tc$Yeont}ox(5&Sg19tUxHn!btId71BnLAC1H)5}e&30T3Z@bPJ|V9EA9()10Tg7=(9qcUIA-BZSs_PmAos)S z!`eWKqa?^L_&)?N+-u$&Inhp{zTDHrF(kwJ?KMZP1_K_KixFFQ{_nkehEYhO zZrkdk*LcfW85kPu4gfiSAM|Hf0Ob(CLUzJWMw@fn6_@A9@*V_qY44Z22Z~&z_3p^r=85sBugD~Uq z{1quc!3CZ!jv*P&Z>MeKYYGrx@plOfJox*6|J6rar)qbcG%ifbG7CP?dg7eRv4dG} zPYF0MFrMY#(Rt99clD8iFHQ`MEL+%jtW2CL;h&Zrp?d6d%2Wm>jtu@Ab%*(~BbNTx zkBnOvmL1*(6#UU>ePQN_+c{gyQtcSOw+AwD+z{SS+rEE$S*nH0#Pdg?rpqik@ii5w ihC`vDq2AtQX8zLM3&eP)FF6BrD}$%2pUXO@geCxpMUYtl