Skip to content

Commit

Permalink
- 修复 MixinWorld 与某些神秘模组的兼容性。
Browse files Browse the repository at this point in the history
- 修复 MixinChunk 在配置项 ·StellarCoreConfig.PERFORMANCE.vanilla.blockPos2ValueMap· 关闭时会导致游戏崩溃的问题。
  • Loading branch information
KasumiNova committed Mar 26, 2024
1 parent bac1a2f commit 27e5b2c
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 287 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ public static class Vanilla {
public boolean capturedBlockSnapshots = false;

@Config.Name("CapturedBlockSnapshotsImprovementsOreExcavationIntegration")
public boolean capturedBlockSnapshotsMiningAgentIntegration = true;
public boolean capturedBlockSnapshotsMiningAgentIntegration = false;

@Config.Name("ChunkTileEntityMapImprovements")
public boolean blockPos2ValueMap = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
package github.kasuminova.stellarcore.common.util;

import javax.annotation.Nonnull;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;

/**
* 这是一个假的 ArrayList,内部使用 LinkedList 封装。
*/
@SuppressWarnings({"StandardVariableNames", "unused", "CloneableClassInSecureContext", "NonFinalClone", "MethodDoesntCallSuperMethod"})
public class LinkedFakeArrayList<E> extends ArrayList<E> {

protected final LinkedList<E> internal;

public LinkedFakeArrayList(final int initialCapacity) {
super(0);
this.internal = new LinkedList<>();
}

public LinkedFakeArrayList() {
this.internal = new LinkedList<>();
}

public LinkedFakeArrayList(final Collection<? extends E> c) {
super(c);
this.internal = new LinkedList<>();
}

@Override
public int size() {
return internal.size();
}

@Override
public boolean isEmpty() {
return internal.isEmpty();
}

@Override
public boolean contains(final Object o) {
return internal.contains(o);
}

@Override
public int indexOf(final Object o) {
return internal.indexOf(o);
}

@Override
public int lastIndexOf(final Object o) {
return internal.lastIndexOf(o);
}

@Override
public Object clone() {
return new LinkedFakeArrayList<>(internal);
}

@Nonnull
@Override
public Object[] toArray() {
return internal.toArray();
}

@Nonnull
@Override
public <T> T[] toArray(final T[] a) {
return internal.toArray(a);
}

@Override
public E get(final int index) {
return internal.get(index);
}

@Override
public E set(final int index, final E element) {
return internal.set(index, element);
}

@Override
public boolean add(final E e) {
return internal.add(e);
}

@Override
public void add(final int index, final E element) {
internal.add(index, element);
}

@Override
public E remove(final int index) {
return internal.remove(index);
}

@Override
public boolean remove(final Object o) {
return internal.remove(o);
}

@Override
public void clear() {
internal.clear();
}

@Override
public boolean addAll(final Collection<? extends E> c) {
return internal.addAll(c);
}

@Override
public boolean addAll(final int index, final Collection<? extends E> c) {
return internal.addAll(index, c);
}

@Override
protected void removeRange(final int fromIndex, final int toIndex) {
ListIterator<E> it = internal.listIterator(fromIndex);
for (int i=0, n=toIndex-fromIndex; i<n; i++) {
it.next();
it.remove();
}
}

@Override
public boolean removeAll(final Collection<?> c) {
return internal.removeAll(c);
}

@Override
public boolean retainAll(final Collection<?> c) {
return internal.retainAll(c);
}

@Nonnull
@Override
public ListIterator<E> listIterator(final int index) {
return internal.listIterator(index);
}

@Nonnull
@Override
public ListIterator<E> listIterator() {
return internal.listIterator();
}

@Nonnull
@Override
public Iterator<E> iterator() {
return internal.iterator();
}

@Nonnull
@Override
public List<E> subList(final int fromIndex, final int toIndex) {
return internal.subList(fromIndex, toIndex);
}

@Override
public void forEach(final Consumer<? super E> action) {
internal.forEach(action);
}

@Override
public Spliterator<E> spliterator() {
return internal.spliterator();
}

@Override
public boolean removeIf(final Predicate<? super E> filter) {
return internal.removeIf(filter);
}

@Override
public void replaceAll(final UnaryOperator<E> operator) {
internal.replaceAll(operator);
}

@Override
public void sort(final Comparator<? super E> c) {
internal.sort(c);
}

@Override
public boolean containsAll(@Nonnull final Collection<?> c) {
return internal.containsAll(c);
}

@Override
public <T> T[] toArray(final IntFunction<T[]> generator) {
return internal.toArray(generator);
}

@Override
public Stream<E> stream() {
return internal.stream();
}

@Override
public Stream<E> parallelStream() {
return internal.parallelStream();
}

@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}

if (!(o instanceof List)) {
return false;
}

return this.internal.equals(o);
}

@Override
public int hashCode() {
return internal.hashCode();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,9 @@ public class StellarCoreLateMixinLoader implements ILateMixinLoader {
addModdedMixinCFG("mixins.stellar_core_mekanism.json", "mekanism");
addModdedMixinCFG("mixins.stellar_core_mets.json", "mets");
addModdedMixinCFG("mixins.stellar_core_nco.json", "nuclearcraft");
addModdedMixinCFG("mixins.stellar_core_oreexcavation.json", "oreexcavation");
addModdedMixinCFG("mixins.stellar_core_rgb_chat.json", "jianghun");
addModdedMixinCFG("mixins.stellar_core_scalingguis.json", "scalingguis");
addModdedMixinCFG("mixins.stellar_core_sync.json", "sync");
addModdedMixinCFG("mixins.stellar_core_sync.json", "sync");
addModdedMixinCFG("mixins.stellar_core_sync_techguns.json", "sync", "techguns");
addModdedMixinCFG("mixins.stellar_core_techguns.json", "techguns");
addModdedMixinCFG("mixins.stellar_core_theoneprobe.json", "theoneprobe");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,25 @@
import github.kasuminova.stellarcore.common.util.BlockPos2ValueMap;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.Map;

@Mixin(value = Chunk.class, priority = 1001)
@Mixin(Chunk.class)
public class MixinChunk {

@Shadow @Final @Mutable private Map<BlockPos, TileEntity> tileEntities;

@Redirect(method = "<init>(Lnet/minecraft/world/World;II)V", at = @At(value = "FIELD", target = "Lnet/minecraft/world/chunk/Chunk;tileEntities:Ljava/util/Map;"))
private void redirectNewHashMap(final Chunk instance, final Map<BlockPos, TileEntity> value) {
@Inject(method = "<init>(Lnet/minecraft/world/World;II)V", at = @At("RETURN"))
private void injectInit(final World worldIn, final int x, final int z, final CallbackInfo ci) {
if (!StellarCoreConfig.PERFORMANCE.vanilla.blockPos2ValueMap) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,29 @@
package github.kasuminova.stellarcore.mixin.minecraft;

import github.kasuminova.stellarcore.common.config.StellarCoreConfig;
import github.kasuminova.stellarcore.mixin.util.BlockSnapShotProvider;
import github.kasuminova.stellarcore.common.util.LinkedFakeArrayList;
import net.minecraft.world.World;
import net.minecraftforge.common.util.BlockSnapshot;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.ArrayList;
import java.util.LinkedList;

@Mixin(World.class)
public class MixinWorld implements BlockSnapShotProvider {
public class MixinWorld {

@Unique public LinkedList<BlockSnapshot> stellarcore$capturedBlockSnapshots = new LinkedList<>();
@Shadow
public ArrayList<BlockSnapshot> capturedBlockSnapshots;

@SuppressWarnings({"rawtypes", "unchecked"})
@Redirect(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/state/IBlockState;I)Z",
at = @At(value = "INVOKE", target = "Ljava/util/ArrayList;add(Ljava/lang/Object;)Z")
)
public boolean onSetBlockStateAddSnapshot(final ArrayList instance, final Object e) {
@Inject(method = "<init>", at = @At("RETURN"))
private void injectInit(final CallbackInfo ci) {
if (!StellarCoreConfig.PERFORMANCE.vanilla.capturedBlockSnapshots) {
return instance.add(e);
return;
}
return stellarcore$capturedBlockSnapshots.add((BlockSnapshot) e);
}

@SuppressWarnings("rawtypes")
@Redirect(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/state/IBlockState;I)Z",
at = @At(value = "INVOKE", target = "Ljava/util/ArrayList;remove(Ljava/lang/Object;)Z")
)
public boolean onSetBlockStateRemoveSnapshot(final ArrayList instance, final Object e) {
if (!StellarCoreConfig.PERFORMANCE.vanilla.capturedBlockSnapshots) {
return instance.remove(e);
}
return stellarcore$capturedBlockSnapshots.remove((BlockSnapshot) e);
}

@Override
@SuppressWarnings("AddedMixinMembersNamePattern")
public LinkedList<BlockSnapshot> getCapturedBlockSnapshots() {
return stellarcore$capturedBlockSnapshots;
this.capturedBlockSnapshots = new LinkedFakeArrayList<>();
}

}
Loading

0 comments on commit 27e5b2c

Please sign in to comment.