diff --git a/dependencies.gradle b/dependencies.gradle index 9b4657a..52550af 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -5,11 +5,15 @@ dependencies { implementation(neoforge.ae2) compileOnly(neoforge.ae2wtlib) + // AE addons for compatibility // + compileOnly(neoforge.advancedae) + // Standard runtime mods // localRuntime(neoforge.jade) localRuntime(neoforge.spark) localRuntime(neoforge.modernfix) + // Runtime Recipe Viewers // localRuntime(neoforge.emi) @@ -17,4 +21,8 @@ dependencies { clientLocalRuntime(neoforge.embeddium) //modClientLocalRuntime(forge.oculus) + // runtime test mods // + //localRuntime(neoforge.advancedae) + //localRuntime(neoforge.geckolib) + } diff --git a/gradle/forge.versions.toml b/gradle/forge.versions.toml index 2abc73c..85dafb5 100644 --- a/gradle/forge.versions.toml +++ b/gradle/forge.versions.toml @@ -2,7 +2,7 @@ mixinExtras = "0.5.0-rc.3" emi = "1.1.21+1.21.1" -ae2 = "19.2.4" +ae2 = "19.2.16" theoneprobe = "1.20.1-10.0.1-3" ## modrinth maven ## @@ -14,6 +14,8 @@ modernfix = "4SPHwiDB" # 5.24.3+mc1.21.1 ## cursemaven ## ae2wtlib = "6939030" spark = "6225208" +advancedae = "7222372" +geckolib = "6659026" @@ -30,5 +32,7 @@ modernfix = { module = "maven.modrinth:modernfix", version.ref = "mode ae2wtlib = { module = "curse.maven:ae2wtlib-459929", version.ref = "ae2wtlib" } spark = { module = "curse.maven:spark-361579", version.ref = "spark" } +advancedae = { module = "curse.maven:advancedae-1084104", version.ref = "advancedae" } +geckolib = { module = "curse.maven:geckolib-388172", version.ref = "geckolib" } [bundles] diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3a24bbb..6c0a554 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] minecraft = "1.21.1" -neo = "21.1.169" +neo = "21.1.203" parchment = "2024.11.17" jetbrains-annotations = "26.0.1" diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/implementations/AE.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/implementations/AE.java index 79539a8..dc6ae05 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/implementations/AE.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/implementations/AE.java @@ -1,6 +1,7 @@ package pl.kuba6000.ae2webintegration.ae2interface.implementations; import java.util.Iterator; +import java.util.WeakHashMap; import net.neoforged.neoforge.server.ServerLifecycleHooks; @@ -11,10 +12,13 @@ import pl.kuba6000.ae2webintegration.core.interfaces.IAE; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.IAEPlayerData; +import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; public class AE implements IAE { + public static WeakHashMap cpuInternalIDMap = new WeakHashMap<>(); + public static AE instance = new AE(); public static AE getInstance() { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingCPULogicMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingCPULogicMixin.java index a443794..55539f4 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingCPULogicMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingCPULogicMixin.java @@ -43,11 +43,6 @@ public class CraftingCPULogicMixin implements ICraftingCPULogicAccessor { @Shadow CraftingCPUCluster cluster; - // @Shadow - // private void postCraftingStatusChange(final IAEItemStack diff) { - // throw new IllegalStateException("Mixin failed to apply"); - // } - @Shadow private ExecutingCraftingJob job; @@ -82,23 +77,6 @@ public class CraftingCPULogicMixin implements ICraftingCPULogicAccessor { .jobCancelled((IAEGrid) cluster.getGrid(), (ICraftingCPUCluster) (Object) cluster); } - // @Inject(method = "cancel", at = @At("HEAD")) - // void ae2webintegration$cancel(CallbackInfo ci) { - // IAEMixinCallbacks.getInstance() - // .jobCancelled((IAEGrid) cluster.getGrid(), (ICraftingCPUCluster) this); - // } - - // @Inject( - // method = "injectItems", - // at = @At( - // value = "INVOKE", - // target = "Lappeng/api/storage/data/IAEItemStack;setStackSize(J)Lappeng/api/storage/data/IAEStack;", - // shift = At.Shift.AFTER, - // ordinal = 2)) - // void ae2webintegration$fixCpuCluster(CallbackInfoReturnable cir, @Local(ordinal = 1) IAEItemStack is) { - // postCraftingStatusChange(is); - // } - @Redirect( method = "executeCrafting", at = @At( diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingCPUClusterMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingCPUClusterMixin.java index a1f6151..46ca614 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingCPUClusterMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingCPUClusterMixin.java @@ -1,110 +1,111 @@ package pl.kuba6000.ae2webintegration.ae2interface.mixins.AE2.implementations; +import net.pedroksl.advanced_ae.common.cluster.AdvCraftingCPU; + import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; +import appeng.api.networking.crafting.ICraftingCPU; import appeng.api.stacks.AEKey; import appeng.api.stacks.KeyCounter; import appeng.me.cluster.implementations.CraftingCPUCluster; import pl.kuba6000.ae2webintegration.ae2interface.accessors.ICraftingCPULogicAccessor; +import pl.kuba6000.ae2webintegration.ae2interface.implementations.AE; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGenericStack; import pl.kuba6000.ae2webintegration.core.interfaces.IAEKey; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -@Mixin(value = CraftingCPUCluster.class, remap = false) -public abstract class AECraftingCPUClusterMixin implements ICraftingCPUCluster { - - @Unique - private int web$internalID = -1; +@Mixin(value = ICraftingCPU.class, remap = false) +public interface AECraftingCPUClusterMixin extends ICraftingCPUCluster { @Override - public void web$setInternalID(int id) { - web$internalID = id; + default public void web$setInternalID(int id) { + AE.cpuInternalIDMap.put(this, id); } @Override - public boolean web$hasCustomName() { - return !(((CraftingCPUCluster) (Object) this).getName() == null); + default public boolean web$hasCustomName() { + return !(((ICraftingCPU) this).getName() == null); } @Override - public String web$getName() { - return web$hasCustomName() ? ((CraftingCPUCluster) (Object) this).getName() - .getString() : ("CPU #" + web$internalID); + default public String web$getName() { + return web$hasCustomName() ? ((ICraftingCPU) this).getName() + .getString() : ("CPU #" + AE.cpuInternalIDMap.getOrDefault(this, -1)); } @Override - public long web$getAvailableStorage() { - return ((CraftingCPUCluster) (Object) this).getAvailableStorage(); + default public long web$getAvailableStorage() { + return ((ICraftingCPU) this).getAvailableStorage(); } - @Unique - private boolean web$isUsedStorageAvailable = true; - - @Unique - private boolean web$usedStorageInitialized = false; - @Override - public long web$getUsedStorage() { + default public long web$getUsedStorage() { return -1L; - // if (!web$usedStorageInitialized) { - // web$usedStorageInitialized = true; - // try { - // appeng.me.cluster.implementations.CraftingCPUCluster.class.getDeclaredMethod("getUsedStorage"); - // } catch (NoSuchMethodException e) { - // web$isUsedStorageAvailable = false; - // return -1L; - // } - // } - // if (!web$isUsedStorageAvailable) return -1L; - // return ((CraftingCPUCluster) (Object) this).getUsedStorage(); } @Override - public long web$getCoProcessors() { - return ((CraftingCPUCluster) (Object) this).getCoProcessors(); + default public long web$getCoProcessors() { + return ((ICraftingCPU) this).getCoProcessors(); } @Override - public boolean web$isBusy() { - return ((CraftingCPUCluster) (Object) this).isBusy(); + default public boolean web$isBusy() { + return ((ICraftingCPU) this).isBusy(); } @Override - public void web$cancel() { - ((CraftingCPUCluster) (Object) this).cancelJob(); + default public void web$cancel() { + ((ICraftingCPU) this).cancelJob(); } @Override - public IAEGenericStack web$getFinalOutput() { - return (IAEGenericStack) (Object) ((CraftingCPUCluster) (Object) this).craftingLogic.getFinalJobOutput(); + default public IAEGenericStack web$getFinalOutput() { + if (web$isBusy()) return (IAEGenericStack) (Object) ((ICraftingCPU) this).getJobStatus() + .crafting(); + return null; } @Override - public void web$getAllItems(IItemList list) { - ((CraftingCPUCluster) (Object) this).craftingLogic.getAllItems((KeyCounter) (Object) list); + default public void web$getAllItems(IItemList list) { + if ((Object) this instanceof CraftingCPUCluster cpuCluster) + cpuCluster.craftingLogic.getAllItems((KeyCounter) (Object) list); + else if ((Object) this instanceof AdvCraftingCPU advCpu) + advCpu.craftingLogic.getAllItems((KeyCounter) (Object) list); } @Override - public long web$getActiveItems(IAEKey key) { - return ((CraftingCPUCluster) (Object) this).craftingLogic.getWaitingFor((AEKey) key); + default public long web$getActiveItems(IAEKey key) { + if ((Object) this instanceof CraftingCPUCluster cpuCluster) + return cpuCluster.craftingLogic.getWaitingFor((AEKey) key); + else if ((Object) this instanceof AdvCraftingCPU advCpu) return advCpu.craftingLogic.getWaitingFor((AEKey) key); + return 0L; } @Override - public long web$getPendingItems(IAEKey key) { - return ((CraftingCPUCluster) (Object) this).craftingLogic.getPendingOutputs((AEKey) key); + default public long web$getPendingItems(IAEKey key) { + if ((Object) this instanceof CraftingCPUCluster cpuCluster) + return cpuCluster.craftingLogic.getPendingOutputs((AEKey) key); + else if ((Object) this instanceof AdvCraftingCPU advCpu) return advCpu.craftingLogic.getWaitingFor((AEKey) key); + return 0L; } @Override - public long web$getStorageItems(IAEKey key) { - return ((CraftingCPUCluster) (Object) this).craftingLogic.getStored((AEKey) key); + default public long web$getStorageItems(IAEKey key) { + if ((Object) this instanceof CraftingCPUCluster cpuCluster) + return cpuCluster.craftingLogic.getStored((AEKey) key); + else if ((Object) this instanceof AdvCraftingCPU advCpu) return advCpu.craftingLogic.getWaitingFor((AEKey) key); + return 0L; } @Override - public IItemList web$getWaitingFor() { - return (IItemList) (Object) ((ICraftingCPULogicAccessor) ((CraftingCPUCluster) (Object) this).craftingLogic) - .web$getJob() - .web$getWaitingFor().list; + default public IItemList web$getWaitingFor() { + if ((Object) this instanceof CraftingCPUCluster cpuCluster) + return (IItemList) (Object) ((ICraftingCPULogicAccessor) cpuCluster.craftingLogic).web$getJob() + .web$getWaitingFor().list; + else if ((Object) this instanceof AdvCraftingCPU advCpu) + return (IItemList) (Object) ((ICraftingCPULogicAccessor) advCpu.craftingLogic).web$getJob() + .web$getWaitingFor().list; + return (IItemList) (Object) new KeyCounter(); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/MixinPlugin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/MixinPlugin.java index a5d7cab..83182f0 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/MixinPlugin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/MixinPlugin.java @@ -5,6 +5,8 @@ import java.util.List; import java.util.Set; +import net.neoforged.fml.loading.FMLLoader; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.spongepowered.asm.lib.tree.ClassNode; @@ -63,6 +65,12 @@ public List getMixins() { LOG.info("MIXING INTO AE2 LETS GOOOOOOOOOOOOOOOOOOOOOOOOO"); + if (FMLLoader.getLoadingModList() + .getModFileById("advanced_ae") != null) { + LOG.info("AdvancedAE detected !, applying mixins for AdvancedAE"); + mixins.addAll(Arrays.asList("advanced_ae.CraftingCPULogicMixin", "advanced_ae.ExecutingCraftingJobMixin")); + } + return mixins; } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/advanced_ae/CraftingCPULogicMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/advanced_ae/CraftingCPULogicMixin.java new file mode 100644 index 0000000..769e4c4 --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/advanced_ae/CraftingCPULogicMixin.java @@ -0,0 +1,109 @@ +package pl.kuba6000.ae2webintegration.ae2interface.mixins.advanced_ae; + +import java.util.Map; + +import net.pedroksl.advanced_ae.common.cluster.AdvCraftingCPU; +import net.pedroksl.advanced_ae.common.logic.AdvCraftingCPULogic; +import net.pedroksl.advanced_ae.common.logic.ExecutingCraftingJob; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import appeng.api.crafting.IPatternDetails; +import appeng.api.networking.IGrid; +import appeng.api.networking.IGridNode; +import appeng.api.networking.crafting.ICraftingPlan; +import appeng.api.networking.crafting.ICraftingProvider; +import appeng.api.networking.crafting.ICraftingRequester; +import appeng.api.networking.crafting.ICraftingService; +import appeng.api.networking.crafting.ICraftingSubmitResult; +import appeng.api.networking.security.IActionSource; +import appeng.api.stacks.AEKey; +import appeng.api.stacks.KeyCounter; +import pl.kuba6000.ae2webintegration.ae2interface.accessors.ICraftingCPULogicAccessor; +import pl.kuba6000.ae2webintegration.ae2interface.accessors.IExecutingCraftingJobAccessor; +import pl.kuba6000.ae2webintegration.core.api.IAEMixinCallbacks; +import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingPatternDetails; +import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; +import pl.kuba6000.ae2webintegration.core.interfaces.IAEKey; +import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; +import pl.kuba6000.ae2webintegration.core.interfaces.IPatternProviderViewable; +import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; + +@Mixin(value = AdvCraftingCPULogic.class, remap = false) +public abstract class CraftingCPULogicMixin implements ICraftingCPULogicAccessor { + + @Final + @Shadow + AdvCraftingCPU cpu; + + @Shadow + private ExecutingCraftingJob job; + + @Inject(method = "trySubmitJob", at = @At("RETURN")) + void ae2webintegration$onJobSubmit(IGrid grid, ICraftingPlan plan, IActionSource src, + @Nullable ICraftingRequester requester, CallbackInfoReturnable ci) { + if (ci.getReturnValue() + .successful()) { + boolean isMachine = !src.player() + .isPresent(); + IAEMixinCallbacks.getInstance() + .jobStarted( + (ICraftingCPUCluster) (Object) cpu, + (IAECraftingGrid) grid.getCraftingService(), + (IAEGrid) grid, + false, + !isMachine); + } + } + + @Inject(method = "postChange", at = @At("HEAD")) + void ae2webintegration$postCraftingStatusChange(AEKey diff, CallbackInfo ci) { + IAEMixinCallbacks.getInstance() + .craftingStatusPostedUpdate((ICraftingCPUCluster) (Object) cpu, (IAEKey) diff); + } + + @Inject(method = "finishJob", at = @At("HEAD")) + void ae2webintegration$finishJob(boolean success, CallbackInfo ci) { + if (success) IAEMixinCallbacks.getInstance() + .jobCompleted((IAEGrid) cpu.getGrid(), (ICraftingCPUCluster) (Object) cpu); + else IAEMixinCallbacks.getInstance() + .jobCancelled((IAEGrid) cpu.getGrid(), (ICraftingCPUCluster) (Object) cpu); + } + + @Redirect( + method = "executeCrafting", + at = @At( + value = "INVOKE", + target = "Lappeng/api/networking/crafting/ICraftingProvider;pushPattern(Lappeng/api/crafting/IPatternDetails;[Lappeng/api/stacks/KeyCounter;)Z")) + private boolean ae2webintegration$pushPattern(ICraftingProvider medium, IPatternDetails details, KeyCounter[] ic) { + if (medium.pushPattern(details, ic)) { + IGridNode viewable = null; + Map mediumToViewable = ((IAECraftingGrid) cpu.getGrid() + .getService(ICraftingService.class)).web$getCraftingProviders() + .web$getCraftingMediums(); + if (mediumToViewable != null) { + viewable = mediumToViewable.get(medium); + } + IAEMixinCallbacks.getInstance() + .pushedPattern( + (ICraftingCPUCluster) (Object) cpu, + (IPatternProviderViewable) viewable, + (IAECraftingPatternDetails) details); + return true; + } + return false; + } + + @Override + public IExecutingCraftingJobAccessor web$getJob() { + return (IExecutingCraftingJobAccessor) job; + } +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/advanced_ae/ExecutingCraftingJobMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/advanced_ae/ExecutingCraftingJobMixin.java new file mode 100644 index 0000000..283696f --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/advanced_ae/ExecutingCraftingJobMixin.java @@ -0,0 +1,24 @@ +package pl.kuba6000.ae2webintegration.ae2interface.mixins.advanced_ae; + +import net.pedroksl.advanced_ae.common.logic.ExecutingCraftingJob; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import appeng.crafting.inv.ListCraftingInventory; +import pl.kuba6000.ae2webintegration.ae2interface.accessors.IExecutingCraftingJobAccessor; + +@Mixin(value = ExecutingCraftingJob.class, remap = false) +public class ExecutingCraftingJobMixin implements IExecutingCraftingJobAccessor { + + @Shadow + @Final + ListCraftingInventory waitingFor; + + @Override + public ListCraftingInventory web$getWaitingFor() { + return waitingFor; + } + +}