diff --git a/src/main/java/com/falsepattern/chunk/internal/mixin/helpers/LockHelper.java b/src/main/java/com/falsepattern/chunk/internal/mixin/helpers/LockHelper.java new file mode 100644 index 0000000..b9f3dc2 --- /dev/null +++ b/src/main/java/com/falsepattern/chunk/internal/mixin/helpers/LockHelper.java @@ -0,0 +1,30 @@ +/* + * ChunkAPI + * + * Copyright (C) 2023-2025 FalsePattern, The MEGA Team, LegacyModdingMC contributors + * All Rights Reserved + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, only version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.falsepattern.chunk.internal.mixin.helpers; + +import java.util.concurrent.locks.ReentrantLock; + +public class LockHelper { + public static final ReentrantLock bufferLockS21PacketChunkData = new ReentrantLock(); + public static final ReentrantLock bufferLockS26PacketMapChunkBulk = new ReentrantLock(); +} diff --git a/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/vanilla/S21PacketChunkDataMixin.java b/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/vanilla/S21PacketChunkDataMixin.java index 2a1c5ba..99faabb 100644 --- a/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/vanilla/S21PacketChunkDataMixin.java +++ b/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/vanilla/S21PacketChunkDataMixin.java @@ -23,6 +23,7 @@ package com.falsepattern.chunk.internal.mixin.mixins.common.vanilla; import com.falsepattern.chunk.internal.DataRegistryImpl; +import com.falsepattern.chunk.internal.mixin.helpers.LockHelper; import lombok.val; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -90,10 +91,6 @@ public abstract class S21PacketChunkDataMixin { ExtendedBlockStorage[] subChunks = chunk.getBlockStorageArray(); S21PacketChunkData.Extracted extracted = new S21PacketChunkData.Extracted(); - if (buffer.length < DataRegistryImpl.maxPacketSize()) { - buffer = new byte[DataRegistryImpl.maxPacketSize()]; - } - if (forceUpdate) { chunk.sendUpdates = true; } @@ -104,10 +101,21 @@ public abstract class S21PacketChunkDataMixin { } } - int length = DataRegistryImpl.writeToBuffer(chunk, extracted.field_150280_b, forceUpdate, buffer); + while (!LockHelper.bufferLockS21PacketChunkData.tryLock()) { + Thread.yield(); + } + try { + if (buffer.length < DataRegistryImpl.maxPacketSize()) { + buffer = new byte[DataRegistryImpl.maxPacketSize()]; + } - extracted.field_150282_a = new byte[length]; - System.arraycopy(buffer, 0, extracted.field_150282_a, 0, length); + int length = DataRegistryImpl.writeToBuffer(chunk, extracted.field_150280_b, forceUpdate, buffer); + + extracted.field_150282_a = new byte[length]; + System.arraycopy(buffer, 0, extracted.field_150282_a, 0, length); + } finally { + LockHelper.bufferLockS21PacketChunkData.unlock(); + } return extracted; } diff --git a/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/vanilla/S26PacketMapChunkBulkMixin.java b/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/vanilla/S26PacketMapChunkBulkMixin.java index 70c176d..c2a3009 100644 --- a/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/vanilla/S26PacketMapChunkBulkMixin.java +++ b/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/vanilla/S26PacketMapChunkBulkMixin.java @@ -22,6 +22,7 @@ package com.falsepattern.chunk.internal.mixin.mixins.common.vanilla; +import com.falsepattern.chunk.internal.mixin.helpers.LockHelper; import lombok.val; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -90,21 +91,29 @@ public abstract class S26PacketMapChunkBulkMixin { subChunkMSBMasks = new int[chunkCount]; datas = new byte[chunkCount][]; - if (inflaterBuffer.length < deflatedSize) { - inflaterBuffer = new byte[deflatedSize]; + while (!LockHelper.bufferLockS26PacketMapChunkBulk.tryLock()) { + Thread.yield(); } - - data.readBytes(inflaterBuffer, 0, deflatedSize); - byte[] buf = new byte[S21PacketChunkData.func_149275_c() * chunkCount]; - Inflater inflater = new Inflater(); - inflater.setInput(inflaterBuffer, 0, deflatedSize); - + byte[] buf; try { - inflater.inflate(buf); - } catch (DataFormatException dataformatexception) { - throw new IOException("Bad compressed data format"); + if (inflaterBuffer.length < deflatedSize) { + inflaterBuffer = new byte[deflatedSize]; + } + + data.readBytes(inflaterBuffer, 0, deflatedSize); + buf = new byte[S21PacketChunkData.func_149275_c() * chunkCount]; + Inflater inflater = new Inflater(); + inflater.setInput(inflaterBuffer, 0, deflatedSize); + + try { + inflater.inflate(buf); + } catch (DataFormatException dataformatexception) { + throw new IOException("Bad compressed data format"); + } finally { + inflater.end(); + } } finally { - inflater.end(); + LockHelper.bufferLockS26PacketMapChunkBulk.unlock(); } int pos = 0;