diff --git a/src/launch/java/baritone/launch/mixins/MixinSodiumChunkProvider.java b/src/launch/java/baritone/launch/mixins/MixinSodiumChunkProvider.java new file mode 100644 index 000000000..5dd4b027e --- /dev/null +++ b/src/launch/java/baritone/launch/mixins/MixinSodiumChunkProvider.java @@ -0,0 +1,97 @@ +/* + * This file is part of Baritone. + * + * Baritone 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, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone 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 Baritone. If not, see . + */ + +package baritone.launch.mixins; + +import baritone.utils.accessor.IChunkArray; +import baritone.utils.accessor.IClientChunkProvider; +import baritone.utils.accessor.ISodiumChunkArray; +import net.minecraft.client.multiplayer.ClientChunkProvider; +import net.minecraft.client.world.ClientWorld; +import org.spongepowered.asm.mixin.*; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.concurrent.locks.StampedLock; + +@Pseudo +@Mixin(targets = "me.jellysquid.mods.sodium.client.world.SodiumChunkManager", remap = false) +public class MixinSodiumChunkProvider implements IClientChunkProvider { + + @Shadow + @Final + private StampedLock lock; + + @Shadow + @Final + private ClientWorld world; + + @Shadow + private int radius; + + @Unique + private static Constructor thisConstructor = null; + + @Unique + private static Field chunkArrayField = null; + + @Override + public ClientChunkProvider createThreadSafeCopy() { + // similar operation to https://github.com/jellysquid3/sodium-fabric/blob/d3528521d48a130322c910c6f0725cf365ebae6f/src/main/java/me/jellysquid/mods/sodium/client/world/SodiumChunkManager.java#L139 + long stamp = this.lock.writeLock(); + + try { + ISodiumChunkArray refArray = extractReferenceArray(); + if (thisConstructor == null) { + thisConstructor = this.getClass().getConstructor(ClientWorld.class, int.class); + } + ClientChunkProvider result = (ClientChunkProvider) thisConstructor.newInstance(world, radius - 3); // -3 because it adds 3 for no reason here too lmao + IChunkArray copyArr = ((IClientChunkProvider) result).extractReferenceArray(); + copyArr.copyFrom(refArray); + return result; + } catch (InstantiationException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { + throw new RuntimeException("Sodium chunk manager initialization for baritone failed", e); + } finally { + // put this in finally so we can't break anything. + this.lock.unlockWrite(stamp); + } + } + + @Override + public ISodiumChunkArray extractReferenceArray() { + if (chunkArrayField == null) { + boolean flag = true; + for (Field f : this.getClass().getDeclaredFields()) { + if (ISodiumChunkArray.class.isAssignableFrom(f.getType())) { + chunkArrayField = f; + flag = false; + break; + } + } // else + if (flag) { + throw new RuntimeException(Arrays.toString(this.getClass().getDeclaredFields())); + } + } + try { + return (ISodiumChunkArray) chunkArrayField.get(this); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/launch/java/baritone/launch/mixins/MixinSodiumFixedLongHashTable.java b/src/launch/java/baritone/launch/mixins/MixinSodiumFixedLongHashTable.java new file mode 100644 index 000000000..06e13b719 --- /dev/null +++ b/src/launch/java/baritone/launch/mixins/MixinSodiumFixedLongHashTable.java @@ -0,0 +1,80 @@ +/* + * This file is part of Baritone. + * + * Baritone 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, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone 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 Baritone. If not, see . + */ + +package baritone.launch.mixins; + +import baritone.utils.accessor.IChunkArray; +import baritone.utils.accessor.ISodiumChunkArray; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.objects.ObjectIterator; +import net.minecraft.world.chunk.Chunk; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.concurrent.atomic.AtomicReferenceArray; + +@Pseudo +@Mixin(targets = "me.jellysquid.mods.sodium.client.util.collections.FixedLongHashTable", remap = false) +public abstract class MixinSodiumFixedLongHashTable implements ISodiumChunkArray { + + @Shadow + public abstract ObjectIterator> iterator(); + + @Shadow + public abstract Object put(final long k, final Object v); + + /** + * similar to https://github.com/jellysquid3/sodium-fabric/blob/d3528521d48a130322c910c6f0725cf365ebae6f/src/main/java/me/jellysquid/mods/sodium/client/world/SodiumChunkManager.java#L149 + * except that since we aren't changing the radius, the key value doesn't change. + */ + @Override + public void copyFrom(IChunkArray other) { + ObjectIterator> it = ((ISodiumChunkArray) other).callIterator(); + while (it.hasNext()) { + Long2ObjectMap.Entry entry = it.next(); + this.put(entry.getLongKey(), entry.getValue()); + } + } + + @Override + public ObjectIterator> callIterator() { + return iterator(); + } + + //these are useless here... + @Override + public AtomicReferenceArray getChunks() { + return null; + } + + @Override + public int centerX() { + return 0; + } + + @Override + public int centerZ() { + return 0; + } + + @Override + public int viewDistance() { + return 0; + } + +} diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json index de4f25e84..6ef809b0b 100644 --- a/src/launch/resources/mixins.baritone.json +++ b/src/launch/resources/mixins.baritone.json @@ -22,6 +22,8 @@ "MixinNetworkManager", "MixinPlayerController", "MixinScreen", + "MixinSodiumChunkProvider", + "MixinSodiumFixedLongHashTable", "MixinWorldRenderer" ] } \ No newline at end of file diff --git a/src/main/java/baritone/utils/accessor/ISodiumChunkArray.java b/src/main/java/baritone/utils/accessor/ISodiumChunkArray.java new file mode 100644 index 000000000..7fcb25722 --- /dev/null +++ b/src/main/java/baritone/utils/accessor/ISodiumChunkArray.java @@ -0,0 +1,26 @@ +/* + * This file is part of Baritone. + * + * Baritone 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, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone 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 Baritone. If not, see . + */ + +package baritone.utils.accessor; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.objects.ObjectIterator; + +public interface ISodiumChunkArray extends IChunkArray { + + ObjectIterator> callIterator(); +}