From 53bf5c141db52eab4fcd94e88e337c671178ab60 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sat, 8 Nov 2025 19:15:58 +0100 Subject: [PATCH 01/29] native fluid --- dependencies.gradle | 8 ++-- .../ae2interface/implementations/AE.java | 2 +- .../mixins/AE2/CraftingCPUClusterMixin.java | 13 +++--- .../AECraftingCPUClusterMixin.java | 22 +++++----- .../implementations/AECraftingJobMixin.java | 4 +- .../AECraftingPatternDetailsMixin.java | 6 +-- .../AE2/implementations/AEItemListMixin.java | 6 +-- .../AEMeInventoryItemMixin.java | 10 ++--- ...EItemStackMixin.java => AEStackMixin.java} | 24 ++++++----- .../service/AECraftingGridMixin.java | 4 +- .../ae2interface/mixins/MixinPlugin.java | 2 +- .../ae2webintegration/core/AE2Controller.java | 4 +- .../ae2webintegration/core/AE2JobTracker.java | 40 +++++++++---------- .../core/AEMixinCallbacks.java | 4 +- .../ae2request/async/GetTrackingHistory.java | 4 +- .../core/ae2request/sync/GetCPU.java | 12 +++--- .../core/ae2request/sync/GetCPUList.java | 4 +- .../core/ae2request/sync/GetItems.java | 4 +- .../core/ae2request/sync/Job.java | 10 ++--- .../core/ae2request/sync/Order.java | 6 +-- .../core/api/IAEMixinCallbacks.java | 4 +- .../core/api/JSON_CompactedItem.java | 8 ++-- .../api/JSON_CompactedJobTrackingInfo.java | 8 ++-- .../interfaces/IAECraftingPatternDetails.java | 2 +- .../core/interfaces/IAEMeInventoryItem.java | 4 +- .../core/interfaces/ICraftingCPUCluster.java | 2 +- .../core/interfaces/IItemList.java | 4 +- .../{IItemStack.java => IStack.java} | 6 +-- .../interfaces/service/IAECraftingGrid.java | 4 +- .../core/utils/GSONUtils.java | 6 +-- 30 files changed, 122 insertions(+), 115 deletions(-) rename src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/{AEItemStackMixin.java => AEStackMixin.java} (61%) rename src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/{IItemStack.java => IStack.java} (76%) diff --git a/dependencies.gradle b/dependencies.gradle index 1f9140d..fab4887 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -34,8 +34,8 @@ * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph */ dependencies { - api("com.github.GTNewHorizons:GTNHLib:0.6.39:dev") - api("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-684-GTNH:dev") - api("com.github.GTNewHorizons:AE2FluidCraft-Rework:1.4.114-gtnh:dev") - runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.7.82-GTNH:dev") + api("com.github.GTNewHorizons:GTNHLib:0.8.2:dev") + api("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-739-GTNH:dev") + api("com.github.GTNewHorizons:AE2FluidCraft-Rework:1.5.19-gtnh:dev") + runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.8.35-GTNH:dev") } 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 566bb4f..46eef47 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/implementations/AE.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/implementations/AE.java @@ -50,7 +50,7 @@ public IAEGrid next() { public IItemList web$createItemList() { return (IItemList) (Object) AEApi.instance() .storage() - .createItemList(); + .createAEStackList(); } @Override diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingCPUClusterMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingCPUClusterMixin.java index 1ee515f..7077286 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingCPUClusterMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingCPUClusterMixin.java @@ -17,7 +17,6 @@ import appeng.api.networking.IGrid; import appeng.api.networking.crafting.ICraftingMedium; import appeng.api.networking.crafting.ICraftingPatternDetails; -import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEStack; import appeng.api.util.IInterfaceViewable; import appeng.me.cluster.implementations.CraftingCPUCluster; @@ -26,8 +25,8 @@ import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingPatternDetails; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; import pl.kuba6000.ae2webintegration.core.interfaces.IPatternProviderViewable; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; @Mixin(value = CraftingCPUCluster.class, remap = false) public class CraftingCPUClusterMixin { @@ -38,14 +37,14 @@ private IGrid getGrid() { } @Shadow - private void postCraftingStatusChange(final IAEItemStack diff) { + private void postCraftingStatusChange(final IAEStack diff) { throw new IllegalStateException("Mixin failed to apply"); } @Inject(method = "postCraftingStatusChange", at = @At("HEAD")) - void ae2webintegration$postCraftingStatusChange(IAEItemStack diff, CallbackInfo ci) { + void ae2webintegration$postCraftingStatusChange(final IAEStack diff, CallbackInfo ci) { IAEMixinCallbacks.getInstance() - .craftingStatusPostedUpdate((ICraftingCPUCluster) this, (IItemStack) diff); + .craftingStatusPostedUpdate((ICraftingCPUCluster) this, (IStack) diff); } @Inject(method = "completeJob", at = @At("HEAD")) @@ -64,10 +63,10 @@ private void postCraftingStatusChange(final IAEItemStack diff) { method = "injectItems", at = @At( value = "INVOKE", - target = "Lappeng/api/storage/data/IAEItemStack;setStackSize(J)Lappeng/api/storage/data/IAEStack;", + target = "Lappeng/api/storage/data/IAEStack;setStackSize(J)Lappeng/api/storage/data/IAEStack;", shift = At.Shift.AFTER, ordinal = 2)) - void ae2webintegration$fixCpuCluster(CallbackInfoReturnable cir, @Local(ordinal = 1) IAEItemStack is) { + void ae2webintegration$fixCpuCluster(CallbackInfoReturnable> cir, @Local(ordinal = 1) IAEStack is) { postCraftingStatusChange(is); } 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 ed56b16..66efbb1 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 @@ -6,10 +6,11 @@ import appeng.api.networking.crafting.CraftingItemList; import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; import appeng.me.cluster.implementations.CraftingCPUCluster; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; @Mixin(value = CraftingCPUCluster.class, remap = false) public abstract class AECraftingCPUClusterMixin implements ICraftingCPUCluster { @@ -78,26 +79,29 @@ public abstract class AECraftingCPUClusterMixin implements ICraftingCPUCluster { } @Override - public IItemStack web$getFinalOutput() { - return (IItemStack) ((CraftingCPUCluster) (Object) this).getFinalOutput(); + public IStack web$getFinalOutput() { + return (IStack) ((CraftingCPUCluster) (Object) this).getFinalMultiOutput(); } @Override public void web$getActiveItems(IItemList list) { - ((CraftingCPUCluster) (Object) this) - .getListOfItem((appeng.api.storage.data.IItemList) (Object) list, CraftingItemList.ACTIVE); + ((CraftingCPUCluster) (Object) this).getModernListOfItem( + (appeng.api.storage.data.IItemList>) (Object) list, + CraftingItemList.ACTIVE); } @Override public void web$getPendingItems(IItemList list) { - ((CraftingCPUCluster) (Object) this) - .getListOfItem((appeng.api.storage.data.IItemList) (Object) list, CraftingItemList.PENDING); + ((CraftingCPUCluster) (Object) this).getModernListOfItem( + (appeng.api.storage.data.IItemList>) (Object) list, + CraftingItemList.PENDING); } @Override public void web$getStorageItems(IItemList list) { - ((CraftingCPUCluster) (Object) this) - .getListOfItem((appeng.api.storage.data.IItemList) (Object) list, CraftingItemList.STORAGE); + ((CraftingCPUCluster) (Object) this).getModernListOfItem( + (appeng.api.storage.data.IItemList>) (Object) list, + CraftingItemList.STORAGE); } @Override diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingJobMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingJobMixin.java index 50ff425..9740d11 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingJobMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingJobMixin.java @@ -3,7 +3,7 @@ import org.spongepowered.asm.mixin.Mixin; import appeng.api.networking.crafting.ICraftingJob; -import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; @@ -22,6 +22,6 @@ public interface AECraftingJobMixin extends IAECraftingJob { @Override public default void web$populatePlan(IItemList plan) { - ((ICraftingJob) (Object) this).populatePlan((appeng.api.storage.data.IItemList) (Object) plan); + ((ICraftingJob) (Object) this).populatePlan((appeng.api.storage.data.IItemList>) (Object) plan); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingPatternDetailsMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingPatternDetailsMixin.java index 2e01388..8c0f6ac 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingPatternDetailsMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingPatternDetailsMixin.java @@ -4,13 +4,13 @@ import appeng.api.networking.crafting.ICraftingPatternDetails; import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingPatternDetails; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; @Mixin(value = ICraftingPatternDetails.class, remap = false) public interface AECraftingPatternDetailsMixin extends IAECraftingPatternDetails { @Override - public default IItemStack[] web$getCondensedOutputs() { - return (IItemStack[]) ((ICraftingPatternDetails) (Object) this).getCondensedOutputs(); + public default IStack[] web$getCondensedOutputs() { + return (IStack[]) ((ICraftingPatternDetails) (Object) this).getCondensedAEOutputs(); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemListMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemListMixin.java index a466685..8ad32dd 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemListMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemListMixin.java @@ -5,15 +5,15 @@ import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IItemContainer; import appeng.api.storage.data.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; @Mixin(value = IItemList.class, remap = false) public interface AEItemListMixin extends IItemContainer, pl.kuba6000.ae2webintegration.core.interfaces.IItemList { @Override - default IItemStack web$findPrecise(IItemStack stack) { - return (IItemStack) findPrecise((StackType) stack); + default IStack web$findPrecise(IStack stack) { + return (IStack) findPrecise((StackType) stack); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java index 8c519d9..85f9cd7 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java @@ -9,21 +9,21 @@ import pl.kuba6000.ae2webintegration.core.api.AEApi.AEActionable; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.IAEMeInventoryItem; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; @Mixin(value = IMEInventory.class) public interface AEMeInventoryItemMixin extends IAEMeInventoryItem { @Override - public default IItemStack web$extractItems(IItemStack stack, AEActionable mode, IAEGrid grid) { - return (IItemStack) ((IMEInventory) (Object) this).extractItems( + public default IStack web$extractItems(IStack stack, AEActionable mode, IAEGrid grid) { + return (IStack) ((IMEInventory) (Object) this).extractItems( (IAEStack) stack, mode == AEActionable.MODULATE ? Actionable.MODULATE : Actionable.SIMULATE, (BaseActionSource) grid.web$getPlayerSource()); } @Override - public default IItemStack web$getAvailableItem(IItemStack stack) { - return (IItemStack) ((IMEInventory) (Object) this).getAvailableItem((IAEStack) stack); + public default IStack web$getAvailableItem(IStack stack) { + return (IStack) ((IMEInventory) (Object) this).getAvailableItem((IAEStack) stack); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemStackMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java similarity index 61% rename from src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemStackMixin.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java index da174cf..e9783ed 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemStackMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java @@ -2,23 +2,27 @@ import org.spongepowered.asm.mixin.Mixin; +import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; import cpw.mods.fml.common.registry.GameRegistry; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -@Mixin(IAEItemStack.class) -public interface AEItemStackMixin extends IAEItemStack, IItemStack { +@Mixin(IAEStack.class) +public interface AEStackMixin extends IAEStack, IStack { @Override public default String web$getItemID() { - return GameRegistry.findUniqueIdentifierFor(getItem()) + if (isItem()) return GameRegistry.findUniqueIdentifierFor(((IAEItemStack) this).getItem()) .toString() + ":" - + getItemDamage(); + + ((IAEItemStack) this).getItemDamage(); + return ((IAEFluidStack) this).getFluid() + .getName(); } @Override public default String web$getDisplayName() { - return getItemStack().getDisplayName(); + return getDisplayName(); } @Override @@ -47,13 +51,13 @@ public interface AEItemStackMixin extends IAEItemStack, IItemStack { } @Override - public default boolean web$isSameType(IItemStack other) { - return isSameType((IAEItemStack) other); + public default boolean web$isSameType(IStack other) { + return isSameType(other); } @Override - public default IItemStack web$copy() { - return (IItemStack) copy(); + public default IStack web$copy() { + return (IStack) copy(); } @Override diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java index 3bb7a6b..8b8e785 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java @@ -21,7 +21,7 @@ import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; @Mixin(value = ICraftingGrid.class) @@ -46,7 +46,7 @@ public interface AECraftingGridMixin extends IAECraftingGrid { } @Override - public default Future web$beginCraftingJob(IAEGrid grid, IItemStack stack) { + public default Future web$beginCraftingJob(IAEGrid grid, IStack stack) { PlayerSource actionSrc = (PlayerSource) grid.web$getPlayerSource(); final Future job = ((ICraftingGrid) (Object) this) .beginCraftingJob(actionSrc.player.worldObj, (IGrid) grid, actionSrc, (IAEItemStack) stack, null); 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 6b13753..f2a7ba7 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/MixinPlugin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/MixinPlugin.java @@ -43,7 +43,7 @@ public List getMixins() { Arrays.asList( "AE2.CraftingGridCacheMixin", "AE2.CraftingCPUClusterMixin", - "AE2.implementations.AEItemStackMixin", + "AE2.implementations.AEStackMixin", "AE2.implementations.AEItemListMixin", "AE2.implementations.AECraftingCPUClusterMixin", "AE2.implementations.AECraftingJobMixin", diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java b/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java index 0f64cde..0312a98 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java @@ -49,7 +49,7 @@ import pl.kuba6000.ae2webintegration.core.ae2request.sync.Job; import pl.kuba6000.ae2webintegration.core.ae2request.sync.Order; import pl.kuba6000.ae2webintegration.core.interfaces.IAE; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.utils.HTTPUtils; import pl.kuba6000.ae2webintegration.core.utils.RateLimiter; import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; @@ -166,7 +166,7 @@ protected void afterExecute(Runnable r, Throwable t) { } }; - public static ConcurrentHashMap hashcodeToAEItemStack = new ConcurrentHashMap<>(); + public static ConcurrentHashMap hashcodeToAEItemStack = new ConcurrentHashMap<>(); private static final HashMap> validTokens = new HashMap<>(); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2JobTracker.java b/src/main/java/pl/kuba6000/ae2webintegration/core/AE2JobTracker.java index 07ffcde..892e4b7 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2JobTracker.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/AE2JobTracker.java @@ -15,8 +15,8 @@ import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; import pl.kuba6000.ae2webintegration.core.interfaces.IPatternProviderViewable; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAESecurityGrid; @@ -45,23 +45,23 @@ public boolean equals(Object obj) { public static class JobTrackingInfo { - public IItemStack finalOutput; + public IStack finalOutput; public long timeStarted; public long timeDone; - public HashMap timeSpentOn = new HashMap<>(); - public HashMap startedWaitingFor = new HashMap<>(); - public HashMap craftedTotal = new HashMap<>(); - public HashMap waitingFor = new HashMap<>(); - public HashMap>> itemShare = new HashMap<>(); + public HashMap timeSpentOn = new HashMap<>(); + public HashMap startedWaitingFor = new HashMap<>(); + public HashMap craftedTotal = new HashMap<>(); + public HashMap waitingFor = new HashMap<>(); + public HashMap>> itemShare = new HashMap<>(); public HashMap>> interfaceShare = new HashMap<>(); public HashMap interfaceStarted = new HashMap<>(); public HashMap interfaceLookup = new HashMap<>(); - public HashMap> interfaceWaitingFor = new HashMap<>(); - public HashMap>> interfaceWaitingForLookup = new HashMap<>(); + public HashMap> interfaceWaitingFor = new HashMap<>(); + public HashMap>> interfaceWaitingForLookup = new HashMap<>(); public boolean isDone = false; public boolean wasCancelled = false; - public long getTimeSpentOn(IItemStack stack) { + public long getTimeSpentOn(IStack stack) { Long time = timeSpentOn.get(stack); if (time == null) return 0L; Long additionalTime = startedWaitingFor.get(stack); @@ -71,10 +71,10 @@ public long getTimeSpentOn(IItemStack stack) { return time; } - public double getShareInCraftingTime(IItemStack stack) { + public double getShareInCraftingTime(IStack stack) { long total = 0L; long stackTime = 0L; - for (IItemStack itemStack : timeSpentOn.keySet()) { + for (IStack itemStack : timeSpentOn.keySet()) { long timeSpent = getTimeSpentOn(itemStack); total += timeSpent; if (stack.web$isSameType(itemStack)) { @@ -106,11 +106,11 @@ public static void addJob(ICraftingCPUCluster cpuCluster, IAECraftingGrid cache, .web$copy(); } - public static void updateCraftingStatus(ICraftingCPUCluster cpu, IItemStack diff) { + public static void updateCraftingStatus(ICraftingCPUCluster cpu, IStack diff) { JobTrackingInfo info = trackingInfoMap.get(cpu); if (info == null) return; IItemList waitingFor = cpu.web$getWaitingFor(); - IItemStack found = waitingFor.web$findPrecise(diff); + IStack found = waitingFor.web$findPrecise(diff); if (found != null && found.web$getStackSize() > 0L) { if (!info.startedWaitingFor.containsKey(found)) { info.startedWaitingFor.put(found, System.currentTimeMillis()); @@ -135,10 +135,10 @@ public static void updateCraftingStatus(ICraftingCPUCluster cpu, IItemStack diff info.itemShare.computeIfAbsent(diff, k -> new ArrayList<>()) .add(Pair.of(started, endedReal)); if (info.interfaceWaitingForLookup.containsKey(diff)) { - for (Map.Entry> entry : info.interfaceWaitingForLookup.get(diff) + for (Map.Entry> entry : info.interfaceWaitingForLookup.get(diff) .entrySet()) { AEInterface aeInterface = entry.getKey(); - HashSet itemList = entry.getValue(); + HashSet itemList = entry.getValue(); itemList.remove(diff); if (itemList.isEmpty()) { info.interfaceWaitingFor.remove(aeInterface); @@ -165,10 +165,10 @@ public static void pushedPattern(ICraftingCPUCluster cpu, IPatternProviderViewab .computeIfAbsent(aeInterfaceToLookup, k -> aeInterfaceToLookup); aeInterface.location.add(provider.web$getLocation()); info.interfaceStarted.computeIfAbsent(aeInterface, k -> System.currentTimeMillis()); - final HashSet itemList = info.interfaceWaitingFor + final HashSet itemList = info.interfaceWaitingFor .computeIfAbsent(aeInterface, k -> new HashSet<>()); - for (IItemStack out : details.web$getCondensedOutputs()) { + for (IStack out : details.web$getCondensedOutputs()) { info.interfaceWaitingForLookup.computeIfAbsent(out, k -> new HashMap<>()) .putIfAbsent(aeInterface, itemList); itemList.add(out); @@ -181,12 +181,12 @@ public static void completeCrafting(IAEGrid grid, ICraftingCPUCluster cpu) { if (info == null) return; GridData gridData = GridData.get(grid); if (gridData == null || !gridData.isTracked) return; // We don't track this grid, so we don't track jobs on it - for (Map.Entry entry : info.waitingFor.entrySet()) { + for (Map.Entry entry : info.waitingFor.entrySet()) { info.craftedTotal.merge(entry.getKey(), entry.getValue(), Long::sum); } info.waitingFor.clear(); final long now = System.currentTimeMillis(); - for (Map.Entry entry : info.startedWaitingFor.entrySet()) { + for (Map.Entry entry : info.startedWaitingFor.entrySet()) { info.timeSpentOn.merge(entry.getKey(), now - entry.getValue(), Long::sum); info.itemShare.computeIfAbsent(entry.getKey(), k -> new ArrayList<>()) .add(Pair.of(entry.getValue(), now)); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/AEMixinCallbacks.java b/src/main/java/pl/kuba6000/ae2webintegration/core/AEMixinCallbacks.java index 4bd9bbb..15001cd 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/AEMixinCallbacks.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/AEMixinCallbacks.java @@ -4,8 +4,8 @@ import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingPatternDetails; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; import pl.kuba6000.ae2webintegration.core.interfaces.IPatternProviderViewable; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; public class AEMixinCallbacks implements IAEMixinCallbacks { @@ -22,7 +22,7 @@ public void jobStarted(ICraftingCPUCluster cpuCluster, IAECraftingGrid cache, IA } @Override - public void craftingStatusPostedUpdate(ICraftingCPUCluster cpu, IItemStack diff) { + public void craftingStatusPostedUpdate(ICraftingCPUCluster cpu, IStack diff) { AE2JobTracker.updateCraftingStatus(cpu, diff); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTrackingHistory.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTrackingHistory.java index c9f15a6..0743cc7 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTrackingHistory.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTrackingHistory.java @@ -4,7 +4,7 @@ import java.util.Map; import pl.kuba6000.ae2webintegration.core.AE2JobTracker; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; public class GetTrackingHistory extends IAsyncRequest { @@ -13,7 +13,7 @@ private static class JSON_TrackingHistoryElement { public long timeStarted; public long timeDone; public boolean wasCancelled; - public IItemStack finalOutput; + public IStack finalOutput; public int id; } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPU.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPU.java index 2334a94..f9eaf8a 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPU.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPU.java @@ -10,7 +10,7 @@ import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; public class GetCPU extends ISyncedRequest { @@ -19,7 +19,7 @@ private static class JSON_ClusterData { public long size; public boolean isBusy; - public IItemStack finalOutput; + public IStack finalOutput; public ArrayList items; public boolean hasTrackingInfo = false; public long timeStarted = 0L; @@ -64,19 +64,19 @@ void handle(IAEGrid grid) { HashMap prep = new HashMap<>(); IItemList items = AE2Controller.AE2Interface.web$createItemList(); cpu.web$getActiveItems(items); - for (IItemStack itemStack : items) { + for (IStack itemStack : items) { JSON_CompactedItem compactedItem = JSON_CompactedItem.create(itemStack); prep.computeIfAbsent(compactedItem, k -> compactedItem).active += itemStack.web$getStackSize(); } items = AE2Controller.AE2Interface.web$createItemList(); cpu.web$getPendingItems(items); - for (IItemStack itemStack : items) { + for (IStack itemStack : items) { JSON_CompactedItem compactedItem = JSON_CompactedItem.create(itemStack); prep.computeIfAbsent(compactedItem, k -> compactedItem).pending += itemStack.web$getStackSize(); } items = AE2Controller.AE2Interface.web$createItemList(); cpu.web$getStorageItems(items); - for (IItemStack itemStack : items) { + for (IStack itemStack : items) { JSON_CompactedItem compactedItem = JSON_CompactedItem.create(itemStack); prep.computeIfAbsent(compactedItem, k -> compactedItem).stored += itemStack.web$getStackSize(); } @@ -84,7 +84,7 @@ void handle(IAEGrid grid) { if (clusterData.hasTrackingInfo) { clusterData.timeStarted = trackingInfo.timeStarted; clusterData.timeElapsed = (System.currentTimeMillis()) - clusterData.timeStarted; - for (IItemStack stack : trackingInfo.timeSpentOn.keySet()) { + for (IStack stack : trackingInfo.timeSpentOn.keySet()) { JSON_CompactedItem compactedItem = JSON_CompactedItem.create(stack); JSON_CompactedItem finalCompactedItem = compactedItem; compactedItem = prep.computeIfAbsent(compactedItem, k -> finalCompactedItem); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPUList.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPUList.java index 24921fe..e3af3cd 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPUList.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPUList.java @@ -6,7 +6,7 @@ import pl.kuba6000.ae2webintegration.core.AE2JobTracker; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; public class GetCPUList extends ISyncedRequest { @@ -14,7 +14,7 @@ public class GetCPUList extends ISyncedRequest { private static class JSON_CpuInfo { public boolean isBusy; - public IItemStack finalOutput; + public IStack finalOutput; public long availableStorage; public long usedStorage; public long coProcessors; diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java index e0ab832..95c2a5f 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java @@ -7,7 +7,7 @@ import pl.kuba6000.ae2webintegration.core.api.JSON_DetailedItem; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEStorageGrid; public class GetItems extends ISyncedRequest { @@ -27,7 +27,7 @@ void handle(IAEGrid grid) { IItemList storageList = storageGrid.web$getItemStorageList(); AE2Controller.hashcodeToAEItemStack.clear(); ArrayList items = new ArrayList<>(); - for (IItemStack stack : storageList) { + for (IStack stack : storageList) { int hash; AE2Controller.hashcodeToAEItemStack.put(hash = stack.hashCode(), stack); JSON_DetailedItem detailedItem = new JSON_DetailedItem(); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java index 6f4a617..dfe8277 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java @@ -14,7 +14,7 @@ import pl.kuba6000.ae2webintegration.core.interfaces.IAEMeInventoryItem; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEStorageGrid; @@ -87,17 +87,17 @@ void handle(IAEGrid grid) { IItemList plan; craftingJob.web$populatePlan(plan = AE2Controller.AE2Interface.web$createItemList()); jobData.plan = new ArrayList<>(); - for (IItemStack stack : plan) { + for (IStack stack : plan) { JSON_JobData.JobItem jobItem = new JSON_JobData.JobItem(); jobItem.itemid = stack.web$getItemID(); jobItem.itemname = stack.web$getDisplayName(); jobItem.requested = stack.web$getCountRequestable(); jobItem.steps = stack.web$getCountRequestableCrafts(); if (jobData.isSimulating) { - IItemStack toExtract = stack.web$copy(); + IStack toExtract = stack.web$copy(); toExtract.web$reset(); toExtract.web$setStackSize(stack.web$getStackSize()); - IItemStack missing = toExtract.web$copy(); + IStack missing = toExtract.web$copy(); toExtract = items.web$extractItems(toExtract, AEActionable.SIMULATE, grid); if (toExtract == null) { toExtract = missing.web$copy(); @@ -110,7 +110,7 @@ void handle(IAEGrid grid) { jobItem.missing = 0; } if (jobItem.missing == 0 && jobItem.requested == 0 && jobItem.stored > 0) { - IItemStack realStack = items.web$getAvailableItem(stack); + IStack realStack = items.web$getAvailableItem(stack); long available = 0L; if (realStack != null) available = realStack.web$getStackSize(); if (available > 0L) jobItem.usedPercent = (double) jobItem.stored / (double) available; diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Order.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Order.java index 6ec9b1b..fb2da33 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Order.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Order.java @@ -11,13 +11,13 @@ import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEStorageGrid; public class Order extends ISyncedRequest { - private IItemStack item; + private IStack item; @Override boolean init(Map getParams) { @@ -54,7 +54,7 @@ void handle(IAEGrid grid) { if (!allBusy) { IAEStorageGrid storageGrid = grid.web$getStorageGrid(); final IItemList itemList = storageGrid.web$getItemStorageList(); - IItemStack realItem = itemList.web$findPrecise(this.item); + IStack realItem = itemList.web$findPrecise(this.item); if (realItem != null && realItem.web$isCraftable()) { Future job = craftingGrid.web$beginCraftingJob(grid, this.item); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEMixinCallbacks.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEMixinCallbacks.java index ca9087b..f9cc5ce 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEMixinCallbacks.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEMixinCallbacks.java @@ -4,8 +4,8 @@ import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingPatternDetails; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; import pl.kuba6000.ae2webintegration.core.interfaces.IPatternProviderViewable; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; public interface IAEMixinCallbacks { @@ -17,7 +17,7 @@ static IAEMixinCallbacks getInstance() { void jobStarted(ICraftingCPUCluster cpuCluster, IAECraftingGrid cache, IAEGrid grid, boolean isMerging, boolean isAuthorPlayer); - void craftingStatusPostedUpdate(ICraftingCPUCluster cpu, IItemStack diff); + void craftingStatusPostedUpdate(ICraftingCPUCluster cpu, IStack diff); void pushedPattern(ICraftingCPUCluster cpu, IPatternProviderViewable provider, IAECraftingPatternDetails details); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedItem.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedItem.java index d54de29..7eb5ca2 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedItem.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedItem.java @@ -1,12 +1,12 @@ package pl.kuba6000.ae2webintegration.core.api; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.utils.GSONUtils; public class JSON_CompactedItem { @GSONUtils.SkipGSON - private final IItemStack internalItem; + private final IStack internalItem; @GSONUtils.SkipGSON private final int hashcode; @@ -21,14 +21,14 @@ public class JSON_CompactedItem { public double shareInCraftingTimeCombined = 0d; public double craftsPerSec = 0d; - public JSON_CompactedItem(IItemStack itemStack) { + public JSON_CompactedItem(IStack itemStack) { this.internalItem = itemStack; this.hashcode = this.internalItem.hashCode(); this.itemid = itemStack.web$getItemID(); this.itemname = itemStack.web$getDisplayName(); } - public static JSON_CompactedItem create(IItemStack stack) { + public static JSON_CompactedItem create(IStack stack) { return new JSON_CompactedItem(stack); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedJobTrackingInfo.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedJobTrackingInfo.java index f378c84..966d08f 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedJobTrackingInfo.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedJobTrackingInfo.java @@ -7,7 +7,7 @@ import org.apache.commons.lang3.tuple.Pair; import pl.kuba6000.ae2webintegration.core.AE2JobTracker; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; public class JSON_CompactedJobTrackingInfo { @@ -35,7 +35,7 @@ public static class CompactedTrackingGSONItem { public ArrayList timings = new ArrayList<>(); } - public IItemStack finalOutput; + public IStack finalOutput; public long timeStarted; public long timeDone; public boolean wasCancelled; @@ -59,8 +59,8 @@ public JSON_CompactedJobTrackingInfo(AE2JobTracker.JobTrackingInfo info) { this.timeDone = info.timeDone; long elapsed = this.timeDone - this.timeStarted; this.wasCancelled = info.wasCancelled; - for (Map.Entry entry : info.timeSpentOn.entrySet()) { - IItemStack stack = entry.getKey(); + for (Map.Entry entry : info.timeSpentOn.entrySet()) { + IStack stack = entry.getKey(); long spent = entry.getValue(); CompactedTrackingGSONItem item = new CompactedTrackingGSONItem(); item.itemid = stack.web$getItemID(); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingPatternDetails.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingPatternDetails.java index fbf1a04..c0670d6 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingPatternDetails.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingPatternDetails.java @@ -2,6 +2,6 @@ public interface IAECraftingPatternDetails { - IItemStack[] web$getCondensedOutputs(); + IStack[] web$getCondensedOutputs(); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEMeInventoryItem.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEMeInventoryItem.java index 880bc5c..8e07937 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEMeInventoryItem.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEMeInventoryItem.java @@ -4,8 +4,8 @@ public interface IAEMeInventoryItem { - IItemStack web$extractItems(IItemStack stack, AEActionable mode, IAEGrid grid); + IStack web$extractItems(IStack stack, AEActionable mode, IAEGrid grid); - IItemStack web$getAvailableItem(IItemStack stack); + IStack web$getAvailableItem(IStack stack); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/ICraftingCPUCluster.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/ICraftingCPUCluster.java index 4c19183..2b1a4e1 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/ICraftingCPUCluster.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/ICraftingCPUCluster.java @@ -18,7 +18,7 @@ public interface ICraftingCPUCluster { void web$cancel(); - IItemStack web$getFinalOutput(); + IStack web$getFinalOutput(); void web$getActiveItems(IItemList list); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemList.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemList.java index 0238428..f651239 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemList.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemList.java @@ -1,7 +1,7 @@ package pl.kuba6000.ae2webintegration.core.interfaces; -public interface IItemList extends Iterable { +public interface IItemList extends Iterable { - IItemStack web$findPrecise(IItemStack stack); + IStack web$findPrecise(IStack stack); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemStack.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java similarity index 76% rename from src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemStack.java rename to src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java index 7a7a929..7941fc9 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemStack.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java @@ -1,6 +1,6 @@ package pl.kuba6000.ae2webintegration.core.interfaces; -public interface IItemStack { +public interface IStack { String web$getItemID(); @@ -16,9 +16,9 @@ public interface IItemStack { void web$reset(); - boolean web$isSameType(IItemStack other); + boolean web$isSameType(IStack other); - IItemStack web$copy(); + IStack web$copy(); void web$setStackSize(long size); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java index 5ea0fd5..bd0346a 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java @@ -8,7 +8,7 @@ import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; public interface IAECraftingGrid { @@ -16,7 +16,7 @@ public interface IAECraftingGrid { Set web$getCPUs(); - Future web$beginCraftingJob(IAEGrid grid, IItemStack stack); + Future web$beginCraftingJob(IAEGrid grid, IStack stack); IChatComponent web$submitJob(IAECraftingJob job, ICraftingCPUCluster target, boolean prioritizePower, IAEGrid grid); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/utils/GSONUtils.java b/src/main/java/pl/kuba6000/ae2webintegration/core/utils/GSONUtils.java index cbf65ba..3a72079 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/utils/GSONUtils.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/utils/GSONUtils.java @@ -11,7 +11,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonSerializer; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemStack; +import pl.kuba6000.ae2webintegration.core.interfaces.IStack; public class GSONUtils { @@ -32,7 +32,7 @@ public boolean shouldSkipClass(Class clazz) { } }; - private static final JsonSerializer IItemStackSerializer = (src, typeOfSrc, context) -> { + private static final JsonSerializer IItemStackSerializer = (src, typeOfSrc, context) -> { JsonObject json = new JsonObject(); json.addProperty("itemid", src.web$getItemID()); json.addProperty("itemname", src.web$getDisplayName()); @@ -43,7 +43,7 @@ public boolean shouldSkipClass(Class clazz) { public static final GsonBuilder GSON_BUILDER = new GsonBuilder().addSerializationExclusionStrategy(GSONStrategy) .addDeserializationExclusionStrategy(GSONStrategy) - .registerTypeHierarchyAdapter(IItemStack.class, IItemStackSerializer) + .registerTypeHierarchyAdapter(IStack.class, IItemStackSerializer) .serializeNulls(); } From 3aadfe7ececdc2cbabff9c35a878401b17d9a64b Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sat, 8 Nov 2025 22:10:00 +0100 Subject: [PATCH 02/29] Show fluids in the terminal --- .../service/AEStorageGridMixin.java | 6 ++++++ .../core/ae2request/sync/GetItems.java | 18 +++++++++++++----- .../interfaces/service/IAEStorageGrid.java | 2 ++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AEStorageGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AEStorageGridMixin.java index 675e33d..44de640 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AEStorageGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AEStorageGridMixin.java @@ -16,6 +16,12 @@ public interface AEStorageGridMixin extends IAEStorageGrid { .getStorageList(); } + @Override + default IItemList web$getFluidStorageList() { + return (IItemList) (Object) ((IStorageGrid) (Object) this).getFluidInventory() + .getStorageList(); + } + @Override public default IAEMeInventoryItem web$getItemInventory() { return (IAEMeInventoryItem) ((IStorageGrid) (Object) this).getItemInventory(); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java index 95c2a5f..04ee14b 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java @@ -25,21 +25,29 @@ void handle(IAEGrid grid) { } IAEStorageGrid storageGrid = grid.web$getStorageGrid(); IItemList storageList = storageGrid.web$getItemStorageList(); + IItemList fluidStorageList = storageGrid.web$getFluidStorageList(); AE2Controller.hashcodeToAEItemStack.clear(); ArrayList items = new ArrayList<>(); - for (IStack stack : storageList) { - int hash; - AE2Controller.hashcodeToAEItemStack.put(hash = stack.hashCode(), stack); + processItemList(storageList, items); + processItemList(fluidStorageList, items); + setData(items); + done(); + } + + private void processItemList(IItemList itemList, ArrayList items) { + for (IStack stack : itemList) { + int hash = stack.hashCode(); + AE2Controller.hashcodeToAEItemStack.put(hash, stack); + JSON_DetailedItem detailedItem = new JSON_DetailedItem(); detailedItem.itemid = stack.web$getItemID(); detailedItem.itemname = stack.web$getDisplayName(); detailedItem.quantity = stack.web$getStackSize(); detailedItem.craftable = stack.web$isCraftable(); detailedItem.hashcode = hash; + items.add(detailedItem); } - setData(items); - done(); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java index 6a7402f..a798888 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java @@ -7,6 +7,8 @@ public interface IAEStorageGrid { IItemList web$getItemStorageList(); + IItemList web$getFluidStorageList(); + IAEMeInventoryItem web$getItemInventory(); } From c6064d5e499db262511c4c17e01a6659c88dc828 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sat, 25 Apr 2026 10:52:02 +0200 Subject: [PATCH 03/29] Update dependencies.gradle --- dependencies.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index fab4887..3e41790 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -34,8 +34,8 @@ * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph */ dependencies { - api("com.github.GTNewHorizons:GTNHLib:0.8.2:dev") - api("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-739-GTNH:dev") - api("com.github.GTNewHorizons:AE2FluidCraft-Rework:1.5.19-gtnh:dev") - runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.8.35-GTNH:dev") + api("com.github.GTNewHorizons:GTNHLib:0.9.53:dev") + api("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-909-GTNH:dev") + api("com.github.GTNewHorizons:AE2FluidCraft-Rework:1.5.76-gtnh:dev") + runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.8.91-GTNH:dev") } From 63b57b8a9659aa0bbd71b6a5c96bc77a2d803f7c Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sat, 25 Apr 2026 11:31:27 +0200 Subject: [PATCH 04/29] fix crash on order --- .../mixins/AE2/implementations/AEStackMixin.java | 5 +++++ .../AE2/implementations/service/AEStorageGridMixin.java | 5 +++++ .../ae2webintegration/core/ae2request/sync/Job.java | 6 ++++-- .../kuba6000/ae2webintegration/core/interfaces/IStack.java | 2 ++ .../core/interfaces/service/IAEStorageGrid.java | 2 ++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java index e9783ed..9a3c604 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java @@ -64,4 +64,9 @@ public interface AEStackMixin extends IAEStack, IStack { public default void web$setStackSize(long size) { setStackSize(size); } + + @Override + public default boolean web$isItem() { + return isItem(); + } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AEStorageGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AEStorageGridMixin.java index 44de640..f4f90ad 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AEStorageGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AEStorageGridMixin.java @@ -26,4 +26,9 @@ public interface AEStorageGridMixin extends IAEStorageGrid { public default IAEMeInventoryItem web$getItemInventory() { return (IAEMeInventoryItem) ((IStorageGrid) (Object) this).getItemInventory(); } + + @Override + default IAEMeInventoryItem web$getFluidInventory() { + return (IAEMeInventoryItem) ((IStorageGrid) (Object) this).getFluidInventory(); + } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java index dfe8277..89563e7 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java @@ -82,6 +82,7 @@ void handle(IAEGrid grid) { IAECraftingJob craftingJob = job.get(); IAEStorageGrid storageGrid = grid.web$getStorageGrid(); IAEMeInventoryItem items = storageGrid.web$getItemInventory(); + IAEMeInventoryItem fluids = storageGrid.web$getFluidInventory(); jobData.isSimulating = craftingJob.web$isSimulation(); jobData.bytesTotal = craftingJob.web$getByteTotal(); IItemList plan; @@ -93,12 +94,13 @@ void handle(IAEGrid grid) { jobItem.itemname = stack.web$getDisplayName(); jobItem.requested = stack.web$getCountRequestable(); jobItem.steps = stack.web$getCountRequestableCrafts(); + IAEMeInventoryItem inventory = stack.web$isItem() ? items : fluids; if (jobData.isSimulating) { IStack toExtract = stack.web$copy(); toExtract.web$reset(); toExtract.web$setStackSize(stack.web$getStackSize()); IStack missing = toExtract.web$copy(); - toExtract = items.web$extractItems(toExtract, AEActionable.SIMULATE, grid); + toExtract = inventory.web$extractItems(toExtract, AEActionable.SIMULATE, grid); if (toExtract == null) { toExtract = missing.web$copy(); toExtract.web$setStackSize(0); @@ -110,7 +112,7 @@ void handle(IAEGrid grid) { jobItem.missing = 0; } if (jobItem.missing == 0 && jobItem.requested == 0 && jobItem.stored > 0) { - IStack realStack = items.web$getAvailableItem(stack); + IStack realStack = inventory.web$getAvailableItem(stack); long available = 0L; if (realStack != null) available = realStack.web$getStackSize(); if (available > 0L) jobItem.usedPercent = (double) jobItem.stored / (double) available; diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java index 7941fc9..0cec4e0 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java @@ -22,4 +22,6 @@ public interface IStack { void web$setStackSize(long size); + boolean web$isItem(); + } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java index a798888..0dd340a 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java @@ -11,4 +11,6 @@ public interface IAEStorageGrid { IAEMeInventoryItem web$getItemInventory(); + IAEMeInventoryItem web$getFluidInventory(); + } From 1f8f236dc79088fc89d84e541aea7cf39e83cb6f Mon Sep 17 00:00:00 2001 From: Jakub Date: Thu, 7 May 2026 16:20:34 +0200 Subject: [PATCH 05/29] Refactor: Extract Forge and Minecraft dependencies out of core engine --- .../AE2/implementations/AEGridMixin.java | 2 +- .../implementations/AEPlayerDataMixin.java | 8 +- .../service/AECraftingGridMixin.java | 4 +- .../service/AESecurityGridMixin.java | 2 +- .../ae2webintegration/core/AE2Controller.java | 29 ++----- .../ae2webintegration/core/Config.java | 80 +------------------ .../ae2webintegration/core/GridData.java | 2 +- .../ae2webintegration/core/WebData.java | 24 +++--- .../ae2webintegration/core/WebEngine.java | 16 ++++ .../core/ae2request/sync/GetGridList.java | 4 +- .../core/ae2request/sync/Job.java | 5 +- .../core/api/DimensionalCoords.java | 8 +- .../core/api/IServerPlatform.java | 26 ++++++ .../core/api/PlayerProfile.java | 21 +++++ .../core/discord/DiscordManager.java | 2 +- .../core/interfaces/IAEGrid.java | 3 +- .../core/interfaces/IAEPlayerData.java | 6 +- .../interfaces/service/IAECraftingGrid.java | 3 +- .../interfaces/service/IAESecurityGrid.java | 4 +- .../AE2WebIntegrationCore.java} | 14 ++-- .../{core => forge}/ClientProxy.java | 2 +- .../{core => forge}/CommonProxy.java | 17 ++-- .../{core => forge}/FMLEventHandler.java | 6 +- .../ae2webintegration/forge/ForgeConfig.java | 74 +++++++++++++++++ .../forge/ForgePlatform.java | 50 ++++++++++++ .../commands/BaseCommandHandler.java | 7 +- 26 files changed, 255 insertions(+), 164 deletions(-) create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/WebEngine.java create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/IServerPlatform.java create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/PlayerProfile.java rename src/main/java/pl/kuba6000/ae2webintegration/{core/AE2WebIntegration.java => forge/AE2WebIntegrationCore.java} (78%) rename src/main/java/pl/kuba6000/ae2webintegration/{core => forge}/ClientProxy.java (83%) rename src/main/java/pl/kuba6000/ae2webintegration/{core => forge}/CommonProxy.java (80%) rename src/main/java/pl/kuba6000/ae2webintegration/{core => forge}/FMLEventHandler.java (88%) create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/forge/ForgeConfig.java create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/forge/ForgePlatform.java rename src/main/java/pl/kuba6000/ae2webintegration/{core => forge}/commands/BaseCommandHandler.java (93%) diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEGridMixin.java index 7fc5586..c2fa5fd 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEGridMixin.java @@ -114,7 +114,7 @@ public void addChatMessage(IChatComponent message) { } @Override - public IChatComponent web$getLastFakePlayerChatMessage() { + public Object web$getLastFakePlayerChatMessage() { return web$lastFakePlayerChatMessage; } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java index b37a467..d6eeddf 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java @@ -28,7 +28,7 @@ public int getPlayerID(@Nonnull final GameProfile profile) { } @Override - public GameProfile web$getPlayerProfile(int playerId) { + public pl.kuba6000.ae2webintegration.core.api.PlayerProfile web$getPlayerProfile(int playerId) { Optional maybe = playerMapping.get(playerId); if (!maybe.isPresent()) return null; UUID uuid = maybe.get(); @@ -44,11 +44,11 @@ public int getPlayerID(@Nonnull final GameProfile profile) { if (p == null) { p = new GameProfile(uuid, uuid.toString()); } - return p; + return new pl.kuba6000.ae2webintegration.core.api.PlayerProfile(p.getId(), p.getName()); } @Override - public int web$getPlayerId(GameProfile id) { - return getPlayerID(id); + public int web$getPlayerId(java.util.UUID id) { + return getPlayerID(new com.mojang.authlib.GameProfile(id, null)); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java index 8b8e785..37cb415 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java @@ -54,7 +54,7 @@ public interface AECraftingGridMixin extends IAECraftingGrid { } @Override - public default IChatComponent web$submitJob(IAECraftingJob job, ICraftingCPUCluster target, boolean prioritizePower, + public default String web$submitJob(IAECraftingJob job, ICraftingCPUCluster target, boolean prioritizePower, IAEGrid grid) { ICraftingLink link = ((ICraftingGrid) (Object) this).submitJob( (ICraftingJob) job, @@ -63,6 +63,6 @@ public interface AECraftingGridMixin extends IAECraftingGrid { prioritizePower, (BaseActionSource) grid.web$getPlayerSource()); if (link != null) return null; - return grid.web$getLastFakePlayerChatMessage(); + Object msg = grid.web$getLastFakePlayerChatMessage(); return msg == null ? null : ((net.minecraft.util.IChatComponent)msg).getUnformattedText(); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java index ab93ead..db471f8 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java @@ -38,7 +38,7 @@ public class AESecurityGridMixin implements IAESecurityGrid { } @Override - public GameProfile web$getOwnerProfile() { + public pl.kuba6000.ae2webintegration.core.api.PlayerProfile web$getOwnerProfile() { IAEPlayerData playerData = (IAEPlayerData) WorldData.instance() .playerData(); return playerData.web$getPlayerProfile(web$getOwner()); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java b/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java index 0312a98..777044e 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java @@ -24,8 +24,6 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import net.minecraft.entity.player.EntityPlayerMP; - import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.tuple.Pair; @@ -35,7 +33,6 @@ import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import cpw.mods.fml.common.FMLCommonHandler; import pl.kuba6000.ae2webintegration.core.ae2request.async.GetTracking; import pl.kuba6000.ae2webintegration.core.ae2request.async.GetTrackingHistory; import pl.kuba6000.ae2webintegration.core.ae2request.async.GridSettings; @@ -92,7 +89,7 @@ public RequestContext(HttpExchange exchange, int userID) { } else if (userID == -2) { this.username = "localhost"; } else { - GameProfile profile = AE2Controller.AE2Interface.web$getPlayerData() + pl.kuba6000.ae2webintegration.core.api.PlayerProfile profile = AE2Controller.AE2Interface.web$getPlayerData() .web$getPlayerProfile(userID); this.username = profile != null ? profile.getName() : "unknown"; } @@ -262,16 +259,8 @@ private static boolean checkAuth(HttpExchange t) throws IOException { if (postData.containsKey("register") && postData.containsKey("password")) { String username = postData.get("register"); UUID uuid = null; - for (EntityPlayerMP entityPlayerMP : FMLCommonHandler.instance() - .getMinecraftServerInstance() - .getConfigurationManager().playerEntityList) { - if (entityPlayerMP.getCommandSenderName() - .equalsIgnoreCase(username)) { - username = entityPlayerMP.getCommandSenderName(); - uuid = entityPlayerMP.getUniqueID(); - break; - } - } + uuid = WebEngine.getPlatform() + .getOnlinePlayerUUID(username); if (uuid == null) { t.getResponseHeaders() .add("Location", "?notonline"); @@ -489,16 +478,8 @@ public void handle(HttpExchange t) throws IOException { if (postData.containsKey("register") && postData.containsKey("password")) { String username = postData.get("register"); UUID uuid = null; - for (EntityPlayerMP entityPlayerMP : FMLCommonHandler.instance() - .getMinecraftServerInstance() - .getConfigurationManager().playerEntityList) { - if (entityPlayerMP.getCommandSenderName() - .equalsIgnoreCase(username)) { - username = entityPlayerMP.getCommandSenderName(); - uuid = entityPlayerMP.getUniqueID(); - break; - } - } + uuid = WebEngine.getPlatform() + .getOnlinePlayerUUID(username); if (uuid == null) { byte[] raw_response = "notonline".getBytes(); t.sendResponseHeaders(400, raw_response.length); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/Config.java b/src/main/java/pl/kuba6000/ae2webintegration/core/Config.java index 177133c..d87b40b 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/Config.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/Config.java @@ -3,13 +3,8 @@ import java.io.File; import java.util.Random; -import net.minecraftforge.common.config.Configuration; - public class Config { - private static File configDirectory; - private static File configFile; - public static String AE_PASSWORD = new Random().ints(48, 122 + 1) .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)) .limit(16) @@ -31,80 +26,7 @@ public class Config { // updates public static boolean CHECK_FOR_UPDATES = true; - public static void synchronizeConfiguration() { - Configuration configuration = new Configuration(configFile); - AE_PORT = configuration - .getInt("port", Configuration.CATEGORY_GENERAL, AE_PORT, 1, 65535, "Port for the hosted website"); - AE_PASSWORD = configuration - .getString("password", Configuration.CATEGORY_GENERAL, AE_PASSWORD, "Password for the admin account"); - ALLOW_NO_PASSWORD_ON_LOCALHOST = configuration.getBoolean( - "allow_no_password_on_localhost", - Configuration.CATEGORY_GENERAL, - ALLOW_NO_PASSWORD_ON_LOCALHOST, - "Don't require to login using loopback address (127.0.0.1/localhost)"); - AE_PUBLIC_MODE = configuration.getBoolean( - "public_mode", - Configuration.CATEGORY_GENERAL, - AE_PUBLIC_MODE, - "Public server mode = enable registration system on the website, players will be able to register and login to monitor their own ae networks, " - + "if disabled, there is only one admin account with password set in the config file with access to all networks on the server"); - AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE = configuration.getInt( - "max_requests_before_logged_in_per_minute", - Configuration.CATEGORY_GENERAL, - AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE, - 1, - 1000, - "How many requests can be made before user is logged in per minute"); - - DISCORD_WEBHOOK = configuration.getString( - "discord_webhook", - "discord", - "", - "Discord webhook url (OPTIONAL, leave empty to ignore) (WORKS ONLY IF PUBLIC_MODE IS DISABLED)"); - DISCORD_ROLE_ID = configuration - .getString("discord_role_id", "discord", "", "Role to ping on message (OPTIONAL, leave empty to ignore)"); - - TRACKING_TRACK_MACHINE_CRAFTING = configuration.getBoolean( - "track_machine_crafting", - "tracking", - TRACKING_TRACK_MACHINE_CRAFTING, - "Track automated crafting jobs (not ordered by player)"); - - CHECK_FOR_UPDATES = configuration.getBoolean( - "check_for_updates", - Configuration.CATEGORY_GENERAL, - CHECK_FOR_UPDATES, - "Check for new versions and display notifications in chat and on the website"); - - if (configuration.hasKey(Configuration.CATEGORY_GENERAL, "cpu_count_threshold")) { - configuration.getInt( - "cpu_count_threshold", - Configuration.CATEGORY_GENERAL, - 0, - 0, - 0, - "[DEPRECATED] This option is no longer used, you can remove it from your config file."); - } - - if (configuration.hasChanged()) { - configuration.save(); - } - } - - public static void init(File configDirectory) { - Config.configDirectory = new File(configDirectory, "ae2webintegration"); - Config.configFile = new File(Config.configDirectory, "ae2webintegration.cfg"); - if (!Config.configDirectory.exists()) { - Config.configDirectory.mkdirs(); - File oldConfigFile = new File(configDirectory, "ae2webintegration.cfg"); - if (oldConfigFile.exists()) { - oldConfigFile.renameTo(Config.configFile); - } - } - - } - public static File getConfigFile(String fileName) { - return new File(configDirectory, fileName); + return new File(WebEngine.getPlatform().getConfigDirectory(), fileName); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/GridData.java b/src/main/java/pl/kuba6000/ae2webintegration/core/GridData.java index 11044b2..678db2f 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/GridData.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/GridData.java @@ -1,6 +1,6 @@ package pl.kuba6000.ae2webintegration.core; -import static pl.kuba6000.ae2webintegration.core.AE2WebIntegration.LOG; +import static pl.kuba6000.ae2webintegration.forge.AE2WebIntegrationCore.LOG; import java.io.File; import java.io.Reader; diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/WebData.java b/src/main/java/pl/kuba6000/ae2webintegration/core/WebData.java index 25725be..9c94b0d 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/WebData.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/WebData.java @@ -1,6 +1,6 @@ package pl.kuba6000.ae2webintegration.core; -import static pl.kuba6000.ae2webintegration.core.AE2WebIntegration.LOG; +import static pl.kuba6000.ae2webintegration.forge.AE2WebIntegrationCore.LOG; import java.io.File; import java.io.Reader; @@ -11,9 +11,7 @@ import com.google.common.io.Files; import com.google.gson.Gson; -import com.mojang.authlib.GameProfile; -import cpw.mods.fml.common.FMLCommonHandler; import pl.kuba6000.ae2webintegration.core.utils.GSONUtils; public class WebData { @@ -30,14 +28,12 @@ public static int getPlayerId(String name) { if (name == null || name.isEmpty()) { return -1; } - GameProfile profile = FMLCommonHandler.instance() - .getMinecraftServerInstance() - .func_152358_ax() - .func_152655_a(name); - if (profile == null) { + UUID uuid = WebEngine.getPlatform() + .getOfflinePlayerUUID(name); + if (uuid == null) { return -1; } - Integer id = instance.UUIDToId.get(profile.getId()); + Integer id = instance.UUIDToId.get(uuid); if (id != null) { return id; } @@ -63,16 +59,16 @@ public static boolean verifyPassword(int playerId, String password) { return false; } - public static void setPassword(GameProfile playerId, String passwordHash) { + public static void setPassword(UUID playerId, String passwordHash) { if (passwordHash == null || passwordHash.isEmpty()) { - instance.passwords.remove(playerId.getId()); + instance.passwords.remove(playerId); } else { try { - instance.passwords.put(playerId.getId(), passwordHash); + instance.passwords.put(playerId, passwordHash); int pID = AE2Controller.AE2Interface.web$getPlayerData() .web$getPlayerId(playerId); - instance.UUIDToId.put(playerId.getId(), pID); - instance.IdToUUID.put(pID, playerId.getId()); + instance.UUIDToId.put(playerId, pID); + instance.IdToUUID.put(pID, playerId); } catch (Exception e) { LOG.error("Failed to set password for player ID: {}", playerId, e); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/WebEngine.java b/src/main/java/pl/kuba6000/ae2webintegration/core/WebEngine.java new file mode 100644 index 0000000..318b273 --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/WebEngine.java @@ -0,0 +1,16 @@ +package pl.kuba6000.ae2webintegration.core; + +import pl.kuba6000.ae2webintegration.core.api.IServerPlatform; + +public class WebEngine { + + private static IServerPlatform platform; + + public static void init(IServerPlatform platformImpl) { + platform = platformImpl; + } + + public static IServerPlatform getPlatform() { + return platform; + } +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetGridList.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetGridList.java index 06c3a82..770e35d 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetGridList.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetGridList.java @@ -2,7 +2,7 @@ import java.util.ArrayList; -import com.mojang.authlib.GameProfile; + import pl.kuba6000.ae2webintegration.core.GridData; import pl.kuba6000.ae2webintegration.core.api.AEApi.AEControllerState; @@ -56,7 +56,7 @@ public void handle(IAE ae) { if (!context.isAdmin() && !security.web$hasPermissions(context.getUserID())) { continue; } - GameProfile gameProfile = security.web$getOwnerProfile(); + pl.kuba6000.ae2webintegration.core.api.PlayerProfile gameProfile = security.web$getOwnerProfile(); GridData gridData = GridData.get(security.web$getSecurityKey()); grids.add( new JSON_GridData( diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java index 89563e7..511a26d 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java @@ -5,7 +5,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import net.minecraft.util.IChatComponent; import pl.kuba6000.ae2webintegration.core.AE2Controller; import pl.kuba6000.ae2webintegration.core.api.AEApi.AEActionable; @@ -155,10 +154,10 @@ void handle(IAEGrid grid) { return; } } - IChatComponent error = craftingGrid.web$submitJob(craftingJob, target, true, grid); + String error = craftingGrid.web$submitJob(craftingJob, target, true, grid); if (error != null) { deny("FAIL"); - setData(error.getUnformattedTextForChat()); + setData(error); } else { done(); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/DimensionalCoords.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/DimensionalCoords.java index 50a9aab..480fd2b 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/DimensionalCoords.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/api/DimensionalCoords.java @@ -2,7 +2,6 @@ import java.util.Objects; -import net.minecraft.world.World; public class DimensionalCoords { @@ -18,12 +17,7 @@ public DimensionalCoords(int dimid, int x, int y, int z) { this.z = z; } - public DimensionalCoords(World world, int x, int y, int z) { - this.dimid = world.provider.dimensionId; - this.x = x; - this.y = y; - this.z = z; - } + @Override public int hashCode() { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/IServerPlatform.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/IServerPlatform.java new file mode 100644 index 0000000..787c9a1 --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/api/IServerPlatform.java @@ -0,0 +1,26 @@ +package pl.kuba6000.ae2webintegration.core.api; + +import java.io.File; +import java.util.UUID; + +public interface IServerPlatform { + + /** + * Resolves a UUID of an online player by their username. + * + * @return The UUID, or null if the player is not online. + */ + UUID getOnlinePlayerUUID(String username); + + /** + * Resolves a UUID from the server's cache/offline data for a given username. + * + * @return The UUID, or null if not found. + */ + UUID getOfflinePlayerUUID(String username); + + /** + * Gets the main config directory. + */ + File getConfigDirectory(); +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/PlayerProfile.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/PlayerProfile.java new file mode 100644 index 0000000..289e211 --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/api/PlayerProfile.java @@ -0,0 +1,21 @@ +package pl.kuba6000.ae2webintegration.core.api; + +import java.util.UUID; + +public class PlayerProfile { + private final UUID uuid; + private final String name; + + public PlayerProfile(UUID uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + public UUID getUUID() { + return uuid; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/discord/DiscordManager.java b/src/main/java/pl/kuba6000/ae2webintegration/core/discord/DiscordManager.java index 475df75..937c7a2 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/discord/DiscordManager.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/discord/DiscordManager.java @@ -1,6 +1,6 @@ package pl.kuba6000.ae2webintegration.core.discord; -import static pl.kuba6000.ae2webintegration.core.AE2WebIntegration.MODID; +import static pl.kuba6000.ae2webintegration.forge.AE2WebIntegrationCore.MODID; import java.io.IOException; import java.io.OutputStream; diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEGrid.java index 61257b0..ed95f3a 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEGrid.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEGrid.java @@ -1,6 +1,5 @@ package pl.kuba6000.ae2webintegration.core.interfaces; -import net.minecraft.util.IChatComponent; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEPathingGrid; @@ -21,6 +20,6 @@ public interface IAEGrid { Object web$getPlayerSource(); - IChatComponent web$getLastFakePlayerChatMessage(); + Object web$getLastFakePlayerChatMessage(); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEPlayerData.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEPlayerData.java index 9d882fc..61c08cf 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEPlayerData.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEPlayerData.java @@ -1,11 +1,11 @@ package pl.kuba6000.ae2webintegration.core.interfaces; -import com.mojang.authlib.GameProfile; +import java.util.UUID; public interface IAEPlayerData { - GameProfile web$getPlayerProfile(int playerId); + pl.kuba6000.ae2webintegration.core.api.PlayerProfile web$getPlayerProfile(int playerId); - int web$getPlayerId(GameProfile id); + int web$getPlayerId(UUID id); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java index bd0346a..f5887f1 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java @@ -3,7 +3,6 @@ import java.util.Set; import java.util.concurrent.Future; -import net.minecraft.util.IChatComponent; import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; @@ -18,5 +17,5 @@ public interface IAECraftingGrid { Future web$beginCraftingJob(IAEGrid grid, IStack stack); - IChatComponent web$submitJob(IAECraftingJob job, ICraftingCPUCluster target, boolean prioritizePower, IAEGrid grid); + String web$submitJob(IAECraftingJob job, ICraftingCPUCluster target, boolean prioritizePower, IAEGrid grid); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAESecurityGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAESecurityGrid.java index abea4bb..13bc653 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAESecurityGrid.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAESecurityGrid.java @@ -1,6 +1,6 @@ package pl.kuba6000.ae2webintegration.core.interfaces.service; -import com.mojang.authlib.GameProfile; + public interface IAESecurityGrid { @@ -10,7 +10,7 @@ public interface IAESecurityGrid { int web$getOwner(); - GameProfile web$getOwnerProfile(); + pl.kuba6000.ae2webintegration.core.api.PlayerProfile web$getOwnerProfile(); boolean web$hasPermissions(int playerId); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2WebIntegration.java b/src/main/java/pl/kuba6000/ae2webintegration/forge/AE2WebIntegrationCore.java similarity index 78% rename from src/main/java/pl/kuba6000/ae2webintegration/core/AE2WebIntegration.java rename to src/main/java/pl/kuba6000/ae2webintegration/forge/AE2WebIntegrationCore.java index 8509403..3cabd05 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2WebIntegration.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/forge/AE2WebIntegrationCore.java @@ -1,6 +1,6 @@ -package pl.kuba6000.ae2webintegration.core; +package pl.kuba6000.ae2webintegration.forge; -import static pl.kuba6000.ae2webintegration.core.AE2WebIntegration.MODID; +import static pl.kuba6000.ae2webintegration.forge.AE2WebIntegrationCore.MODID; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -14,6 +14,10 @@ import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.event.FMLServerStoppingEvent; import pl.kuba6000.ae2webintegration.Tags; +import pl.kuba6000.ae2webintegration.core.*; + +import pl.kuba6000.ae2webintegration.core.discord.*; +import pl.kuba6000.ae2webintegration.core.utils.*; @Mod( modid = MODID, @@ -21,14 +25,14 @@ name = "AE2WebIntegration-Core", acceptedMinecraftVersions = "*", acceptableRemoteVersions = "*") -public class AE2WebIntegration { +public class AE2WebIntegrationCore { public static final String MODID = "ae2webintegration-core"; public static final Logger LOG = LogManager.getLogger(MODID); @SidedProxy( - clientSide = "pl.kuba6000.ae2webintegration.core.ClientProxy", - serverSide = "pl.kuba6000.ae2webintegration.core.CommonProxy") + clientSide = "pl.kuba6000.ae2webintegration.forge.ClientProxy", + serverSide = "pl.kuba6000.ae2webintegration.forge.CommonProxy") public static CommonProxy proxy; @Mod.EventHandler diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ClientProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/forge/ClientProxy.java similarity index 83% rename from src/main/java/pl/kuba6000/ae2webintegration/core/ClientProxy.java rename to src/main/java/pl/kuba6000/ae2webintegration/forge/ClientProxy.java index c8a9833..c7309fc 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ClientProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/forge/ClientProxy.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.core; +package pl.kuba6000.ae2webintegration.forge; public class ClientProxy extends CommonProxy { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/forge/CommonProxy.java similarity index 80% rename from src/main/java/pl/kuba6000/ae2webintegration/core/CommonProxy.java rename to src/main/java/pl/kuba6000/ae2webintegration/forge/CommonProxy.java index a4f20a4..03f07d8 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/forge/CommonProxy.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.core; +package pl.kuba6000.ae2webintegration.forge; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.event.FMLInitializationEvent; @@ -8,8 +8,12 @@ import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.event.FMLServerStoppingEvent; import pl.kuba6000.ae2webintegration.Tags; -import pl.kuba6000.ae2webintegration.core.commands.BaseCommandHandler; +import pl.kuba6000.ae2webintegration.core.*; + +import pl.kuba6000.ae2webintegration.forge.commands.BaseCommandHandler; +import pl.kuba6000.ae2webintegration.core.discord.*; import pl.kuba6000.ae2webintegration.core.discord.DiscordManager; +import pl.kuba6000.ae2webintegration.core.utils.*; import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; public class CommonProxy { @@ -17,13 +21,14 @@ public class CommonProxy { // preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the // GameRegistry." (Remove if not needed) public void preInit(FMLPreInitializationEvent event) { - Config.init(event.getModConfigurationDirectory()); - Config.synchronizeConfiguration(); + ForgeConfig.init(event.getModConfigurationDirectory()); + ForgeConfig.synchronizeConfiguration(); + WebEngine.init(new ForgePlatform(new java.io.File(event.getModConfigurationDirectory(), "ae2webintegration"))); WebData.loadData(); GridData.loadData(); - AE2WebIntegration.LOG.info("AE2WebIntegration loading at version " + Tags.VERSION); - if (Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated()) AE2WebIntegration.LOG.warn( + AE2WebIntegrationCore.LOG.info("AE2WebIntegration loading at version " + Tags.VERSION); + if (Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated()) AE2WebIntegrationCore.LOG.warn( "You are not on latest version ! Consider updating to {} at https://github.com/kuba6000/AE2-Web-Integration/releases/latest", VersionChecker.getLatestTag()); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/FMLEventHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/forge/FMLEventHandler.java similarity index 88% rename from src/main/java/pl/kuba6000/ae2webintegration/core/FMLEventHandler.java rename to src/main/java/pl/kuba6000/ae2webintegration/forge/FMLEventHandler.java index 87b16cb..f0d25b6 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/FMLEventHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/forge/FMLEventHandler.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.core; +package pl.kuba6000.ae2webintegration.forge; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.ChatComponentText; @@ -7,7 +7,11 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent; import cpw.mods.fml.common.gameevent.TickEvent; +import pl.kuba6000.ae2webintegration.core.*; import pl.kuba6000.ae2webintegration.core.ae2request.sync.ISyncedRequest; + +import pl.kuba6000.ae2webintegration.core.discord.*; +import pl.kuba6000.ae2webintegration.core.utils.*; import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; public class FMLEventHandler { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/forge/ForgeConfig.java b/src/main/java/pl/kuba6000/ae2webintegration/forge/ForgeConfig.java new file mode 100644 index 0000000..5634270 --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/forge/ForgeConfig.java @@ -0,0 +1,74 @@ +package pl.kuba6000.ae2webintegration.forge; + +import java.io.File; + +import net.minecraftforge.common.config.Configuration; + +import pl.kuba6000.ae2webintegration.core.Config; + +public class ForgeConfig { + + private static File configDirectory; + private static File configFile; + + public static void init(File rootConfigDirectory) { + configDirectory = new File(rootConfigDirectory, "ae2webintegration"); + configFile = new File(configDirectory, "ae2webintegration.cfg"); + if (!configDirectory.exists()) { + configDirectory.mkdirs(); + File oldConfigFile = new File(rootConfigDirectory, "ae2webintegration.cfg"); + if (oldConfigFile.exists()) { + oldConfigFile.renameTo(configFile); + } + } + } + + public static void synchronizeConfiguration() { + Configuration configuration = new Configuration(configFile); + Config.AE_PORT = configuration + .getInt("port", Configuration.CATEGORY_GENERAL, Config.AE_PORT, 1, 65535, "Port for the hosted website"); + Config.AE_PASSWORD = configuration.getString( + "password", + Configuration.CATEGORY_GENERAL, + Config.AE_PASSWORD, + "Password for the admin account"); + Config.ALLOW_NO_PASSWORD_ON_LOCALHOST = configuration.getBoolean( + "allow_no_password_on_localhost", + Configuration.CATEGORY_GENERAL, + Config.ALLOW_NO_PASSWORD_ON_LOCALHOST, + "Don't require to login using loopback address (127.0.0.1/localhost)"); + Config.AE_PUBLIC_MODE = configuration.getBoolean( + "public_mode", + Configuration.CATEGORY_GENERAL, + Config.AE_PUBLIC_MODE, + "If enabled every player will have their own 'account' (good for public servers with multiple ME Networks)"); + Config.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE = configuration.getInt( + "max_requests_before_logged_in_per_minute", + Configuration.CATEGORY_GENERAL, + Config.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE, + 1, + 999999999, + "Max requests per minute before logging in (anti brute force)"); + + Config.DISCORD_WEBHOOK = configuration.getString( + "discord_webhook", + "discord", + Config.DISCORD_WEBHOOK, + "Webhook url for discord integration, keep empty to disable"); + Config.DISCORD_ROLE_ID = configuration.getString( + "discord_role_id", + "discord", + Config.DISCORD_ROLE_ID, + "Role id to ping on errors, keep empty to disable pinging (if webhook is empty it will do nothing)"); + + Config.TRACKING_TRACK_MACHINE_CRAFTING = configuration.getBoolean( + "track_machine_crafting", + "tracking", + Config.TRACKING_TRACK_MACHINE_CRAFTING, + "Track crafting jobs run directly by machines ? (Not manually ordered)"); + + if (configuration.hasChanged()) { + configuration.save(); + } + } +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/forge/ForgePlatform.java b/src/main/java/pl/kuba6000/ae2webintegration/forge/ForgePlatform.java new file mode 100644 index 0000000..4ed3b28 --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/forge/ForgePlatform.java @@ -0,0 +1,50 @@ +package pl.kuba6000.ae2webintegration.forge; + +import java.io.File; +import java.util.UUID; + +import net.minecraft.entity.player.EntityPlayerMP; + +import com.mojang.authlib.GameProfile; + +import cpw.mods.fml.common.FMLCommonHandler; +import pl.kuba6000.ae2webintegration.core.api.IServerPlatform; + +public class ForgePlatform implements IServerPlatform { + + private final File configDir; + + public ForgePlatform(File configDir) { + this.configDir = configDir; + } + + @Override + public UUID getOnlinePlayerUUID(String username) { + for (EntityPlayerMP entityPlayerMP : (java.util.List) FMLCommonHandler.instance() + .getMinecraftServerInstance() + .getConfigurationManager().playerEntityList) { + if (entityPlayerMP.getCommandSenderName() + .equalsIgnoreCase(username)) { + return entityPlayerMP.getUniqueID(); + } + } + return null; + } + + @Override + public UUID getOfflinePlayerUUID(String username) { + GameProfile profile = FMLCommonHandler.instance() + .getMinecraftServerInstance() + .func_152358_ax() + .func_152655_a(username); + if (profile != null) { + return profile.getId(); + } + return null; + } + + @Override + public File getConfigDirectory() { + return configDir; + } +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/commands/BaseCommandHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/forge/commands/BaseCommandHandler.java similarity index 93% rename from src/main/java/pl/kuba6000/ae2webintegration/core/commands/BaseCommandHandler.java rename to src/main/java/pl/kuba6000/ae2webintegration/forge/commands/BaseCommandHandler.java index 31a89ac..148c36f 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/commands/BaseCommandHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/forge/commands/BaseCommandHandler.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.core.commands; +package pl.kuba6000.ae2webintegration.forge.commands; import java.util.UUID; @@ -13,6 +13,7 @@ import pl.kuba6000.ae2webintegration.core.AE2Controller; import pl.kuba6000.ae2webintegration.core.Config; +import pl.kuba6000.ae2webintegration.forge.ForgeConfig; import pl.kuba6000.ae2webintegration.core.WebData; public class BaseCommandHandler extends CommandBase { @@ -49,7 +50,7 @@ public void processCommand(ICommandSender sender, String[] args) { sender.addChatMessage(chatcomponenttranslation2); return; } - Config.synchronizeConfiguration(); + ForgeConfig.synchronizeConfiguration(); AE2Controller.stopHTTPServer(); AE2Controller.startHTTPServer(); sender.addChatMessage( @@ -88,7 +89,7 @@ public void processCommand(ICommandSender sender, String[] args) { return; } - WebData.setPassword(((EntityPlayerMP) sender).getGameProfile(), p.getRight()); + WebData.setPassword(((EntityPlayerMP) sender).getUniqueID(), p.getRight()); AE2Controller.awaitingRegistration.remove(id); From ed64dcd14dbf663c186dbb8c53751efd7777d0ac Mon Sep 17 00:00:00 2001 From: Jakub Date: Thu, 7 May 2026 16:21:46 +0200 Subject: [PATCH 06/29] Extract core engine to interface submodule and setup gradle dependencies --- .gitmodules | 4 + dependencies.gradle | 3 + settings.gradle | 3 +- .../ae2webintegration/core/AE2Controller.java | 689 ------------------ .../ae2webintegration/core/AE2JobTracker.java | 239 ------ .../core/AEMixinCallbacks.java | 44 -- .../ae2webintegration/core/AEWebAPI.java | 21 - .../ae2webintegration/core/Config.java | 32 - .../ae2webintegration/core/GridData.java | 115 --- .../core/PasswordHelper.java | 76 -- .../ae2webintegration/core/WebData.java | 121 --- .../ae2webintegration/core/WebEngine.java | 16 - .../core/ae2request/IRequest.java | 57 -- .../core/ae2request/async/GetTracking.java | 32 - .../ae2request/async/GetTrackingHistory.java | 45 -- .../core/ae2request/async/GridSettings.java | 25 - .../core/ae2request/async/IAsyncRequest.java | 29 - .../core/ae2request/sync/CancelCPU.java | 41 -- .../core/ae2request/sync/GetCPU.java | 119 --- .../core/ae2request/sync/GetCPUList.java | 66 -- .../core/ae2request/sync/GetGridList.java | 90 --- .../core/ae2request/sync/GetItems.java | 53 -- .../core/ae2request/sync/ISyncedRequest.java | 65 -- .../core/ae2request/sync/Job.java | 174 ----- .../core/ae2request/sync/Order.java | 79 -- .../core/api/AEApi/AEActionable.java | 6 - .../core/api/AEApi/AEControllerState.java | 9 - .../core/api/DimensionalCoords.java | 34 - .../core/api/IAEMixinCallbacks.java | 28 - .../core/api/IAEWebInterface.java | 18 - .../core/api/IServerPlatform.java | 26 - .../core/api/JSON_CompactedItem.java | 47 -- .../api/JSON_CompactedJobTrackingInfo.java | 95 --- .../core/api/JSON_DetailedItem.java | 10 - .../core/api/PlayerProfile.java | 21 - .../core/discord/DiscordManager.java | 115 --- .../core/interfaces/IAE.java | 11 - .../core/interfaces/IAECraftingJob.java | 11 - .../interfaces/IAECraftingPatternDetails.java | 7 - .../core/interfaces/IAEGrid.java | 25 - .../core/interfaces/IAEMeInventoryItem.java | 11 - .../core/interfaces/IAEPlayerData.java | 11 - .../core/interfaces/ICraftingCPUCluster.java | 31 - .../core/interfaces/IItemList.java | 7 - .../interfaces/IPatternProviderViewable.java | 11 - .../core/interfaces/IStack.java | 27 - .../interfaces/service/IAECraftingGrid.java | 21 - .../interfaces/service/IAEPathingGrid.java | 11 - .../interfaces/service/IAESecurityGrid.java | 17 - .../interfaces/service/IAEStorageGrid.java | 16 - .../core/utils/GSONUtils.java | 49 -- .../core/utils/HTTPUtils.java | 35 - .../core/utils/RateLimiter.java | 49 -- .../core/utils/VersionChecker.java | 70 -- web-engine | 1 + 55 files changed, 10 insertions(+), 3058 deletions(-) create mode 100644 .gitmodules delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/AE2JobTracker.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/AEMixinCallbacks.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/AEWebAPI.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/Config.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/GridData.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/PasswordHelper.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/WebData.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/WebEngine.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/IRequest.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTracking.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTrackingHistory.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GridSettings.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/IAsyncRequest.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/CancelCPU.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPU.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPUList.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetGridList.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/ISyncedRequest.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Order.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/AEApi/AEActionable.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/AEApi/AEControllerState.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/DimensionalCoords.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEMixinCallbacks.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEWebInterface.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/IServerPlatform.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedItem.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedJobTrackingInfo.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_DetailedItem.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/api/PlayerProfile.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/discord/DiscordManager.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAE.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingJob.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingPatternDetails.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEGrid.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEMeInventoryItem.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEPlayerData.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/ICraftingCPUCluster.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemList.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IPatternProviderViewable.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEPathingGrid.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAESecurityGrid.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/utils/GSONUtils.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/utils/HTTPUtils.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/utils/RateLimiter.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/core/utils/VersionChecker.java create mode 160000 web-engine diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..def7749 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "web-engine"] + path = web-engine + url = https://github.com/kuba6000/AE2-Web-Integration.git + branch = interface diff --git a/dependencies.gradle b/dependencies.gradle index 3e41790..facb369 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -34,6 +34,9 @@ * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph */ dependencies { + implementation project(':web-engine') + shadow project(':web-engine') + api("com.github.GTNewHorizons:GTNHLib:0.9.53:dev") api("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-909-GTNH:dev") api("com.github.GTNewHorizons:AE2FluidCraft-Rework:1.5.76-gtnh:dev") diff --git a/settings.gradle b/settings.gradle index ea29dac..5ab75e9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,3 @@ - pluginManagement { repositories { maven { @@ -19,3 +18,5 @@ pluginManagement { plugins { id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.24' } + +include ':web-engine' diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java b/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java deleted file mode 100644 index 777044e..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2Controller.java +++ /dev/null @@ -1,689 +0,0 @@ -package pl.kuba6000.ae2webintegration.core; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.security.SecureRandom; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Scanner; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.tuple.Pair; - -import com.google.gson.JsonObject; -import com.mojang.authlib.GameProfile; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; - -import pl.kuba6000.ae2webintegration.core.ae2request.async.GetTracking; -import pl.kuba6000.ae2webintegration.core.ae2request.async.GetTrackingHistory; -import pl.kuba6000.ae2webintegration.core.ae2request.async.GridSettings; -import pl.kuba6000.ae2webintegration.core.ae2request.async.IAsyncRequest; -import pl.kuba6000.ae2webintegration.core.ae2request.sync.CancelCPU; -import pl.kuba6000.ae2webintegration.core.ae2request.sync.GetCPU; -import pl.kuba6000.ae2webintegration.core.ae2request.sync.GetCPUList; -import pl.kuba6000.ae2webintegration.core.ae2request.sync.GetGridList; -import pl.kuba6000.ae2webintegration.core.ae2request.sync.GetItems; -import pl.kuba6000.ae2webintegration.core.ae2request.sync.ISyncedRequest; -import pl.kuba6000.ae2webintegration.core.ae2request.sync.Job; -import pl.kuba6000.ae2webintegration.core.ae2request.sync.Order; -import pl.kuba6000.ae2webintegration.core.interfaces.IAE; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -import pl.kuba6000.ae2webintegration.core.utils.HTTPUtils; -import pl.kuba6000.ae2webintegration.core.utils.RateLimiter; -import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; - -public class AE2Controller { - - public static IAE AE2Interface; - - public static long timer; - private static HttpServer server; - - public static GameProfile AEControllerProfile; - - static { - try { - AEControllerProfile = new GameProfile( - UUID.nameUUIDFromBytes("AE2-WEB-INTEGRATION-AE2CONTROLLER".getBytes("UTF-8")), - "AE2CONTROLLER"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - public static class RequestContext { - - private final HttpExchange exchange; - private final Map getParams; - // -1 id is admin permissions -2 is localhost access - private final int userID; - private final String username; - - public RequestContext(HttpExchange exchange, int userID) { - this.exchange = exchange; - this.getParams = HTTPUtils.parseQueryString( - exchange.getRequestURI() - .getQuery()); - this.userID = userID; - if (userID == -1) { - this.username = "admin"; - } else if (userID == -2) { - this.username = "localhost"; - } else { - pl.kuba6000.ae2webintegration.core.api.PlayerProfile profile = AE2Controller.AE2Interface.web$getPlayerData() - .web$getPlayerProfile(userID); - this.username = profile != null ? profile.getName() : "unknown"; - } - } - - public HttpExchange getExchange() { - return exchange; - } - - public Map getGetParams() { - return getParams; - } - - public int getUserID() { - return userID; - } - - public boolean isAdmin() { - return userID == -1 || userID == -2; - } - } - - static ThreadLocal requestContext = new ThreadLocal<>(); - - public static HashMap> awaitingRegistration = new HashMap<>(); - - public static ConcurrentLinkedQueue requests = new ConcurrentLinkedQueue<>(); - - private static final RateLimiter rateLimiter = new RateLimiter( - Config.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE, - 60 * 1000, - 60 * 60 * 1000); // 60 requests per minute, whitelisted for 1 hour - - public static void startHTTPServer() { - try { - server = HttpServer.create(new InetSocketAddress(Config.AE_PORT), 0); - } catch (IOException e) { - throw new RuntimeException(e); - } - server.createContext("/grids", new SyncedRequestHandler(GetGridList.class)); - server.createContext("/list", new SyncedRequestHandler(GetCPUList.class)); - server.createContext("/get", new SyncedRequestHandler(GetCPU.class)); - server.createContext("/cancelcpu", new SyncedRequestHandler(CancelCPU.class)); - server.createContext("/items", new SyncedRequestHandler(GetItems.class)); - server.createContext("/order", new SyncedRequestHandler(Order.class)); - server.createContext("/job", new SyncedRequestHandler(Job.class)); - server.createContext("/trackinghistory", new ASyncRequestHandler(GetTrackingHistory.class)); - server.createContext("/gettracking", new ASyncRequestHandler(GetTracking.class)); - server.createContext("/gridsettings", new ASyncRequestHandler(GridSettings.class)); - server.createContext("/auth", new AuthHandler()); - server.createContext("/", new WebHandler()); - server.setExecutor(serverThread); - server.start(); - } - - public static void stopHTTPServer() { - server.stop(0); - } - - private static final ExecutorService serverThread = new ThreadPoolExecutor( - 0, - Integer.MAX_VALUE, - 60L, - TimeUnit.SECONDS, - new SynchronousQueue()) { - - @Override - protected void afterExecute(Runnable r, Throwable t) { - super.afterExecute(r, t); - requestContext.remove(); - } - }; - - public static ConcurrentHashMap hashcodeToAEItemStack = new ConcurrentHashMap<>(); - - private static final HashMap> validTokens = new HashMap<>(); - - private static String generateToken() { - return generateToken(200); - } - - private static String generateToken(int limit) { - return new SecureRandom().ints(48, 122 + 1) - .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)) - .limit(limit) - .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) - .toString(); - } - - private static boolean checkAuth(HttpExchange t) throws IOException { - InetAddress remoteAddress = t.getRemoteAddress() - .getAddress(); - - if (Config.ALLOW_NO_PASSWORD_ON_LOCALHOST && remoteAddress.isLoopbackAddress()) { - requestContext.set(new RequestContext(t, -2)); // Localhost access - rateLimiter.ensureWhitelisted(remoteAddress); - return true; - } - - // Alternative authentication method - List auth = t.getRequestHeaders() - .get("Authorization"); - if (auth != null && !auth.isEmpty()) { - String token = auth.get(0); - token = token.replace("Bearer ", ""); - Pair tokenData = validTokens.get(token); - if (tokenData != null) { - long validity = tokenData.getLeft(); - if (System.currentTimeMillis() < validity) { - requestContext.set(new RequestContext(t, tokenData.getRight())); - rateLimiter.ensureWhitelisted(remoteAddress); - return true; // Token is valid - } else { - validTokens.remove(token); // Remove expired token - return false; // Token expired - } - } else { - return false; // Invalid token - } - } - - List cookies = t.getRequestHeaders() - .get("Cookie"); - if (cookies != null && !cookies.isEmpty()) { - String cookiesString = cookies.get(0); - for (String cookie : cookiesString.split("; ")) { - if (cookie.startsWith("authenticationToken=")) { - String token = cookie.substring("authenticationToken=".length()); - Pair tokenData = validTokens.get(token); - if (tokenData != null) { - long validity = tokenData.getLeft(); - if (System.currentTimeMillis() < validity) { - Map GET_PARAMS = HTTPUtils.parseQueryString( - t.getRequestURI() - .getQuery()); - if (GET_PARAMS.containsKey("logout")) { - validTokens.remove(token); // Invalidate token on logout - t.getResponseHeaders() - .add("Set-Cookie", "authenticationToken=" + token + "; Max-Age=-1; HttpOnly"); - t.getResponseHeaders() - .add("Location", "."); - t.sendResponseHeaders(302, -1); - return false; // Logout successful - } - requestContext.set(new RequestContext(t, tokenData.getRight())); - rateLimiter.ensureWhitelisted(remoteAddress); - return true; // Token is valid - } else { - validTokens.remove(token); // Remove expired token - t.getResponseHeaders() - .add("Set-Cookie", "authenticationToken=" + token + "; Max-Age=-1; HttpOnly"); - return false; // Token expired - } - } else { - t.getResponseHeaders() - .add("Set-Cookie", "authenticationToken=" + token + "; Max-Age=-1; HttpOnly"); - return false; // Invalid token - } - } - } - } - if (t.getRequestMethod() - .equals("POST")) { - String postRaw = new Scanner(t.getRequestBody()).nextLine(); - Map postData = HTTPUtils.parseQueryString(postRaw); - - if (postData.containsKey("register") && postData.containsKey("password")) { - String username = postData.get("register"); - UUID uuid = null; - uuid = WebEngine.getPlatform() - .getOnlinePlayerUUID(username); - if (uuid == null) { - t.getResponseHeaders() - .add("Location", "?notonline"); - t.sendResponseHeaders(302, -1); - return false; - } - String password = postData.get("password"); - try { - password = PasswordHelper.generateStrongPasswordHash(password); - } catch (Exception e) { - t.getResponseHeaders() - .add("Location", "?invalidpassword"); - t.sendResponseHeaders(302, -1); - return false; - } - - String confirmationToken = generateToken(50); - awaitingRegistration.put(uuid, Pair.of(confirmationToken, password)); - t.getResponseHeaders() - .add("Location", "?confirmregistration&token=" + confirmationToken); - t.sendResponseHeaders(302, -1); - return false; // Registration initiated - } - - if (postData.containsKey("password") && postData.containsKey("username")) { - String username = postData.get("username"); - int playerID; - if (username.equalsIgnoreCase("admin") || !Config.AE_PUBLIC_MODE) { - username = "Admin"; - playerID = -1; - String password = postData.get("password"); - if (!password.equals(Config.AE_PASSWORD) && !Config.AE_PASSWORD.isEmpty()) { - t.getResponseHeaders() - .add("Location", "?invalidpassword"); - t.sendResponseHeaders(302, -1); - return false; - } - } else { - playerID = WebData.getPlayerId(username); - if (playerID == -1) { - t.getResponseHeaders() - .add("Location", "?invaliduser"); - t.sendResponseHeaders(302, -1); - return false; - } - String password = postData.get("password"); - if (!WebData.verifyPassword(playerID, password)) { - t.getResponseHeaders() - .add("Location", "?invalidpassword"); - t.sendResponseHeaders(302, -1); - return false; - } - } - boolean rememberMe = postData.containsKey("remember"); - String token = generateToken(); - long validFor = rememberMe ? 604_800L : 3600L; // 1 week or 1 hour - validTokens.put(token, Pair.of(System.currentTimeMillis() + validFor * 1000L, playerID)); // 1 hour - // validity - t.getResponseHeaders() - .add("Set-Cookie", "authenticationToken=" + token + "; Max-Age=" + validFor + "; HttpOnly"); - t.getResponseHeaders() - .add("Location", "."); - t.sendResponseHeaders(302, -1); - rateLimiter.ensureWhitelisted(remoteAddress); - return true; - } - } - return false; - } - - private static boolean preHTTPHandler(HttpExchange t) throws IOException { - if (!rateLimiter.isAllowed( - t.getRemoteAddress() - .getAddress())) { - byte[] raw_response = "Too Many Requests".getBytes(); - t.getResponseHeaders() - .add("Content-Type", "text/plain"); - t.sendResponseHeaders(429, raw_response.length); // Too Many Requests - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - return true; - } - t.getResponseHeaders() - .add("Access-Control-Allow-Origin", "*"); - if (t.getRequestMethod() - .equalsIgnoreCase("OPTIONS")) { - t.getResponseHeaders() - .add("Access-Control-Allow-Methods", "GET, OPTIONS"); - t.getResponseHeaders() - .add("Access-Control-Allow-Headers", "Content-Type,Authorization"); - t.sendResponseHeaders(204, -1); - return true; - } - if (!checkAuth(t)) { - t.sendResponseHeaders(401, -1); - return true; - } - return false; - } - - private static boolean sendRequest(ISyncedRequest request) { - requests.offer(request); - int timeout = 0; - while (!request.isDone.get() && timeout < 50) { - try { - Thread.sleep(200); - timeout++; - } catch (InterruptedException e) { - return requests.remove(request); - } - } - if (timeout == 50) { - return requests.remove(request); - } - return true; - } - - static class SyncedRequestHandler implements HttpHandler { - - private final Constructor factory; - - public SyncedRequestHandler(Class syncedRequestClass) { - try { - factory = syncedRequestClass.getConstructor(); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } - } - - @Override - public void handle(HttpExchange t) throws IOException { - if (preHTTPHandler(t)) return; - - ISyncedRequest syncedRequest; - - try { - syncedRequest = factory.newInstance(); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - - if (syncedRequest.init(requestContext.get())) { - sendRequest(syncedRequest); - } - - byte[] raw_response = syncedRequest.getJSON() - .getBytes(); - t.sendResponseHeaders(200, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - - } - - } - - static class ASyncRequestHandler implements HttpHandler { - - private final Constructor factory; - - public ASyncRequestHandler(Class syncedRequestClass) { - try { - factory = syncedRequestClass.getConstructor(); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } - } - - @Override - public void handle(HttpExchange t) throws IOException { - if (preHTTPHandler(t)) return; - - IAsyncRequest asyncRequest; - - try { - asyncRequest = factory.newInstance(); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - - asyncRequest.handle(requestContext.get()); - - byte[] raw_response = asyncRequest.getJSON() - .getBytes(); - t.sendResponseHeaders(200, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - } - - } - - static class AuthHandler implements HttpHandler { - - @Override - public void handle(HttpExchange t) throws IOException { - if (!rateLimiter.isAllowed( - t.getRemoteAddress() - .getAddress())) { - byte[] raw_response = "Too Many Requests".getBytes(); - t.getResponseHeaders() - .add("Content-Type", "text/plain"); - t.sendResponseHeaders(429, raw_response.length); // Too Many Requests - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - return; - } - if (t.getRequestMethod() - .equals("POST")) { - String postRaw = new Scanner(t.getRequestBody()).nextLine(); - Map postData = HTTPUtils.parseQueryString(postRaw); - - if (postData.containsKey("register") && postData.containsKey("password")) { - String username = postData.get("register"); - UUID uuid = null; - uuid = WebEngine.getPlatform() - .getOnlinePlayerUUID(username); - if (uuid == null) { - byte[] raw_response = "notonline".getBytes(); - t.sendResponseHeaders(400, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - return; - } - String password = postData.get("password"); - try { - password = PasswordHelper.generateStrongPasswordHash(password); - } catch (Exception e) { - byte[] raw_response = "invalidpassword".getBytes(); - t.sendResponseHeaders(400, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - return; - } - - String confirmationToken = generateToken(50); - awaitingRegistration.put(uuid, Pair.of(confirmationToken, password)); - byte[] raw_response = confirmationToken.getBytes(); - t.sendResponseHeaders(200, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - return; - } - - if (postData.containsKey("password") && postData.containsKey("username")) { - String username = postData.get("username"); - int playerID; - if (username.equalsIgnoreCase("admin") || !Config.AE_PUBLIC_MODE) { - username = "Admin"; - playerID = -1; - String password = postData.get("password"); - if (!password.equals(Config.AE_PASSWORD) && !Config.AE_PASSWORD.isEmpty()) { - byte[] raw_response = "invalidpassword".getBytes(); - t.sendResponseHeaders(400, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - return; - } - } else { - playerID = WebData.getPlayerId(username); - if (playerID == -1) { - byte[] raw_response = "invaliduser".getBytes(); - t.sendResponseHeaders(400, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - return; - } - String password = postData.get("password"); - if (!WebData.verifyPassword(playerID, password)) { - byte[] raw_response = "invalidpassword".getBytes(); - t.sendResponseHeaders(400, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - return; - } - } - boolean rememberMe = postData.containsKey("remember"); - String token = generateToken(); - long validFor = rememberMe ? 604_800L : 3600L; // 1 week or 1 hour - validTokens.put(token, Pair.of(System.currentTimeMillis() + validFor * 1000L, playerID)); // 1 hour - // validity - JsonObject json = new JsonObject(); - json.addProperty("token", token); - json.addProperty("username", username); - json.addProperty("isAdmin", playerID == -1); - json.addProperty("isOutdated", Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated()); - byte[] raw_response = json.toString() - .getBytes(); - t.sendResponseHeaders(200, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - rateLimiter.ensureWhitelisted( - t.getRemoteAddress() - .getAddress()); - return; - } - } - - Map GET_PARAMS = HTTPUtils.parseQueryString( - t.getRequestURI() - .getQuery()); - - if (GET_PARAMS.containsKey("revoke")) { - List auth = t.getRequestHeaders() - .get("Authorization"); - if (auth != null && !auth.isEmpty()) { - String token = auth.get(0); - token = token.replace("Bearer ", ""); - validTokens.remove(token); - t.sendResponseHeaders(200, -1); - return; - } - } - - t.sendResponseHeaders(400, -1); - } - - } - - static class WebHandler implements HttpHandler { - - @Override - public void handle(HttpExchange t) throws IOException { - - if (!rateLimiter.isAllowed( - t.getRemoteAddress() - .getAddress())) { - byte[] raw_response = "Too Many Requests".getBytes(); - t.getResponseHeaders() - .add("Content-Type", "text/plain"); - t.sendResponseHeaders(429, raw_response.length); // Too Many Requests - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - return; - } - - String path = t.getRequestURI() - .getPath(); - - if (path.equals("/favicon.ico")) { - t.getResponseHeaders() - .set("Content-Type", "image/x-icon"); - try (InputStream is = AE2Controller.class.getResourceAsStream("/assets/favicon.ico")) { - if (is == null) return; - - byte[] raw_response = IOUtils.toByteArray(is); - is.read(raw_response); - t.sendResponseHeaders(200, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - } - return; - } - - // only accept index file - if (!path.equals("/") && !path.isEmpty() - && !path.equals("/index.php") - && !path.equals("/index.html") - && !path.equals("/index.htm") - && !path.equals("/index.asp") - && !path.equals("/index.aspx") - && !path.equals("/index.jsp")) { - - String response = "

Invalid url! (ERROR 404)

"; - byte[] raw_response = response.getBytes(); - t.sendResponseHeaders(404, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - return; - } - - String site = "/assets/webpage.html"; - - if (!checkAuth(t)) { - site = "/assets/login.html"; - } - - String response; - try (InputStream is = AE2Controller.class.getResourceAsStream(site)) { - if (is == null) return; - try (InputStreamReader isr = new InputStreamReader(is); - BufferedReader reader = new BufferedReader(isr)) { - response = reader.lines() - .collect(Collectors.joining(System.lineSeparator())); - } - } - response = response.replace("_REPLACE_ME_IS_PUBLIC_MODE", Config.AE_PUBLIC_MODE ? "true" : "false"); - response = response.replace( - "_REPLACE_ME_VERSION_OUTDATED", - Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated() ? "true" : "false"); - RequestContext context = requestContext.get(); - if (context != null) { - response = response.replace("_REPLACE_ME_USERNAME", context.username); - response = response.replace("_REPLACE_ME_IS_ADMIN", context.isAdmin() ? "true" : "false"); - } - byte[] raw_response = response.getBytes(); - t.sendResponseHeaders(200, raw_response.length); - OutputStream os = t.getResponseBody(); - os.write(raw_response); - os.close(); - } - - } - - public static void init() { - try { - startHTTPServer(); - } catch (Exception e) { - throw new RuntimeException(e); - } - - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2JobTracker.java b/src/main/java/pl/kuba6000/ae2webintegration/core/AE2JobTracker.java deleted file mode 100644 index 892e4b7..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/AE2JobTracker.java +++ /dev/null @@ -1,239 +0,0 @@ -package pl.kuba6000.ae2webintegration.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.commons.lang3.tuple.Pair; - -import pl.kuba6000.ae2webintegration.core.api.DimensionalCoords; -import pl.kuba6000.ae2webintegration.core.discord.DiscordManager; -import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingPatternDetails; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IPatternProviderViewable; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAESecurityGrid; - -public class AE2JobTracker { - - public static class AEInterface { - - public String name; - public HashSet location = new HashSet<>(); - - AEInterface(String name) { - this.name = name; - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof AEInterface)) return false; - return ((AEInterface) obj).name.equals(this.name); - } - } - - public static class JobTrackingInfo { - - public IStack finalOutput; - public long timeStarted; - public long timeDone; - public HashMap timeSpentOn = new HashMap<>(); - public HashMap startedWaitingFor = new HashMap<>(); - public HashMap craftedTotal = new HashMap<>(); - public HashMap waitingFor = new HashMap<>(); - public HashMap>> itemShare = new HashMap<>(); - public HashMap>> interfaceShare = new HashMap<>(); - public HashMap interfaceStarted = new HashMap<>(); - public HashMap interfaceLookup = new HashMap<>(); - public HashMap> interfaceWaitingFor = new HashMap<>(); - public HashMap>> interfaceWaitingForLookup = new HashMap<>(); - public boolean isDone = false; - public boolean wasCancelled = false; - - public long getTimeSpentOn(IStack stack) { - Long time = timeSpentOn.get(stack); - if (time == null) return 0L; - Long additionalTime = startedWaitingFor.get(stack); - if (additionalTime != null) { - time += System.currentTimeMillis() - additionalTime; - } - return time; - } - - public double getShareInCraftingTime(IStack stack) { - long total = 0L; - long stackTime = 0L; - for (IStack itemStack : timeSpentOn.keySet()) { - long timeSpent = getTimeSpentOn(itemStack); - total += timeSpent; - if (stack.web$isSameType(itemStack)) { - stackTime = timeSpent; - } - } - if (total == 0L) return 1d; - return (double) stackTime / (double) total; - } - } - - public static IdentityHashMap trackingInfoMap = new IdentityHashMap<>(); - public ConcurrentHashMap trackingInfos = new ConcurrentHashMap<>(); - - private int nextFreeTrackingInfoID = 1; - - public static void addJob(ICraftingCPUCluster cpuCluster, IAECraftingGrid cache, IAEGrid grid, boolean isMerging) { - GridData gridData = GridData.get(grid); - if (gridData == null || !gridData.isTracked) return; // We don't track this grid, so we don't track jobs on it - JobTrackingInfo info; - if (isMerging) { - info = trackingInfoMap.get(cpuCluster); - if (info == null) return; // We can't start tracking mid crafting :P - } else { - trackingInfoMap.put(cpuCluster, info = new JobTrackingInfo()); - info.timeStarted = System.currentTimeMillis(); - } - info.finalOutput = cpuCluster.web$getFinalOutput() - .web$copy(); - } - - public static void updateCraftingStatus(ICraftingCPUCluster cpu, IStack diff) { - JobTrackingInfo info = trackingInfoMap.get(cpu); - if (info == null) return; - IItemList waitingFor = cpu.web$getWaitingFor(); - IStack found = waitingFor.web$findPrecise(diff); - if (found != null && found.web$getStackSize() > 0L) { - if (!info.startedWaitingFor.containsKey(found)) { - info.startedWaitingFor.put(found, System.currentTimeMillis()); - info.timeSpentOn.putIfAbsent(found, 0L); - info.waitingFor.put(found, found.web$getStackSize()); - } else { - long i = info.waitingFor.get(found); - long newi = found.web$getStackSize(); - if (i > newi) { - info.craftedTotal.merge(found, i - newi, Long::sum); - } - info.waitingFor.put(found, newi); - } - } else { - if (info.startedWaitingFor.containsKey(diff)) { - long started = info.startedWaitingFor.remove(diff); - long ended = System.currentTimeMillis(); - long elapsed = ended - started; - long endedReal = System.currentTimeMillis(); - info.timeSpentOn.merge(diff, elapsed, Long::sum); - info.craftedTotal.merge(diff, info.waitingFor.remove(diff), Long::sum); - info.itemShare.computeIfAbsent(diff, k -> new ArrayList<>()) - .add(Pair.of(started, endedReal)); - if (info.interfaceWaitingForLookup.containsKey(diff)) { - for (Map.Entry> entry : info.interfaceWaitingForLookup.get(diff) - .entrySet()) { - AEInterface aeInterface = entry.getKey(); - HashSet itemList = entry.getValue(); - itemList.remove(diff); - if (itemList.isEmpty()) { - info.interfaceWaitingFor.remove(aeInterface); - long interfaceStarted = info.interfaceStarted.remove(aeInterface); - info.interfaceShare.computeIfAbsent(aeInterface, k -> new ArrayList<>()) - .add(Pair.of(interfaceStarted, endedReal)); - } - } - info.interfaceWaitingForLookup.remove(diff); - } - } - } - } - - public static void pushedPattern(ICraftingCPUCluster cpu, IPatternProviderViewable provider, - IAECraftingPatternDetails details) { - JobTrackingInfo info = trackingInfoMap.get(cpu); - if (info == null) return; - if (provider != null) { - String name = provider.web$getName(); - if (name == null) name = "[NULL]"; - final AEInterface aeInterfaceToLookup = new AEInterface(name); - final AEInterface aeInterface = info.interfaceLookup - .computeIfAbsent(aeInterfaceToLookup, k -> aeInterfaceToLookup); - aeInterface.location.add(provider.web$getLocation()); - info.interfaceStarted.computeIfAbsent(aeInterface, k -> System.currentTimeMillis()); - final HashSet itemList = info.interfaceWaitingFor - .computeIfAbsent(aeInterface, k -> new HashSet<>()); - - for (IStack out : details.web$getCondensedOutputs()) { - info.interfaceWaitingForLookup.computeIfAbsent(out, k -> new HashMap<>()) - .putIfAbsent(aeInterface, itemList); - itemList.add(out); - } - } - } - - public static void completeCrafting(IAEGrid grid, ICraftingCPUCluster cpu) { - JobTrackingInfo info = trackingInfoMap.remove(cpu); - if (info == null) return; - GridData gridData = GridData.get(grid); - if (gridData == null || !gridData.isTracked) return; // We don't track this grid, so we don't track jobs on it - for (Map.Entry entry : info.waitingFor.entrySet()) { - info.craftedTotal.merge(entry.getKey(), entry.getValue(), Long::sum); - } - info.waitingFor.clear(); - final long now = System.currentTimeMillis(); - for (Map.Entry entry : info.startedWaitingFor.entrySet()) { - info.timeSpentOn.merge(entry.getKey(), now - entry.getValue(), Long::sum); - info.itemShare.computeIfAbsent(entry.getKey(), k -> new ArrayList<>()) - .add(Pair.of(entry.getValue(), now)); - } - for (Map.Entry entry : info.interfaceStarted.entrySet()) { - info.interfaceShare.computeIfAbsent(entry.getKey(), k -> new ArrayList<>()) - .add(Pair.of(entry.getValue(), now)); - } - info.interfaceStarted.clear(); - info.interfaceWaitingFor.clear(); - info.interfaceWaitingForLookup.clear(); - info.interfaceLookup.clear(); - info.startedWaitingFor.clear(); - info.isDone = true; - info.timeDone = System.currentTimeMillis(); - gridData.trackingInfo.trackingInfos.put(gridData.trackingInfo.nextFreeTrackingInfoID++, info); - double took = info.timeDone - info.timeStarted; - took /= 1000d; - if (!Config.AE_PUBLIC_MODE && !Config.DISCORD_WEBHOOK.isEmpty()) { - IAESecurityGrid securityGrid = grid.web$getSecurityGrid(); - if (securityGrid != null && securityGrid.web$isAvailable()) { - IAECraftingGrid craftingGrid = grid.web$getCraftingGrid(); - craftingGrid.web$getCPUs(); // make sure the cpu has id - DiscordManager.postMessageNonBlocking( - new DiscordManager.DiscordEmbed( - "AE2 Job Tracker [ Grid " + securityGrid.web$getSecurityKey() - + " ][ " - + cpu.web$getName() - + " ]", - "Crafting for `" + info.finalOutput.web$getDisplayName() - + " x" - + info.finalOutput.web$getStackSize() - + "` " - + (info.wasCancelled ? "cancelled" : "completed") - + "!\nIt took " - + took - + "s", - info.wasCancelled ? 15548997 : 5763719)); - } - } - } - - public static void cancelCrafting(IAEGrid grid, ICraftingCPUCluster cpu) { - JobTrackingInfo info = trackingInfoMap.get(cpu); - if (info == null) return; - info.wasCancelled = true; - completeCrafting(grid, cpu); - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/AEMixinCallbacks.java b/src/main/java/pl/kuba6000/ae2webintegration/core/AEMixinCallbacks.java deleted file mode 100644 index 15001cd..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/AEMixinCallbacks.java +++ /dev/null @@ -1,44 +0,0 @@ -package pl.kuba6000.ae2webintegration.core; - -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.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IPatternProviderViewable; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; - -public class AEMixinCallbacks implements IAEMixinCallbacks { - - public static AEMixinCallbacks INSTANCE = new AEMixinCallbacks(); - - @Override - public void jobStarted(ICraftingCPUCluster cpuCluster, IAECraftingGrid cache, IAEGrid grid, boolean isMerging, - boolean isAuthorPlayer) { - if (!Config.TRACKING_TRACK_MACHINE_CRAFTING && !isAuthorPlayer) { - return; - } - AE2JobTracker.addJob(cpuCluster, cache, grid, isMerging); - } - - @Override - public void craftingStatusPostedUpdate(ICraftingCPUCluster cpu, IStack diff) { - AE2JobTracker.updateCraftingStatus(cpu, diff); - } - - @Override - public void pushedPattern(ICraftingCPUCluster cpu, IPatternProviderViewable provider, - IAECraftingPatternDetails details) { - AE2JobTracker.pushedPattern(cpu, provider, details); - } - - @Override - public void jobCompleted(IAEGrid grid, ICraftingCPUCluster cpu) { - AE2JobTracker.completeCrafting(grid, cpu); - } - - @Override - public void jobCancelled(IAEGrid grid, ICraftingCPUCluster cpu) { - AE2JobTracker.cancelCrafting(grid, cpu); - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/AEWebAPI.java b/src/main/java/pl/kuba6000/ae2webintegration/core/AEWebAPI.java deleted file mode 100644 index 0e6f1c5..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/AEWebAPI.java +++ /dev/null @@ -1,21 +0,0 @@ -package pl.kuba6000.ae2webintegration.core; - -import com.mojang.authlib.GameProfile; - -import pl.kuba6000.ae2webintegration.core.api.IAEWebInterface; -import pl.kuba6000.ae2webintegration.core.interfaces.IAE; - -public class AEWebAPI implements IAEWebInterface { - - public static final AEWebAPI INSTANCE = new AEWebAPI(); - - @Override - public GameProfile getAEWebGameProfile() { - return AE2Controller.AEControllerProfile; - } - - @Override - public void initAEInterface(IAE ae) { - AE2Controller.AE2Interface = ae; - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/Config.java b/src/main/java/pl/kuba6000/ae2webintegration/core/Config.java deleted file mode 100644 index d87b40b..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/Config.java +++ /dev/null @@ -1,32 +0,0 @@ -package pl.kuba6000.ae2webintegration.core; - -import java.io.File; -import java.util.Random; - -public class Config { - - public static String AE_PASSWORD = new Random().ints(48, 122 + 1) - .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)) - .limit(16) - .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) - .toString(); - public static int AE_PORT = 2324; - public static boolean ALLOW_NO_PASSWORD_ON_LOCALHOST = true; - public static boolean AE_PUBLIC_MODE = true; - public static int AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE = 20; - - // discord - public static String DISCORD_WEBHOOK = ""; - public static String DISCORD_ROLE_ID = ""; - - // tracking - // TODO: Add more customization options (order time, size, item type ? etc.) - public static boolean TRACKING_TRACK_MACHINE_CRAFTING = false; - - // updates - public static boolean CHECK_FOR_UPDATES = true; - - public static File getConfigFile(String fileName) { - return new File(WebEngine.getPlatform().getConfigDirectory(), fileName); - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/GridData.java b/src/main/java/pl/kuba6000/ae2webintegration/core/GridData.java deleted file mode 100644 index 678db2f..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/GridData.java +++ /dev/null @@ -1,115 +0,0 @@ -package pl.kuba6000.ae2webintegration.core; - -import static pl.kuba6000.ae2webintegration.forge.AE2WebIntegrationCore.LOG; - -import java.io.File; -import java.io.Reader; -import java.io.Writer; -import java.lang.reflect.Type; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Future; - -import com.google.common.io.Files; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - -import pl.kuba6000.ae2webintegration.core.api.AEApi.AEControllerState; -import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEPathingGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAESecurityGrid; -import pl.kuba6000.ae2webintegration.core.utils.GSONUtils; - -public class GridData { - - @GSONUtils.SkipGSON - private static final File dataFile = Config.getConfigFile("griddata.json"); - - @GSONUtils.SkipGSON - private static ConcurrentHashMap gridDataMap = new ConcurrentHashMap<>(); - - public boolean isTracked = false; - - @GSONUtils.SkipGSON - public AE2JobTracker trackingInfo = new AE2JobTracker(); - - @GSONUtils.SkipGSON - private int nextJobID = 1; - - private int getNextJobID() { - return nextJobID++; - } - - @GSONUtils.SkipGSON - public HashMap> jobs = new HashMap<>(); - - public int addJob(Future job) { - int jobID = getNextJobID(); - jobs.put(jobID, job); - return jobID; - } - - public static GridData get(long gridKey) { - return gridDataMap.computeIfAbsent(gridKey, k -> new GridData()); - } - - public static GridData get(IAEGrid grid) { - IAEPathingGrid pathing = grid.web$getPathingGrid(); - if (pathing == null || pathing.web$isNetworkBooting() - || pathing.web$getControllerState() != AEControllerState.CONTROLLER_ONLINE) { - return null; - } - IAESecurityGrid security = grid.web$getSecurityGrid(); - if (security == null || !security.web$isAvailable()) { - return null; - } - long gridKey = security.web$getSecurityKey(); - if (gridKey == -1) { - return null; - } - return gridDataMap.computeIfAbsent(gridKey, k -> new GridData()); - } - - public static void saveChanges() { - Gson gson = GSONUtils.GSON_BUILDER.create(); - Writer writer = null; - try { - writer = Files.newWriter(dataFile, StandardCharsets.UTF_8); - gson.toJson(gridDataMap, writer); - writer.flush(); - writer.close(); - } catch (Exception e) { - e.printStackTrace(); - } finally { - if (writer != null) try { - writer.close(); - } catch (Exception ignored) {} - } - } - - public static void loadData() { - Gson gson = GSONUtils.GSON_BUILDER.create(); - if (!dataFile.exists()) { - LOG.info("Grid data file not found, creating a new one."); - saveChanges(); - return; - } - Reader reader = null; - try { - reader = Files.newReader(dataFile, StandardCharsets.UTF_8); - Type type = new TypeToken>() {}.getType(); - gridDataMap = gson.fromJson(reader, type); - } catch (Exception e) { - LOG.error("Failed to load web data from file: {}", dataFile.getAbsolutePath(), e); - gridDataMap.clear(); - saveChanges(); - } finally { - if (reader != null) try { - reader.close(); - } catch (Exception ignored) {} - } - - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/PasswordHelper.java b/src/main/java/pl/kuba6000/ae2webintegration/core/PasswordHelper.java deleted file mode 100644 index b3224b3..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/PasswordHelper.java +++ /dev/null @@ -1,76 +0,0 @@ -package pl.kuba6000.ae2webintegration.core; - -import java.math.BigInteger; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.spec.InvalidKeySpecException; - -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; - -public class PasswordHelper { - - private static final int ITERATIONS = 65536; - private static final int HASH_LENGTH = 512; // Length of the hash in bytes - - public static String generateStrongPasswordHash(String password) - throws NoSuchAlgorithmException, InvalidKeySpecException { - char[] chars = password.toCharArray(); - byte[] salt = getSalt(); - - PBEKeySpec spec = new PBEKeySpec(chars, salt, ITERATIONS, HASH_LENGTH); - SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); - - byte[] hash = skf.generateSecret(spec) - .getEncoded(); - return ITERATIONS + ":" + toHex(salt) + ":" + toHex(hash); - } - - private static byte[] getSalt() throws NoSuchAlgorithmException { - SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); - byte[] salt = new byte[16]; - sr.nextBytes(salt); - return salt; - } - - private static String toHex(byte[] array) throws NoSuchAlgorithmException { - BigInteger bi = new BigInteger(1, array); - String hex = bi.toString(16); - - int paddingLength = (array.length * 2) - hex.length(); - if (paddingLength > 0) { - return String.format("%0" + paddingLength + "d", 0) + hex; - } else { - return hex; - } - } - - public static boolean validatePassword(String originalPassword, String storedPassword) - throws NoSuchAlgorithmException, InvalidKeySpecException { - String[] parts = storedPassword.split(":"); - int iterations = Integer.parseInt(parts[0]); - - byte[] salt = fromHex(parts[1]); - byte[] hash = fromHex(parts[2]); - - PBEKeySpec spec = new PBEKeySpec(originalPassword.toCharArray(), salt, iterations, hash.length * 8); - SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); - byte[] testHash = skf.generateSecret(spec) - .getEncoded(); - - int diff = hash.length ^ testHash.length; - for (int i = 0; i < hash.length && i < testHash.length; i++) { - diff |= hash[i] ^ testHash[i]; - } - return diff == 0; - } - - private static byte[] fromHex(String hex) throws NoSuchAlgorithmException { - byte[] bytes = new byte[hex.length() / 2]; - for (int i = 0; i < bytes.length; i++) { - bytes[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16); - } - return bytes; - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/WebData.java b/src/main/java/pl/kuba6000/ae2webintegration/core/WebData.java deleted file mode 100644 index 9c94b0d..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/WebData.java +++ /dev/null @@ -1,121 +0,0 @@ -package pl.kuba6000.ae2webintegration.core; - -import static pl.kuba6000.ae2webintegration.forge.AE2WebIntegrationCore.LOG; - -import java.io.File; -import java.io.Reader; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.UUID; - -import com.google.common.io.Files; -import com.google.gson.Gson; - -import pl.kuba6000.ae2webintegration.core.utils.GSONUtils; - -public class WebData { - - static WebData instance = new WebData(); - - private static final File dataFile = Config.getConfigFile("webdata.json"); - - private HashMap UUIDToId = new HashMap<>(); - private HashMap IdToUUID = new HashMap<>(); - private HashMap passwords = new HashMap<>(); - - public static int getPlayerId(String name) { - if (name == null || name.isEmpty()) { - return -1; - } - UUID uuid = WebEngine.getPlatform() - .getOfflinePlayerUUID(name); - if (uuid == null) { - return -1; - } - Integer id = instance.UUIDToId.get(uuid); - if (id != null) { - return id; - } - - return -1; - } - - public static boolean verifyPassword(int playerId, String password) { - UUID id = instance.IdToUUID.get(playerId); - if (id == null) { - LOG.warn("Player ID {} not found in IdToUUID map.", playerId); - return false; - } - if (instance.passwords.containsKey(id)) { - try { - return PasswordHelper.validatePassword(password, instance.passwords.get(id)); - } catch (Exception e) { - LOG.error("Password verification failed for player ID: {}", playerId, e); - return false; - } - } - - return false; - } - - public static void setPassword(UUID playerId, String passwordHash) { - if (passwordHash == null || passwordHash.isEmpty()) { - instance.passwords.remove(playerId); - } else { - try { - instance.passwords.put(playerId, passwordHash); - int pID = AE2Controller.AE2Interface.web$getPlayerData() - .web$getPlayerId(playerId); - instance.UUIDToId.put(playerId, pID); - instance.IdToUUID.put(pID, playerId); - } catch (Exception e) { - LOG.error("Failed to set password for player ID: {}", playerId, e); - } - } - saveChanges(); - } - - private static void saveChanges() { - Gson gson = GSONUtils.GSON_BUILDER.create(); - Writer writer = null; - try { - writer = Files.newWriter(dataFile, StandardCharsets.UTF_8); - gson.toJson(instance, writer); - writer.flush(); - writer.close(); - } catch (Exception e) { - e.printStackTrace(); - } finally { - if (writer != null) try { - writer.close(); - } catch (Exception ignored) {} - } - } - - public static void loadData() { - Gson gson = GSONUtils.GSON_BUILDER.create(); - if (!dataFile.exists()) { - LOG.info("Web data file not found, creating a new one."); - saveChanges(); - return; - } - Reader reader = null; - try { - reader = Files.newReader(dataFile, StandardCharsets.UTF_8); - instance = gson.fromJson(reader, WebData.class); - } catch (Exception e) { - LOG.error("Failed to load web data from file: {}", dataFile.getAbsolutePath(), e); - instance.UUIDToId.clear(); - instance.IdToUUID.clear(); - instance.passwords.clear(); - saveChanges(); - } finally { - if (reader != null) try { - reader.close(); - } catch (Exception ignored) {} - } - - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/WebEngine.java b/src/main/java/pl/kuba6000/ae2webintegration/core/WebEngine.java deleted file mode 100644 index 318b273..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/WebEngine.java +++ /dev/null @@ -1,16 +0,0 @@ -package pl.kuba6000.ae2webintegration.core; - -import pl.kuba6000.ae2webintegration.core.api.IServerPlatform; - -public class WebEngine { - - private static IServerPlatform platform; - - public static void init(IServerPlatform platformImpl) { - platform = platformImpl; - } - - public static IServerPlatform getPlatform() { - return platform; - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/IRequest.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/IRequest.java deleted file mode 100644 index 07f7a9e..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/IRequest.java +++ /dev/null @@ -1,57 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request; - -import java.util.concurrent.atomic.AtomicBoolean; - -import com.google.gson.GsonBuilder; - -import pl.kuba6000.ae2webintegration.core.AE2Controller; -import pl.kuba6000.ae2webintegration.core.utils.GSONUtils; - -public abstract class IRequest { - - protected static GsonBuilder JSONBuilder = GSONUtils.GSON_BUILDER; - - private static class JSON_Structure { - - String status; - Object data; - } - - public AtomicBoolean isDone = new AtomicBoolean(false); - protected String status = "TIMEOUT"; - protected Object data = null; - - abstract public void handle(AE2Controller.RequestContext context); - - Object getData() { - return data; - } - - protected void setData(Object data) { - this.data = data; - } - - public String getJSON() { - JSON_Structure structure = new JSON_Structure(); - structure.status = status; - structure.data = getData(); - return JSONBuilder.create() - .toJson(structure); - } - - public void done() { - this.status = "OK"; - this.isDone.set(true); - } - - public void deny(String status) { - this.status = status; - this.isDone.set(true); - } - - public void noParam(String... params) { - deny("NO_PARAM"); - setData(params); - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTracking.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTracking.java deleted file mode 100644 index 0e9f3d6..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTracking.java +++ /dev/null @@ -1,32 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.async; - -import java.util.Map; - -import pl.kuba6000.ae2webintegration.core.AE2JobTracker; -import pl.kuba6000.ae2webintegration.core.api.JSON_CompactedJobTrackingInfo; - -public class GetTracking extends IAsyncRequest { - - @Override - public void handle(Map getParams) { - if (grid == null) { - deny("GRID_NOT_FOUND"); - return; - } - if (!getParams.containsKey("id")) { - noParam("id"); - return; - } - int id = Integer.parseInt(getParams.get("id")); - - AE2JobTracker.JobTrackingInfo info = grid.trackingInfo.trackingInfos.get(id); - if (info == null) { - deny("TRACKING_NOT_FOUND"); - return; - } - - setData(new JSON_CompactedJobTrackingInfo(info)); - done(); - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTrackingHistory.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTrackingHistory.java deleted file mode 100644 index 0743cc7..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GetTrackingHistory.java +++ /dev/null @@ -1,45 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.async; - -import java.util.ArrayList; -import java.util.Map; - -import pl.kuba6000.ae2webintegration.core.AE2JobTracker; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; - -public class GetTrackingHistory extends IAsyncRequest { - - private static class JSON_TrackingHistoryElement { - - public long timeStarted; - public long timeDone; - public boolean wasCancelled; - public IStack finalOutput; - public int id; - } - - @Override - public void handle(Map getParams) { - if (grid == null) { - deny("GRID_NOT_FOUND"); - return; - } - ArrayList jobs = new ArrayList<>(grid.trackingInfo.trackingInfos.size()); - - for (Map.Entry integerJobTrackingInfoEntry : grid.trackingInfo.trackingInfos - .entrySet()) { - JSON_TrackingHistoryElement element = new JSON_TrackingHistoryElement(); - element.id = integerJobTrackingInfoEntry.getKey(); - element.timeStarted = integerJobTrackingInfoEntry.getValue().timeStarted; - element.timeDone = integerJobTrackingInfoEntry.getValue().timeDone; - element.wasCancelled = integerJobTrackingInfoEntry.getValue().wasCancelled; - element.finalOutput = integerJobTrackingInfoEntry.getValue().finalOutput; - jobs.add(element); - } - - jobs.sort((i1, i2) -> Long.compare(i2.timeDone, i1.timeDone)); - - setData(jobs); - done(); - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GridSettings.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GridSettings.java deleted file mode 100644 index 944bf97..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/GridSettings.java +++ /dev/null @@ -1,25 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.async; - -import java.util.Map; - -import pl.kuba6000.ae2webintegration.core.GridData; - -public class GridSettings extends IAsyncRequest { - - @Override - public void handle(Map getParams) { - if (grid == null) { - deny("GRID_NOT_FOUND"); - return; - } - - if (getParams.containsKey("track")) { - grid.isTracked = getParams.get("track") - .equals("1"); - GridData.saveChanges(); - } - - setData(grid); - done(); - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/IAsyncRequest.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/IAsyncRequest.java deleted file mode 100644 index 26f8e21..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/async/IAsyncRequest.java +++ /dev/null @@ -1,29 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.async; - -import java.util.Map; - -import pl.kuba6000.ae2webintegration.core.AE2Controller; -import pl.kuba6000.ae2webintegration.core.GridData; -import pl.kuba6000.ae2webintegration.core.ae2request.IRequest; - -public abstract class IAsyncRequest extends IRequest { - - protected AE2Controller.RequestContext context = null; - protected long gridKey = -1; - protected GridData grid = null; - - public void handle(Map getParams) {}; - - @Override - public void handle(AE2Controller.RequestContext context) { - this.context = context; - String gridstr = context.getGetParams() - .get("grid"); - if (gridstr == null || gridstr.isEmpty()) gridKey = -1; - else gridKey = Long.parseLong(gridstr); - if (gridKey != -1) { - grid = GridData.get(gridKey); - } - handle(context.getGetParams()); - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/CancelCPU.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/CancelCPU.java deleted file mode 100644 index 4428572..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/CancelCPU.java +++ /dev/null @@ -1,41 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.sync; - -import java.util.Map; - -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; - -public class CancelCPU extends ISyncedRequest { - - private String cpuName; - - @Override - boolean init(Map getParams) { - if (!getParams.containsKey("cpu")) { - noParam("cpu"); - return false; - } - cpuName = getParams.get("cpu"); - return true; - } - - @Override - void handle(IAEGrid grid) { - if (grid == null) { - deny("GRID_NOT_FOUND"); - return; - } - ICraftingCPUCluster cluster = GetCPUList.getCPUList(grid.web$getCraftingGrid()) - .get(cpuName); - if (cluster == null) { - deny("CPU_NOT_FOUND"); - return; - } - if (cluster.web$isBusy()) { - cluster.web$cancel(); - done(); - return; - } - deny("CPU_NOT_BUSY"); - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPU.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPU.java deleted file mode 100644 index f9eaf8a..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPU.java +++ /dev/null @@ -1,119 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.sync; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import pl.kuba6000.ae2webintegration.core.AE2Controller; -import pl.kuba6000.ae2webintegration.core.AE2JobTracker; -import pl.kuba6000.ae2webintegration.core.api.JSON_CompactedItem; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; - -public class GetCPU extends ISyncedRequest { - - private static class JSON_ClusterData { - - public long size; - public boolean isBusy; - public IStack finalOutput; - public ArrayList items; - public boolean hasTrackingInfo = false; - public long timeStarted = 0L; - public long timeElapsed = 0L; - } - - String cpuName = null; - - @Override - boolean init(Map getParams) { - if (!getParams.containsKey("cpu")) { - noParam("cpu"); - return false; - } - cpuName = getParams.get("cpu"); - return true; - } - - @Override - void handle(IAEGrid grid) { - if (grid == null) { - deny("GRID_NOT_FOUND"); - return; - } - IAECraftingGrid craftingGrid = grid.web$getCraftingGrid(); - - ICraftingCPUCluster cpu = GetCPUList.getCPUList(craftingGrid) - .get(cpuName); - if (cpu == null) { - deny("CPU_NOT_FOUND"); - return; - } - - JSON_ClusterData clusterData = new JSON_ClusterData(); - clusterData.size = cpu.web$getAvailableStorage(); - clusterData.isBusy = cpu.web$isBusy(); - if (clusterData.isBusy) { - clusterData.finalOutput = cpu.web$getFinalOutput(); - AE2JobTracker.JobTrackingInfo trackingInfo = AE2JobTracker.trackingInfoMap.get(cpu); - clusterData.hasTrackingInfo = trackingInfo != null; - - HashMap prep = new HashMap<>(); - IItemList items = AE2Controller.AE2Interface.web$createItemList(); - cpu.web$getActiveItems(items); - for (IStack itemStack : items) { - JSON_CompactedItem compactedItem = JSON_CompactedItem.create(itemStack); - prep.computeIfAbsent(compactedItem, k -> compactedItem).active += itemStack.web$getStackSize(); - } - items = AE2Controller.AE2Interface.web$createItemList(); - cpu.web$getPendingItems(items); - for (IStack itemStack : items) { - JSON_CompactedItem compactedItem = JSON_CompactedItem.create(itemStack); - prep.computeIfAbsent(compactedItem, k -> compactedItem).pending += itemStack.web$getStackSize(); - } - items = AE2Controller.AE2Interface.web$createItemList(); - cpu.web$getStorageItems(items); - for (IStack itemStack : items) { - JSON_CompactedItem compactedItem = JSON_CompactedItem.create(itemStack); - prep.computeIfAbsent(compactedItem, k -> compactedItem).stored += itemStack.web$getStackSize(); - } - - if (clusterData.hasTrackingInfo) { - clusterData.timeStarted = trackingInfo.timeStarted; - clusterData.timeElapsed = (System.currentTimeMillis()) - clusterData.timeStarted; - for (IStack stack : trackingInfo.timeSpentOn.keySet()) { - JSON_CompactedItem compactedItem = JSON_CompactedItem.create(stack); - JSON_CompactedItem finalCompactedItem = compactedItem; - compactedItem = prep.computeIfAbsent(compactedItem, k -> finalCompactedItem); - compactedItem.timeSpentCrafting += trackingInfo.getTimeSpentOn(stack); - compactedItem.craftedTotal += trackingInfo.craftedTotal.getOrDefault(stack, 0L); - compactedItem.shareInCraftingTime += trackingInfo.getShareInCraftingTime(stack); - compactedItem.shareInCraftingTimeCombined = Math - .min(((double) compactedItem.timeSpentCrafting) / (double) clusterData.timeElapsed, 1d); - compactedItem.craftsPerSec = (double) compactedItem.craftedTotal - / (compactedItem.timeSpentCrafting / 1000d); - } - } - - clusterData.items = new ArrayList<>(prep.values()); - // TODO Move sorting to javascript! - clusterData.items.sort((i1, i2) -> { - if (i1.active > 0 && i2.active > 0) return Long.compare(i2.active, i1.active); - else if (i1.active > 0 && i2.active == 0) return -1; - else if (i1.active == 0 && i2.active > 0) return 1; - if (i1.pending > 0 && i2.pending > 0) return Long.compare(i2.pending, i1.pending); - else if (i1.pending > 0 && i2.pending == 0) return -1; - else if (i1.pending == 0 && i2.pending > 0) return 1; - return Long.compare(i2.stored, i1.stored); - }); - - } - - setData(clusterData); - done(); - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPUList.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPUList.java deleted file mode 100644 index e3af3cd..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetCPUList.java +++ /dev/null @@ -1,66 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.sync; - -import java.util.LinkedHashMap; -import java.util.Map; - -import pl.kuba6000.ae2webintegration.core.AE2JobTracker; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; - -public class GetCPUList extends ISyncedRequest { - - private static class JSON_CpuInfo { - - public boolean isBusy; - public IStack finalOutput; - public long availableStorage; - public long usedStorage; - public long coProcessors; - public boolean hasTrackingInfo = false; - public long timeStarted = 0L; - } - - public static Map getCPUList(IAECraftingGrid craftingGrid) { - LinkedHashMap orderedMap = new LinkedHashMap<>(); - for (ICraftingCPUCluster cpu : craftingGrid.web$getCPUs()) { - String name = cpu.web$getName(); - orderedMap.put(name, cpu); - } - return orderedMap; - } - - @Override - boolean init(Map getParams) { - return true; - } - - @Override - void handle(IAEGrid grid) { - if (grid == null) { - deny("GRID_NOT_FOUND"); - return; - } - Map clusters = getCPUList(grid.web$getCraftingGrid()); - LinkedHashMap cpuList = new LinkedHashMap<>(clusters.size()); - for (Map.Entry entry : clusters.entrySet()) { - JSON_CpuInfo cpuInfo = new JSON_CpuInfo(); - ICraftingCPUCluster cluster = entry.getValue(); - cpuInfo.availableStorage = cluster.web$getAvailableStorage(); - cpuInfo.usedStorage = cluster.web$getUsedStorage(); - cpuInfo.coProcessors = cluster.web$getCoProcessors(); - if (cpuInfo.isBusy = cluster.web$isBusy()) { - cpuInfo.finalOutput = cluster.web$getFinalOutput(); - AE2JobTracker.JobTrackingInfo trackingInfo = AE2JobTracker.trackingInfoMap.get(cluster); - if (cpuInfo.hasTrackingInfo = trackingInfo != null) { - cpuInfo.timeStarted = trackingInfo.timeStarted; - } - } - cpuList.put(entry.getKey(), cpuInfo); - } - setData(cpuList); - done(); - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetGridList.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetGridList.java deleted file mode 100644 index 770e35d..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetGridList.java +++ /dev/null @@ -1,90 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.sync; - -import java.util.ArrayList; - - - -import pl.kuba6000.ae2webintegration.core.GridData; -import pl.kuba6000.ae2webintegration.core.api.AEApi.AEControllerState; -import pl.kuba6000.ae2webintegration.core.interfaces.IAE; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEPathingGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAESecurityGrid; - -public class GetGridList extends ISyncedRequest { - - private static class JSON_GridData { - - JSON_GridData(long key, int cpuCount, String owner, boolean isOwned, boolean isTrackingEnabled) { - this.key = key; - this.cpuCount = cpuCount; - this.owner = owner; - this.isOwned = isOwned; - this.isTrackingEnabled = isTrackingEnabled; - } - - public long key; // key == -1 -> not attachable - public int cpuCount; - public String owner; - public boolean isOwned; - public boolean isTrackingEnabled = false; - } - - @Override - public void handle(IAE ae) { - ArrayList grids = new ArrayList<>(); - for (IAEGrid grid : ae.web$getGrids()) { - IAEPathingGrid pathing = grid.web$getPathingGrid(); - if (pathing == null || pathing.web$isNetworkBooting() - || pathing.web$getControllerState() != AEControllerState.CONTROLLER_ONLINE) { - continue; - } - IAESecurityGrid security = grid.web$getSecurityGrid(); - if (security == null || !security.web$isAvailable() || security.web$getSecurityKey() == -1) { - if (context.isAdmin()) { - grids.add( - new JSON_GridData( - -1, - grid.web$getCraftingGrid() - .web$getCPUCount(), - "N/A", - false, - false)); - } - continue; - } - if (!context.isAdmin() && !security.web$hasPermissions(context.getUserID())) { - continue; - } - pl.kuba6000.ae2webintegration.core.api.PlayerProfile gameProfile = security.web$getOwnerProfile(); - GridData gridData = GridData.get(security.web$getSecurityKey()); - grids.add( - new JSON_GridData( - security.web$getSecurityKey(), - grid.web$getCraftingGrid() - .web$getCPUCount(), - gameProfile == null ? "N/A" : gameProfile.getName(), - security.web$hasPermissions(context.getUserID()), - gridData.isTracked)); - } - grids.sort((d1, d2) -> { - if (d1.isOwned && !d2.isOwned) { - return -1; - } else if (!d1.isOwned && d2.isOwned) { - return 1; - } else if (d1.isTrackingEnabled && !d2.isTrackingEnabled) { - return -1; - } else if (!d1.isTrackingEnabled && d2.isTrackingEnabled) { - return 1; - } else if (d1.key == -1 && d2.key != -1) { - return 1; // unattached grids go to the end - } else if (d1.key != -1 && d2.key == -1) { - return -1; // attached grids come first - } else { - return Integer.compare(d2.cpuCount, d1.cpuCount); // sort by cpu count if all else is equal - } - }); - setData(grids); - done(); - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java deleted file mode 100644 index 04ee14b..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/GetItems.java +++ /dev/null @@ -1,53 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.sync; - -import java.util.ArrayList; -import java.util.Map; - -import pl.kuba6000.ae2webintegration.core.AE2Controller; -import pl.kuba6000.ae2webintegration.core.api.JSON_DetailedItem; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEStorageGrid; - -public class GetItems extends ISyncedRequest { - - @Override - boolean init(Map getParams) { - return true; - } - - @Override - void handle(IAEGrid grid) { - if (grid == null) { - deny("GRID_NOT_FOUND"); - return; - } - IAEStorageGrid storageGrid = grid.web$getStorageGrid(); - IItemList storageList = storageGrid.web$getItemStorageList(); - IItemList fluidStorageList = storageGrid.web$getFluidStorageList(); - AE2Controller.hashcodeToAEItemStack.clear(); - ArrayList items = new ArrayList<>(); - processItemList(storageList, items); - processItemList(fluidStorageList, items); - setData(items); - done(); - } - - private void processItemList(IItemList itemList, ArrayList items) { - for (IStack stack : itemList) { - int hash = stack.hashCode(); - AE2Controller.hashcodeToAEItemStack.put(hash, stack); - - JSON_DetailedItem detailedItem = new JSON_DetailedItem(); - detailedItem.itemid = stack.web$getItemID(); - detailedItem.itemname = stack.web$getDisplayName(); - detailedItem.quantity = stack.web$getStackSize(); - detailedItem.craftable = stack.web$isCraftable(); - detailedItem.hashcode = hash; - - items.add(detailedItem); - } - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/ISyncedRequest.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/ISyncedRequest.java deleted file mode 100644 index b165dec..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/ISyncedRequest.java +++ /dev/null @@ -1,65 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.sync; - -import java.util.Map; - -import pl.kuba6000.ae2webintegration.core.AE2Controller; -import pl.kuba6000.ae2webintegration.core.GridData; -import pl.kuba6000.ae2webintegration.core.ae2request.IRequest; -import pl.kuba6000.ae2webintegration.core.api.AEApi.AEControllerState; -import pl.kuba6000.ae2webintegration.core.interfaces.IAE; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEPathingGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAESecurityGrid; - -public abstract class ISyncedRequest extends IRequest { - - protected AE2Controller.RequestContext context = null; - protected long gridKey = -1; - protected IAEGrid grid = null; - protected GridData gridData = null; - - boolean init(Map getParams) { - return true; - } - - public boolean init(AE2Controller.RequestContext context) { - this.context = context; - String gridstr = context.getGetParams() - .get("grid"); - if (gridstr == null || gridstr.isEmpty()) gridKey = -1; - else gridKey = Long.parseLong(gridstr); - return init(context.getGetParams()); - } - - void handle(IAEGrid grid) {} - - public void handle(IAE ae) { - if (gridKey != -1) { - for (IAEGrid grid : ae.web$getGrids()) { - IAEPathingGrid pathing = grid.web$getPathingGrid(); - if (pathing == null || pathing.web$isNetworkBooting() - || pathing.web$getControllerState() != AEControllerState.CONTROLLER_ONLINE) { - continue; - } - IAESecurityGrid security = grid.web$getSecurityGrid(); - if (security == null || !security.web$isAvailable()) { - continue; - } - if (gridKey == security.web$getSecurityKey()) { - if (!context.isAdmin() && !security.web$hasPermissions(context.getUserID())) { - deny("NO_PERMISSIONS"); - return; - } - this.grid = grid; - } - } - } - if (grid != null) gridData = GridData.get(gridKey); - handle(grid); - } - - @Override - public void handle(AE2Controller.RequestContext context) { - throw new IllegalArgumentException("ONLY SYNCED"); - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java deleted file mode 100644 index 511a26d..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Job.java +++ /dev/null @@ -1,174 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.sync; - -import java.util.ArrayList; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - - -import pl.kuba6000.ae2webintegration.core.AE2Controller; -import pl.kuba6000.ae2webintegration.core.api.AEApi.AEActionable; -import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEMeInventoryItem; -import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEStorageGrid; - -public class Job extends ISyncedRequest { - - private static class JSON_JobData { - - boolean isDone; - public boolean isSimulating; - public long bytesTotal; - public ArrayList plan; - - public static class JobItem { - - public String itemid; - public String itemname; - public long stored; - public long requested; - public long missing; - public long steps; - public double usedPercent; - } - } - - private enum ERequestType { - CHECK, - CANCEL, - SUBMIT - } - - private ERequestType type = null; - private int jobID; - private String cpuName; - - @Override - boolean init(Map getParams) { - if (!getParams.containsKey("id")) { - noParam("id"); - return false; - } - this.jobID = Integer.parseInt(getParams.get("id")); - if (getParams.containsKey("cancel")) this.type = ERequestType.CANCEL; - else if (getParams.containsKey("submit")) { - this.type = ERequestType.SUBMIT; - if (getParams.containsKey("cpu")) this.cpuName = getParams.get("cpu"); - } else this.type = ERequestType.CHECK; - return true; - } - - @Override - void handle(IAEGrid grid) { - if (grid == null) { - deny("GRID_NOT_FOUND"); - return; - } - Future job = gridData.jobs.get(jobID); - if (job == null) { - deny("INVALID_ID"); - return; - } - if (type == ERequestType.CHECK) { - JSON_JobData jobData = new JSON_JobData(); - if (jobData.isDone = job.isDone()) { - try { - IAECraftingJob craftingJob = job.get(); - IAEStorageGrid storageGrid = grid.web$getStorageGrid(); - IAEMeInventoryItem items = storageGrid.web$getItemInventory(); - IAEMeInventoryItem fluids = storageGrid.web$getFluidInventory(); - jobData.isSimulating = craftingJob.web$isSimulation(); - jobData.bytesTotal = craftingJob.web$getByteTotal(); - IItemList plan; - craftingJob.web$populatePlan(plan = AE2Controller.AE2Interface.web$createItemList()); - jobData.plan = new ArrayList<>(); - for (IStack stack : plan) { - JSON_JobData.JobItem jobItem = new JSON_JobData.JobItem(); - jobItem.itemid = stack.web$getItemID(); - jobItem.itemname = stack.web$getDisplayName(); - jobItem.requested = stack.web$getCountRequestable(); - jobItem.steps = stack.web$getCountRequestableCrafts(); - IAEMeInventoryItem inventory = stack.web$isItem() ? items : fluids; - if (jobData.isSimulating) { - IStack toExtract = stack.web$copy(); - toExtract.web$reset(); - toExtract.web$setStackSize(stack.web$getStackSize()); - IStack missing = toExtract.web$copy(); - toExtract = inventory.web$extractItems(toExtract, AEActionable.SIMULATE, grid); - if (toExtract == null) { - toExtract = missing.web$copy(); - toExtract.web$setStackSize(0); - } - jobItem.stored = toExtract.web$getStackSize(); - jobItem.missing = missing.web$getStackSize() - toExtract.web$getStackSize(); - } else { - jobItem.stored = stack.web$getStackSize(); - jobItem.missing = 0; - } - if (jobItem.missing == 0 && jobItem.requested == 0 && jobItem.stored > 0) { - IStack realStack = inventory.web$getAvailableItem(stack); - long available = 0L; - if (realStack != null) available = realStack.web$getStackSize(); - if (available > 0L) jobItem.usedPercent = (double) jobItem.stored / (double) available; - } - jobData.plan.add(jobItem); - } - // TODO Move sorting to javascript! - jobData.plan.sort((i1, i2) -> { - if (i1.missing > 0 && i2.missing > 0) return Long.compare(i2.missing, i1.missing); - else if (i1.missing > 0 && i2.missing == 0) return -1; - else if (i1.missing == 0 && i2.missing > 0) return 1; - if (i1.requested > 0 && i2.requested > 0) return Long.compare(i2.steps, i1.steps); - else if (i1.requested > 0 && i2.requested == 0) return -1; - else if (i1.requested == 0 && i2.requested > 0) return 1; - return Long.compare(i2.stored, i1.stored); - }); - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); - deny("INTERNAL_ERROR"); - return; - } - } - setData(jobData); - done(); - } else if (type == ERequestType.CANCEL) { - job.cancel(true); - gridData.jobs.remove(this.jobID); - done(); - } else if (type == ERequestType.SUBMIT) { - IAECraftingGrid craftingGrid = grid.web$getCraftingGrid(); - if (job.isDone()) { - try { - IAECraftingJob craftingJob = job.get(); - ICraftingCPUCluster target = null; - if (cpuName != null) { - target = GetCPUList.getCPUList(craftingGrid) - .get(cpuName); - if (target == null) { - deny("CPU_NOT_FOUND"); - return; - } - } - String error = craftingGrid.web$submitJob(craftingJob, target, true, grid); - if (error != null) { - deny("FAIL"); - setData(error); - } else { - done(); - } - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); - deny("INTERNAL_ERROR"); - } - } else { - deny("JOB_NOT_DONE"); - } - } - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Order.java b/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Order.java deleted file mode 100644 index fb2da33..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/ae2request/sync/Order.java +++ /dev/null @@ -1,79 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.ae2request.sync; - -import static pl.kuba6000.ae2webintegration.core.AE2Controller.hashcodeToAEItemStack; - -import java.util.Map; -import java.util.concurrent.Future; - -import com.google.gson.JsonObject; - -import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEStorageGrid; - -public class Order extends ISyncedRequest { - - private IStack item; - - @Override - boolean init(Map getParams) { - if (!getParams.containsKey("item") || !getParams.containsKey("quantity")) { - noParam("item", "quantity"); - return false; - } - int hash = Integer.parseInt(getParams.get("item")); - int quantity = Integer.parseInt(getParams.get("quantity")); - this.item = hashcodeToAEItemStack.get(hash); - if (this.item == null || !this.item.web$isCraftable()) { - deny("ITEM_NOT_FOUND"); - return false; - } - this.item = this.item.web$copy(); - this.item.web$setStackSize(quantity); - return true; - } - - @Override - void handle(IAEGrid grid) { - if (grid == null) { - deny("GRID_NOT_FOUND"); - return; - } - IAECraftingGrid craftingGrid = grid.web$getCraftingGrid(); - boolean allBusy = true; - for (ICraftingCPUCluster cpu : craftingGrid.web$getCPUs()) { - if (!cpu.web$isBusy()) { - allBusy = false; - break; - } - } - if (!allBusy) { - IAEStorageGrid storageGrid = grid.web$getStorageGrid(); - final IItemList itemList = storageGrid.web$getItemStorageList(); - IStack realItem = itemList.web$findPrecise(this.item); - if (realItem != null && realItem.web$isCraftable()) { - Future job = craftingGrid.web$beginCraftingJob(grid, this.item); - - int jobID = gridData.addJob(job); - JsonObject jobData = new JsonObject(); - jobData.addProperty("jobID", jobID); - if (gridData.jobs.size() > 3) { - int toDeleteBelowAndEqual = jobID - 3; - gridData.jobs.entrySet() - .removeIf(integerFutureEntry -> integerFutureEntry.getKey() <= toDeleteBelowAndEqual); - } - setData(jobData); - done(); - } else { - deny("ITEM_NOT_FOUND"); - } - } else { - deny("ALL_CPU_BUSY"); - } - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/AEApi/AEActionable.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/AEApi/AEActionable.java deleted file mode 100644 index f6ce667..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/AEApi/AEActionable.java +++ /dev/null @@ -1,6 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.api.AEApi; - -public enum AEActionable { - MODULATE, - SIMULATE -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/AEApi/AEControllerState.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/AEApi/AEControllerState.java deleted file mode 100644 index b3f4bf1..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/AEApi/AEControllerState.java +++ /dev/null @@ -1,9 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.api.AEApi; - -public enum AEControllerState { - NO_CONTROLLER, - CONTROLLER_ONLINE, - CONTROLLER_CONFLICT, - // not implemented - UNSUPPORTED -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/DimensionalCoords.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/DimensionalCoords.java deleted file mode 100644 index 480fd2b..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/DimensionalCoords.java +++ /dev/null @@ -1,34 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.api; - -import java.util.Objects; - - -public class DimensionalCoords { - - int dimid; - int x; - int y; - int z; - - public DimensionalCoords(int dimid, int x, int y, int z) { - this.dimid = dimid; - this.x = x; - this.y = y; - this.z = z; - } - - - - @Override - public int hashCode() { - return Objects.hash(dimid, x, y, z); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof DimensionalCoords coords && coords.dimid == dimid - && coords.x == x - && coords.y == y - && coords.z == z; - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEMixinCallbacks.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEMixinCallbacks.java deleted file mode 100644 index f9cc5ce..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEMixinCallbacks.java +++ /dev/null @@ -1,28 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.api; - -import pl.kuba6000.ae2webintegration.core.AEMixinCallbacks; -import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingPatternDetails; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IPatternProviderViewable; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; - -public interface IAEMixinCallbacks { - - static IAEMixinCallbacks getInstance() { - return AEMixinCallbacks.INSTANCE; - } - - void jobStarted(ICraftingCPUCluster cpuCluster, IAECraftingGrid cache, IAEGrid grid, boolean isMerging, - boolean isAuthorPlayer); - - void craftingStatusPostedUpdate(ICraftingCPUCluster cpu, IStack diff); - - void pushedPattern(ICraftingCPUCluster cpu, IPatternProviderViewable provider, IAECraftingPatternDetails details); - - void jobCompleted(IAEGrid grid, ICraftingCPUCluster cpu); - - void jobCancelled(IAEGrid grid, ICraftingCPUCluster cpu); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEWebInterface.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEWebInterface.java deleted file mode 100644 index 9e70f30..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/IAEWebInterface.java +++ /dev/null @@ -1,18 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.api; - -import com.mojang.authlib.GameProfile; - -import pl.kuba6000.ae2webintegration.core.AEWebAPI; -import pl.kuba6000.ae2webintegration.core.interfaces.IAE; - -public interface IAEWebInterface { - - static IAEWebInterface getInstance() { - return AEWebAPI.INSTANCE; - } - - GameProfile getAEWebGameProfile(); - - void initAEInterface(IAE ae); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/IServerPlatform.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/IServerPlatform.java deleted file mode 100644 index 787c9a1..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/IServerPlatform.java +++ /dev/null @@ -1,26 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.api; - -import java.io.File; -import java.util.UUID; - -public interface IServerPlatform { - - /** - * Resolves a UUID of an online player by their username. - * - * @return The UUID, or null if the player is not online. - */ - UUID getOnlinePlayerUUID(String username); - - /** - * Resolves a UUID from the server's cache/offline data for a given username. - * - * @return The UUID, or null if not found. - */ - UUID getOfflinePlayerUUID(String username); - - /** - * Gets the main config directory. - */ - File getConfigDirectory(); -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedItem.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedItem.java deleted file mode 100644 index 7eb5ca2..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedItem.java +++ /dev/null @@ -1,47 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.api; - -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; -import pl.kuba6000.ae2webintegration.core.utils.GSONUtils; - -public class JSON_CompactedItem { - - @GSONUtils.SkipGSON - private final IStack internalItem; - @GSONUtils.SkipGSON - private final int hashcode; - - public final String itemid; - public final String itemname; - public long active = 0; - public long pending = 0; - public long stored = 0; - public long timeSpentCrafting = 0; - public long craftedTotal = 0; - public double shareInCraftingTime = 0d; - public double shareInCraftingTimeCombined = 0d; - public double craftsPerSec = 0d; - - public JSON_CompactedItem(IStack itemStack) { - this.internalItem = itemStack; - this.hashcode = this.internalItem.hashCode(); - this.itemid = itemStack.web$getItemID(); - this.itemname = itemStack.web$getDisplayName(); - } - - public static JSON_CompactedItem create(IStack stack) { - return new JSON_CompactedItem(stack); - } - - @Override - public int hashCode() { - return hashcode; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof JSON_CompactedItem) { - return ((JSON_CompactedItem) obj).internalItem.equals(this.internalItem); - } - return false; - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedJobTrackingInfo.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedJobTrackingInfo.java deleted file mode 100644 index 966d08f..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_CompactedJobTrackingInfo.java +++ /dev/null @@ -1,95 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.api; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Map; - -import org.apache.commons.lang3.tuple.Pair; - -import pl.kuba6000.ae2webintegration.core.AE2JobTracker; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; - -public class JSON_CompactedJobTrackingInfo { - - public static class timingClass { - - long started; - long ended; - - public timingClass(long started, long ended) { - this.started = started; - this.ended = ended; - } - } - - public static class CompactedTrackingGSONItem { - - public String itemid; - public String itemname; - public long timeSpentOn; - public long craftedTotal; - public double shareInCraftingTime = 0d; - public double shareInCraftingTimeCombined = 0d; - public double craftsPerSec = 0d; - - public ArrayList timings = new ArrayList<>(); - } - - public IStack finalOutput; - public long timeStarted; - public long timeDone; - public boolean wasCancelled; - public ArrayList items = new ArrayList<>(); - - public static class AEInterfaceGSON { - - String name; - - public ArrayList timings = new ArrayList<>(); - public long timingsCombined; - - public HashSet location = new HashSet<>(); - } - - public ArrayList interfaceShare = new ArrayList<>(); - - public JSON_CompactedJobTrackingInfo(AE2JobTracker.JobTrackingInfo info) { - this.finalOutput = info.finalOutput; - this.timeStarted = info.timeStarted; - this.timeDone = info.timeDone; - long elapsed = this.timeDone - this.timeStarted; - this.wasCancelled = info.wasCancelled; - for (Map.Entry entry : info.timeSpentOn.entrySet()) { - IStack stack = entry.getKey(); - long spent = entry.getValue(); - CompactedTrackingGSONItem item = new CompactedTrackingGSONItem(); - item.itemid = stack.web$getItemID(); - item.itemname = stack.web$getDisplayName(); - item.timeSpentOn = spent; - item.craftedTotal = info.craftedTotal.get(stack); - item.shareInCraftingTime = info.getShareInCraftingTime(stack); - item.shareInCraftingTimeCombined = Math.min(((double) item.timeSpentOn) / (double) elapsed, 1d); - item.craftsPerSec = (double) item.craftedTotal / (item.timeSpentOn / 1000d); - for (Pair longLongPair : info.itemShare.get(stack)) { - item.timings.add(new timingClass(longLongPair.getKey(), longLongPair.getValue())); - } - items.add(item); - } - items.sort((i1, i2) -> Double.compare(i2.shareInCraftingTime, i1.shareInCraftingTime)); - for (Map.Entry>> entry : info.interfaceShare.entrySet()) { - AEInterfaceGSON interfaceGSON = new AEInterfaceGSON(); - interfaceGSON.name = entry.getKey().name; - interfaceGSON.location = entry.getKey().location; - for (Pair longLongPair : entry.getValue()) { - interfaceGSON.timings.add(new timingClass(longLongPair.getKey(), longLongPair.getValue())); - } - long interfaceElapsed = 0L; - for (Pair pair : entry.getValue()) { - interfaceElapsed += pair.getValue() - pair.getKey(); - } - interfaceGSON.timingsCombined = interfaceElapsed; - interfaceShare.add(interfaceGSON); - } - interfaceShare.sort((i1, i2) -> Long.compare(i2.timingsCombined, i1.timingsCombined)); - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_DetailedItem.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_DetailedItem.java deleted file mode 100644 index 9a3cc57..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/JSON_DetailedItem.java +++ /dev/null @@ -1,10 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.api; - -public class JSON_DetailedItem { - - public int hashcode; - public String itemid; - public String itemname; - public long quantity; - public boolean craftable; -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/api/PlayerProfile.java b/src/main/java/pl/kuba6000/ae2webintegration/core/api/PlayerProfile.java deleted file mode 100644 index 289e211..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/api/PlayerProfile.java +++ /dev/null @@ -1,21 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.api; - -import java.util.UUID; - -public class PlayerProfile { - private final UUID uuid; - private final String name; - - public PlayerProfile(UUID uuid, String name) { - this.uuid = uuid; - this.name = name; - } - - public UUID getUUID() { - return uuid; - } - - public String getName() { - return name; - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/discord/DiscordManager.java b/src/main/java/pl/kuba6000/ae2webintegration/core/discord/DiscordManager.java deleted file mode 100644 index 937c7a2..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/discord/DiscordManager.java +++ /dev/null @@ -1,115 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.discord; - -import static pl.kuba6000.ae2webintegration.forge.AE2WebIntegrationCore.MODID; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.URL; -import java.util.concurrent.ConcurrentLinkedQueue; - -import javax.net.ssl.HttpsURLConnection; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; - -import pl.kuba6000.ae2webintegration.core.Config; - -public class DiscordManager extends Thread { - - private static final Logger LOG = LogManager.getLogger(MODID + " - DISCORD INTEGRATION"); - - private static DiscordManager thread; - - private static ConcurrentLinkedQueue toPush = new ConcurrentLinkedQueue<>(); - - public static void init() { - if (thread != null) return; - thread = new DiscordManager(); - thread.start(); - } - - public static void postMessageNonBlocking(DiscordEmbed message) { - toPush.offer(message); - } - - public static class DiscordEmbed { - - String title; - String description; - int color; - - public DiscordEmbed(String title, String description, int color) { - this.title = title; - this.description = description; - this.color = color; - } - - public DiscordEmbed(String title, String description) { - this(title, description, 1752220); - } - } - - private static void postMessage(DiscordEmbed message) { - if (Config.DISCORD_WEBHOOK.isEmpty()) return; - - String roleID = Config.DISCORD_ROLE_ID; - - JsonObject json = new JsonObject(); - json.addProperty("username", "AE2 Web Integration"); - json.addProperty("content", !roleID.isEmpty() ? "<@&" + roleID + ">" : ""); - JsonArray embeds = new JsonArray(); - JsonObject embed = new JsonObject(); - embed.addProperty("title", message.title); - embed.addProperty("description", message.description); - embed.addProperty("color", message.color); - embeds.add(embed); - json.add("embeds", embeds); - json.add("attachments", new JsonArray()); - - URL url = null; - try { - url = new URL(Config.DISCORD_WEBHOOK); - - HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); - connection.addRequestProperty("Content-Type", "application/json"); - connection.addRequestProperty("User-Agent", "AE2-Web-Integration"); - connection.setDoOutput(true); - connection.setRequestMethod("POST"); - - OutputStream stream = connection.getOutputStream(); - stream.write( - json.toString() - .getBytes()); - stream.flush(); - stream.close(); - - int code; - if ((code = connection.getResponseCode()) != 200 && code != 204) { - LOG.error("Error, response code: {}", code); - } - } catch (IOException e) { - // throw new RuntimeException(e); - } - } - - @Override - public void run() { - while (true) { - if (toPush.peek() != null) { - DiscordEmbed message; - while ((message = toPush.poll()) != null) { - postMessage(message); - } - } - - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // throw new RuntimeException(e); - } - } - } -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAE.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAE.java deleted file mode 100644 index 088f25b..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAE.java +++ /dev/null @@ -1,11 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces; - -public interface IAE { - - Iterable web$getGrids(); - - IItemList web$createItemList(); - - IAEPlayerData web$getPlayerData(); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingJob.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingJob.java deleted file mode 100644 index 510abd6..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingJob.java +++ /dev/null @@ -1,11 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces; - -public interface IAECraftingJob { - - boolean web$isSimulation(); - - long web$getByteTotal(); - - void web$populatePlan(IItemList plan); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingPatternDetails.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingPatternDetails.java deleted file mode 100644 index c0670d6..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAECraftingPatternDetails.java +++ /dev/null @@ -1,7 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces; - -public interface IAECraftingPatternDetails { - - IStack[] web$getCondensedOutputs(); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEGrid.java deleted file mode 100644 index ed95f3a..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEGrid.java +++ /dev/null @@ -1,25 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces; - - -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEPathingGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAESecurityGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.service.IAEStorageGrid; - -public interface IAEGrid { - - IAECraftingGrid web$getCraftingGrid(); - - IAEPathingGrid web$getPathingGrid(); - - IAEStorageGrid web$getStorageGrid(); - - IAESecurityGrid web$getSecurityGrid(); - - boolean web$isEmpty(); - - Object web$getPlayerSource(); - - Object web$getLastFakePlayerChatMessage(); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEMeInventoryItem.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEMeInventoryItem.java deleted file mode 100644 index 8e07937..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEMeInventoryItem.java +++ /dev/null @@ -1,11 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces; - -import pl.kuba6000.ae2webintegration.core.api.AEApi.AEActionable; - -public interface IAEMeInventoryItem { - - IStack web$extractItems(IStack stack, AEActionable mode, IAEGrid grid); - - IStack web$getAvailableItem(IStack stack); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEPlayerData.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEPlayerData.java deleted file mode 100644 index 61c08cf..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IAEPlayerData.java +++ /dev/null @@ -1,11 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces; - -import java.util.UUID; - -public interface IAEPlayerData { - - pl.kuba6000.ae2webintegration.core.api.PlayerProfile web$getPlayerProfile(int playerId); - - int web$getPlayerId(UUID id); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/ICraftingCPUCluster.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/ICraftingCPUCluster.java deleted file mode 100644 index 2b1a4e1..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/ICraftingCPUCluster.java +++ /dev/null @@ -1,31 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces; - -public interface ICraftingCPUCluster { - - void web$setInternalID(int id); - - boolean web$hasCustomName(); - - String web$getName(); - - long web$getAvailableStorage(); - - long web$getUsedStorage(); - - long web$getCoProcessors(); - - boolean web$isBusy(); - - void web$cancel(); - - IStack web$getFinalOutput(); - - void web$getActiveItems(IItemList list); - - void web$getPendingItems(IItemList list); - - void web$getStorageItems(IItemList list); - - IItemList web$getWaitingFor(); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemList.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemList.java deleted file mode 100644 index f651239..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IItemList.java +++ /dev/null @@ -1,7 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces; - -public interface IItemList extends Iterable { - - IStack web$findPrecise(IStack stack); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IPatternProviderViewable.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IPatternProviderViewable.java deleted file mode 100644 index 23a1722..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IPatternProviderViewable.java +++ /dev/null @@ -1,11 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces; - -import pl.kuba6000.ae2webintegration.core.api.DimensionalCoords; - -public interface IPatternProviderViewable { - - String web$getName(); - - DimensionalCoords web$getLocation(); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java deleted file mode 100644 index 0cec4e0..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/IStack.java +++ /dev/null @@ -1,27 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces; - -public interface IStack { - - String web$getItemID(); - - String web$getDisplayName(); - - long web$getStackSize(); - - boolean web$isCraftable(); - - long web$getCountRequestable(); - - long web$getCountRequestableCrafts(); - - void web$reset(); - - boolean web$isSameType(IStack other); - - IStack web$copy(); - - void web$setStackSize(long size); - - boolean web$isItem(); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java deleted file mode 100644 index f5887f1..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAECraftingGrid.java +++ /dev/null @@ -1,21 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces.service; - -import java.util.Set; -import java.util.concurrent.Future; - - -import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; -import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; -import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; - -public interface IAECraftingGrid { - - int web$getCPUCount(); - - Set web$getCPUs(); - - Future web$beginCraftingJob(IAEGrid grid, IStack stack); - - String web$submitJob(IAECraftingJob job, ICraftingCPUCluster target, boolean prioritizePower, IAEGrid grid); -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEPathingGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEPathingGrid.java deleted file mode 100644 index 73d0fd1..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEPathingGrid.java +++ /dev/null @@ -1,11 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces.service; - -import pl.kuba6000.ae2webintegration.core.api.AEApi.AEControllerState; - -public interface IAEPathingGrid { - - boolean web$isNetworkBooting(); - - AEControllerState web$getControllerState(); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAESecurityGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAESecurityGrid.java deleted file mode 100644 index 13bc653..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAESecurityGrid.java +++ /dev/null @@ -1,17 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces.service; - - - -public interface IAESecurityGrid { - - boolean web$isAvailable(); - - long web$getSecurityKey(); - - int web$getOwner(); - - pl.kuba6000.ae2webintegration.core.api.PlayerProfile web$getOwnerProfile(); - - boolean web$hasPermissions(int playerId); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java b/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java deleted file mode 100644 index 0dd340a..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/interfaces/service/IAEStorageGrid.java +++ /dev/null @@ -1,16 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.interfaces.service; - -import pl.kuba6000.ae2webintegration.core.interfaces.IAEMeInventoryItem; -import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; - -public interface IAEStorageGrid { - - IItemList web$getItemStorageList(); - - IItemList web$getFluidStorageList(); - - IAEMeInventoryItem web$getItemInventory(); - - IAEMeInventoryItem web$getFluidInventory(); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/utils/GSONUtils.java b/src/main/java/pl/kuba6000/ae2webintegration/core/utils/GSONUtils.java deleted file mode 100644 index 3a72079..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/utils/GSONUtils.java +++ /dev/null @@ -1,49 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.utils; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.google.gson.ExclusionStrategy; -import com.google.gson.FieldAttributes; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; -import com.google.gson.JsonSerializer; - -import pl.kuba6000.ae2webintegration.core.interfaces.IStack; - -public class GSONUtils { - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface SkipGSON {} - - private static final ExclusionStrategy GSONStrategy = new ExclusionStrategy() { - - @Override - public boolean shouldSkipField(FieldAttributes f) { - return f.getAnnotation(SkipGSON.class) != null; - } - - @Override - public boolean shouldSkipClass(Class clazz) { - return false; - } - }; - - private static final JsonSerializer IItemStackSerializer = (src, typeOfSrc, context) -> { - JsonObject json = new JsonObject(); - json.addProperty("itemid", src.web$getItemID()); - json.addProperty("itemname", src.web$getDisplayName()); - json.addProperty("hashcode", src.hashCode()); - json.addProperty("quantity", src.web$getStackSize()); - return json; - }; - - public static final GsonBuilder GSON_BUILDER = new GsonBuilder().addSerializationExclusionStrategy(GSONStrategy) - .addDeserializationExclusionStrategy(GSONStrategy) - .registerTypeHierarchyAdapter(IStack.class, IItemStackSerializer) - .serializeNulls(); - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/utils/HTTPUtils.java b/src/main/java/pl/kuba6000/ae2webintegration/core/utils/HTTPUtils.java deleted file mode 100644 index 1346eea..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/utils/HTTPUtils.java +++ /dev/null @@ -1,35 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.utils; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.HashMap; -import java.util.Map; - -public class HTTPUtils { - - public static Map parseQueryString(String qs) { - Map result = new HashMap<>(); - if (qs == null) return result; - - int last = 0, next, l = qs.length(); - while (last < l) { - next = qs.indexOf('&', last); - if (next == -1) next = l; - - if (next > last) { - int eqPos = qs.indexOf('=', last); - try { - if (eqPos < 0 || eqPos > next) result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), ""); - else result.put( - URLDecoder.decode(qs.substring(last, eqPos), "utf-8"), - URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8")); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); // will never happen, utf-8 support is mandatory for java - } - } - last = next + 1; - } - return result; - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/utils/RateLimiter.java b/src/main/java/pl/kuba6000/ae2webintegration/core/utils/RateLimiter.java deleted file mode 100644 index f63a2e6..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/utils/RateLimiter.java +++ /dev/null @@ -1,49 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.utils; - -import java.net.InetAddress; -import java.util.HashMap; - -public class RateLimiter { - - private final int MAX_REQUESTS_PER_INTERVAL; - private final int RESET_INTERVAL_MS; - private final int RESET_WHITELIST_INTERVAL_MS; // 1 hour - - public RateLimiter(int maxRequestsPerInterval, int resetIntervalMs, int resetWhitelistIntervalMs) { - MAX_REQUESTS_PER_INTERVAL = maxRequestsPerInterval; - RESET_INTERVAL_MS = resetIntervalMs; - RESET_WHITELIST_INTERVAL_MS = resetWhitelistIntervalMs; - } - - private long lastUpdate = 0; - private final HashMap requestCounter = new HashMap<>(); - private final HashMap whitelist = new HashMap<>(); - - public boolean isAllowed(InetAddress userId) { - updateRequests(); - - if (whitelist.containsKey(userId)) { - return true; // User is whitelisted - } - - return requestCounter.merge(userId, 1, Integer::sum) < MAX_REQUESTS_PER_INTERVAL; - } - - public void ensureWhitelisted(InetAddress userId) { - whitelist.put(userId, System.currentTimeMillis()); - } - - private void updateRequests() { - long currentTime = System.currentTimeMillis(); - - if (currentTime - lastUpdate > RESET_INTERVAL_MS) { // Reset every 60 seconds - requestCounter.clear(); - lastUpdate = currentTime; - } - - whitelist.entrySet() - .removeIf(entry -> currentTime - entry.getValue() > RESET_WHITELIST_INTERVAL_MS); // Remove entries older - // than 1 hour - } - -} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/core/utils/VersionChecker.java b/src/main/java/pl/kuba6000/ae2webintegration/core/utils/VersionChecker.java deleted file mode 100644 index 9b19c18..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/core/utils/VersionChecker.java +++ /dev/null @@ -1,70 +0,0 @@ -package pl.kuba6000.ae2webintegration.core.utils; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; - -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; - -import pl.kuba6000.ae2webintegration.Tags; - -public class VersionChecker { - - // example version: 0.0.9-alpha-forge-1.12.2 - private static final String VERSION_IDENTIFIER = "-forge-1.7.10"; - - private static final String versionCheckURL = "https://api.github.com/repos/kuba6000/AE2-Web-Integration/tags"; - private static String latestTag = null; - - private static long lastChecked = 0L; - - private static void updateLatestVersion() { - if (lastChecked != 0L) { - if (!Tags.VERSION.equals(latestTag)) return; - long elapsed = System.currentTimeMillis() - lastChecked; - if (latestTag == null) { - if (elapsed < 5 * 60 * 1000) // 5 minutes - return; - } else if (elapsed < 5 * 60 * 60 * 1000) { // 5 hours - return; - } - } - lastChecked = System.currentTimeMillis(); - try { - HttpURLConnection conn = (HttpURLConnection) new URL(versionCheckURL).openConnection(); - if (conn.getResponseCode() == 200) { - try (BufferedReader buf = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { - JsonElement element = new JsonParser().parse(buf); - // this should be sorted right? - for (JsonElement tag : element.getAsJsonArray()) { - String name = tag.getAsJsonObject() - .get("name") - .getAsString(); - if (name.contains(VERSION_IDENTIFIER)) { - latestTag = name; - return; - } - } - // not found??? - latestTag = Tags.VERSION; - } - } - - } catch (Exception ignored) { - - } - } - - public static boolean isOutdated() { - updateLatestVersion(); - if (latestTag == null) return false; - return !latestTag.equals(Tags.VERSION); - } - - public static String getLatestTag() { - return latestTag; - } - -} diff --git a/web-engine b/web-engine new file mode 160000 index 0000000..85c4386 --- /dev/null +++ b/web-engine @@ -0,0 +1 @@ +Subproject commit 85c4386e4bb5b6ab5acafc56afea2da2f94c5edd From d099f16f36f5b49fd4a0ff553c4fe5309a16944d Mon Sep 17 00:00:00 2001 From: Jakub Date: Thu, 7 May 2026 21:06:10 +0200 Subject: [PATCH 07/29] Clean up architecture: single @Mod, remove forge/, move core to submodule - Rename submodule branch interface -> core, update .gitmodules - Remove forge/ package entirely, merge into ae2interface/ - Single @Mod (ae2webintegration) combining former -core and -interface - Fix shadow() -> shadowImplementation() + usesShadowedDependencies - Move web resources (html, favicon) to web-engine submodule - Update mcmod.info to single mod entry - Fix mixin references: GameProfile -> PlayerIdentity/UUID, AEControllerProfile -> AEControllerUUID --- .gitmodules | 2 +- dependencies.gradle | 2 +- gradle.properties | 2 +- .../ae2interface/AE2WebIntegration.java | 35 +- .../{forge => ae2interface}/ClientProxy.java | 2 +- .../{forge => ae2interface}/CommonProxy.java | 11 +- .../FMLEventHandler.java | 3 +- .../{forge => ae2interface}/ForgeConfig.java | 2 +- .../ForgePlatform.java | 2 +- .../commands/BaseCommandHandler.java | 5 +- .../AE2/implementations/AEGridMixin.java | 10 +- .../implementations/AEPlayerDataMixin.java | 4 +- .../service/AECraftingGridMixin.java | 5 +- .../service/AESecurityGridMixin.java | 4 +- .../forge/AE2WebIntegrationCore.java | 68 - src/main/resources/assets/favicon.ico | Bin 318 -> 0 bytes src/main/resources/assets/login.html | 257 --- src/main/resources/assets/webpage.html | 1819 ----------------- src/main/resources/mcmod.info | 22 +- web-engine | 2 +- 20 files changed, 57 insertions(+), 2200 deletions(-) rename src/main/java/pl/kuba6000/ae2webintegration/{forge => ae2interface}/ClientProxy.java (81%) rename src/main/java/pl/kuba6000/ae2webintegration/{forge => ae2interface}/CommonProxy.java (88%) rename src/main/java/pl/kuba6000/ae2webintegration/{forge => ae2interface}/FMLEventHandler.java (96%) rename src/main/java/pl/kuba6000/ae2webintegration/{forge => ae2interface}/ForgeConfig.java (98%) rename src/main/java/pl/kuba6000/ae2webintegration/{forge => ae2interface}/ForgePlatform.java (96%) rename src/main/java/pl/kuba6000/ae2webintegration/{forge => ae2interface}/commands/BaseCommandHandler.java (95%) delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/forge/AE2WebIntegrationCore.java delete mode 100644 src/main/resources/assets/favicon.ico delete mode 100644 src/main/resources/assets/login.html delete mode 100644 src/main/resources/assets/webpage.html diff --git a/.gitmodules b/.gitmodules index def7749..e0b08d1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "web-engine"] path = web-engine url = https://github.com/kuba6000/AE2-Web-Integration.git - branch = interface + branch = core diff --git a/dependencies.gradle b/dependencies.gradle index facb369..c7cdbdc 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -35,7 +35,7 @@ */ dependencies { implementation project(':web-engine') - shadow project(':web-engine') + shadowImplementation project(':web-engine') api("com.github.GTNewHorizons:GTNHLib:0.9.53:dev") api("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-909-GTNH:dev") diff --git a/gradle.properties b/gradle.properties index 1a56b09..7f9706a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -130,7 +130,7 @@ forceEnableMixins = false # If enabled, you may use 'shadowCompile' for dependencies. They will be integrated into your jar. It is your # responsibility to check the license and request permission for distribution if required. -usesShadowedDependencies = false +usesShadowedDependencies = true # If disabled, won't remove unused classes from shadowed dependencies. Some libraries use reflection to access # their own classes, making the minimization unreliable. diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/AE2WebIntegration.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/AE2WebIntegration.java index 2ddf1ee..0e129df 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/AE2WebIntegration.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/AE2WebIntegration.java @@ -3,12 +3,17 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.mojang.authlib.GameProfile; + import appeng.me.cache.SecurityCache; import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.event.FMLServerStartedEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; +import cpw.mods.fml.common.event.FMLServerStoppingEvent; import pl.kuba6000.ae2webintegration.Tags; import pl.kuba6000.ae2webintegration.ae2interface.implementations.AE; import pl.kuba6000.ae2webintegration.core.api.IAEWebInterface; @@ -16,33 +21,53 @@ @Mod( modid = AE2WebIntegration.MODID, version = Tags.VERSION, - name = "AE2WebIntegration-Interface", + name = "AE2 Web Integration", acceptedMinecraftVersions = "[1.7.10]", acceptableRemoteVersions = "*") public class AE2WebIntegration { - public static final String MODID = "ae2webintegration-interface"; + public static final String MODID = "ae2webintegration"; public static final Logger LOG = LogManager.getLogger(MODID); + @SidedProxy( + clientSide = "pl.kuba6000.ae2webintegration.ae2interface.ClientProxy", + serverSide = "pl.kuba6000.ae2webintegration.ae2interface.CommonProxy") + public static CommonProxy proxy; + @Mod.EventHandler - public void preInit(FMLPreInitializationEvent event) {} + public void preInit(FMLPreInitializationEvent event) { + proxy.preInit(event); + } @Mod.EventHandler public void init(FMLInitializationEvent event) { + proxy.init(event); IAEWebInterface.getInstance() .initAEInterface(AE.instance); } @Mod.EventHandler public void postInit(FMLPostInitializationEvent event) { + proxy.postInit(event); SecurityCache.registerOpPlayer( - IAEWebInterface.getInstance() - .getAEWebGameProfile()); + new GameProfile( + IAEWebInterface.getInstance() + .getAEWebUUID(), + "AE2CONTROLLER")); } @Mod.EventHandler public void serverStarting(FMLServerStartingEvent event) { + proxy.serverStarting(event); + } + @Mod.EventHandler + public void serverStarted(FMLServerStartedEvent event) { + proxy.serverStarted(event); } + @Mod.EventHandler + public void serverStopping(FMLServerStoppingEvent event) { + proxy.serverStopping(event); + } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/forge/ClientProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ClientProxy.java similarity index 81% rename from src/main/java/pl/kuba6000/ae2webintegration/forge/ClientProxy.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ClientProxy.java index c7309fc..df7254a 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/forge/ClientProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ClientProxy.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.forge; +package pl.kuba6000.ae2webintegration.ae2interface; public class ClientProxy extends CommonProxy { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/forge/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java similarity index 88% rename from src/main/java/pl/kuba6000/ae2webintegration/forge/CommonProxy.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java index 03f07d8..2de70a2 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/forge/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.forge; +package pl.kuba6000.ae2webintegration.ae2interface; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.event.FMLInitializationEvent; @@ -8,13 +8,10 @@ import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.event.FMLServerStoppingEvent; import pl.kuba6000.ae2webintegration.Tags; +import pl.kuba6000.ae2webintegration.ae2interface.commands.BaseCommandHandler; import pl.kuba6000.ae2webintegration.core.*; - -import pl.kuba6000.ae2webintegration.forge.commands.BaseCommandHandler; import pl.kuba6000.ae2webintegration.core.discord.*; -import pl.kuba6000.ae2webintegration.core.discord.DiscordManager; import pl.kuba6000.ae2webintegration.core.utils.*; -import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; public class CommonProxy { @@ -27,8 +24,8 @@ public void preInit(FMLPreInitializationEvent event) { WebData.loadData(); GridData.loadData(); - AE2WebIntegrationCore.LOG.info("AE2WebIntegration loading at version " + Tags.VERSION); - if (Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated()) AE2WebIntegrationCore.LOG.warn( + AE2WebIntegration.LOG.info("AE2WebIntegration loading at version " + Tags.VERSION); + if (Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated()) AE2WebIntegration.LOG.warn( "You are not on latest version ! Consider updating to {} at https://github.com/kuba6000/AE2-Web-Integration/releases/latest", VersionChecker.getLatestTag()); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/forge/FMLEventHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java similarity index 96% rename from src/main/java/pl/kuba6000/ae2webintegration/forge/FMLEventHandler.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java index f0d25b6..2ce16e4 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/forge/FMLEventHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.forge; +package pl.kuba6000.ae2webintegration.ae2interface; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.ChatComponentText; @@ -9,7 +9,6 @@ import cpw.mods.fml.common.gameevent.TickEvent; import pl.kuba6000.ae2webintegration.core.*; import pl.kuba6000.ae2webintegration.core.ae2request.sync.ISyncedRequest; - import pl.kuba6000.ae2webintegration.core.discord.*; import pl.kuba6000.ae2webintegration.core.utils.*; import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; diff --git a/src/main/java/pl/kuba6000/ae2webintegration/forge/ForgeConfig.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java similarity index 98% rename from src/main/java/pl/kuba6000/ae2webintegration/forge/ForgeConfig.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java index 5634270..a3ba7c1 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/forge/ForgeConfig.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.forge; +package pl.kuba6000.ae2webintegration.ae2interface; import java.io.File; diff --git a/src/main/java/pl/kuba6000/ae2webintegration/forge/ForgePlatform.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlatform.java similarity index 96% rename from src/main/java/pl/kuba6000/ae2webintegration/forge/ForgePlatform.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlatform.java index 4ed3b28..5cdbb00 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/forge/ForgePlatform.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlatform.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.forge; +package pl.kuba6000.ae2webintegration.ae2interface; import java.io.File; import java.util.UUID; diff --git a/src/main/java/pl/kuba6000/ae2webintegration/forge/commands/BaseCommandHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java similarity index 95% rename from src/main/java/pl/kuba6000/ae2webintegration/forge/commands/BaseCommandHandler.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java index 148c36f..93b9f26 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/forge/commands/BaseCommandHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.forge.commands; +package pl.kuba6000.ae2webintegration.ae2interface.commands; import java.util.UUID; @@ -11,9 +11,8 @@ import org.apache.commons.lang3.tuple.Pair; +import pl.kuba6000.ae2webintegration.ae2interface.ForgeConfig; import pl.kuba6000.ae2webintegration.core.AE2Controller; -import pl.kuba6000.ae2webintegration.core.Config; -import pl.kuba6000.ae2webintegration.forge.ForgeConfig; import pl.kuba6000.ae2webintegration.core.WebData; public class BaseCommandHandler extends CommandBase { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEGridMixin.java index c2fa5fd..0209c84 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEGridMixin.java @@ -8,6 +8,8 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; +import com.mojang.authlib.GameProfile; + import appeng.api.networking.IGridHost; import appeng.api.networking.IGridNode; import appeng.api.networking.IMachineSet; @@ -59,7 +61,7 @@ public abstract class AEGridMixin implements IAEGrid { private Class web$lastUsedMachineClass = null; @Unique - public IChatComponent web$lastFakePlayerChatMessage; + public String web$lastFakePlayerChatMessage; @Unique private PlayerSource web$cachedPlayerSource = null; @@ -101,11 +103,11 @@ public abstract class AEGridMixin implements IAEGrid { } web$cachedPlayerSource = new PlayerSource( - new FakePlayer((WorldServer) world, AE2Controller.AEControllerProfile) { + new FakePlayer((WorldServer) world, new GameProfile(AE2Controller.AEControllerUUID, "AE2CONTROLLER")) { @Override public void addChatMessage(IChatComponent message) { - web$lastFakePlayerChatMessage = message; + web$lastFakePlayerChatMessage = message.getUnformattedText(); } }, actionHost); @@ -114,7 +116,7 @@ public void addChatMessage(IChatComponent message) { } @Override - public Object web$getLastFakePlayerChatMessage() { + public String web$getLastFakePlayerChatMessage() { return web$lastFakePlayerChatMessage; } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java index d6eeddf..7dda084 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java @@ -28,7 +28,7 @@ public int getPlayerID(@Nonnull final GameProfile profile) { } @Override - public pl.kuba6000.ae2webintegration.core.api.PlayerProfile web$getPlayerProfile(int playerId) { + public pl.kuba6000.ae2webintegration.core.api.PlayerIdentity web$getPlayerProfile(int playerId) { Optional maybe = playerMapping.get(playerId); if (!maybe.isPresent()) return null; UUID uuid = maybe.get(); @@ -44,7 +44,7 @@ public int getPlayerID(@Nonnull final GameProfile profile) { if (p == null) { p = new GameProfile(uuid, uuid.toString()); } - return new pl.kuba6000.ae2webintegration.core.api.PlayerProfile(p.getId(), p.getName()); + return new pl.kuba6000.ae2webintegration.core.api.PlayerIdentity(p.getId(), p.getName()); } @Override diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java index 37cb415..610f3f0 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java @@ -4,8 +4,6 @@ import java.util.Set; import java.util.concurrent.Future; -import net.minecraft.util.IChatComponent; - import org.spongepowered.asm.mixin.Mixin; import com.google.common.collect.ImmutableSet; @@ -63,6 +61,7 @@ public interface AECraftingGridMixin extends IAECraftingGrid { prioritizePower, (BaseActionSource) grid.web$getPlayerSource()); if (link != null) return null; - Object msg = grid.web$getLastFakePlayerChatMessage(); return msg == null ? null : ((net.minecraft.util.IChatComponent)msg).getUnformattedText(); + Object msg = grid.web$getLastFakePlayerChatMessage(); + return msg == null ? null : ((net.minecraft.util.IChatComponent) msg).getUnformattedText(); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java index db471f8..6c4fc52 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java @@ -7,8 +7,6 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import com.mojang.authlib.GameProfile; - import appeng.api.config.SecurityPermissions; import appeng.core.worlddata.WorldData; import appeng.me.cache.SecurityCache; @@ -38,7 +36,7 @@ public class AESecurityGridMixin implements IAESecurityGrid { } @Override - public pl.kuba6000.ae2webintegration.core.api.PlayerProfile web$getOwnerProfile() { + public pl.kuba6000.ae2webintegration.core.api.PlayerIdentity web$getOwnerProfile() { IAEPlayerData playerData = (IAEPlayerData) WorldData.instance() .playerData(); return playerData.web$getPlayerProfile(web$getOwner()); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/forge/AE2WebIntegrationCore.java b/src/main/java/pl/kuba6000/ae2webintegration/forge/AE2WebIntegrationCore.java deleted file mode 100644 index 3cabd05..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/forge/AE2WebIntegrationCore.java +++ /dev/null @@ -1,68 +0,0 @@ -package pl.kuba6000.ae2webintegration.forge; - -import static pl.kuba6000.ae2webintegration.forge.AE2WebIntegrationCore.MODID; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import cpw.mods.fml.common.Mod; -import cpw.mods.fml.common.SidedProxy; -import cpw.mods.fml.common.event.FMLInitializationEvent; -import cpw.mods.fml.common.event.FMLPostInitializationEvent; -import cpw.mods.fml.common.event.FMLPreInitializationEvent; -import cpw.mods.fml.common.event.FMLServerStartedEvent; -import cpw.mods.fml.common.event.FMLServerStartingEvent; -import cpw.mods.fml.common.event.FMLServerStoppingEvent; -import pl.kuba6000.ae2webintegration.Tags; -import pl.kuba6000.ae2webintegration.core.*; - -import pl.kuba6000.ae2webintegration.core.discord.*; -import pl.kuba6000.ae2webintegration.core.utils.*; - -@Mod( - modid = MODID, - version = Tags.VERSION, - name = "AE2WebIntegration-Core", - acceptedMinecraftVersions = "*", - acceptableRemoteVersions = "*") -public class AE2WebIntegrationCore { - - public static final String MODID = "ae2webintegration-core"; - public static final Logger LOG = LogManager.getLogger(MODID); - - @SidedProxy( - clientSide = "pl.kuba6000.ae2webintegration.forge.ClientProxy", - serverSide = "pl.kuba6000.ae2webintegration.forge.CommonProxy") - public static CommonProxy proxy; - - @Mod.EventHandler - public void preInit(FMLPreInitializationEvent event) { - proxy.preInit(event); - } - - @Mod.EventHandler - public void init(FMLInitializationEvent event) { - proxy.init(event); - } - - @Mod.EventHandler - public void postInit(FMLPostInitializationEvent event) { - proxy.postInit(event); - } - - @Mod.EventHandler - public void serverStarting(FMLServerStartingEvent event) { - proxy.serverStarting(event); - } - - @Mod.EventHandler - public void serverStarted(FMLServerStartedEvent event) { - proxy.serverStarted(event); - } - - @Mod.EventHandler - public void serverStarted(FMLServerStoppingEvent event) { - proxy.serverStopping(event); - } - -} diff --git a/src/main/resources/assets/favicon.ico b/src/main/resources/assets/favicon.ico deleted file mode 100644 index 65f94a94051d77e34696cc52b5fbdf09ecc5da50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318 zcmZQzU<5(|0RbS%!l1#(z#zuJz@P!d0zj+)#2|58Kt|t&!PC=|!7wPDAt51wAv-&p zp`f6EA)tOfLuY3vE^Tn}4s@UZ6-eTMFxs#P2!f@O7)>ldj5cBSU=ZDCQVQlnxg8=9 zZbvg%7N`I$3sQ*${{LrS0O9jMd>n`$1Mx>7{&Ajx;SW0l!#`#q2GW1{fmj~Mwg;-O Jhv)(60|3igUZMa1 diff --git a/src/main/resources/assets/login.html b/src/main/resources/assets/login.html deleted file mode 100644 index 462a9a3..0000000 --- a/src/main/resources/assets/login.html +++ /dev/null @@ -1,257 +0,0 @@ - - - - - - - - - - AE2 - - -

UNIVERSAL WEB TERMINAL

- -
-
-
- -
-
-
- This service requires authentication

-
-
-
-
-


- -
-
- Or register

-
-
-
-
-

- -
-
-
-
- - - -

- - - diff --git a/src/main/resources/assets/webpage.html b/src/main/resources/assets/webpage.html deleted file mode 100644 index f3674cb..0000000 --- a/src/main/resources/assets/webpage.html +++ /dev/null @@ -1,1819 +0,0 @@ - - - - - - - - - - AE2 - - -
-
- -
-
-

UNIVERSAL WEB TERMINAL

-
-
- LOADING... -
-
-
- -
-
- -
-
- -
-
-
-
- To be able to select a grid, there must be security terminal available and you have to be owner or have every permission enabled in the bio card -
-
-
-
-
-
- -
- - - - - - - -
-
- - - -
-
-
-
- Terminal - - - -
- - - -
-
-
-
-
-
Settings
- -
- -
- -
- - -
- -
- -
- -
- You are logged in as
- -
-
-
-
- - -

- - - diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 58b6757..a5abab1 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -1,26 +1,8 @@ { "modListVersion": 2, "modList": [{ - "modid": "ae2webintegration-core", - "name": "AE2WebIntegration-Core", - "description": "AE2 Web Integration mod", - "version": "${modVersion}", - "mcversion": "*", - "url": "https://github.com/kuba6000/AE2-Web-Integration", - "updateUrl": "", - "authorList": ["kuba6000"], - "credits": "", - "logoFile": "", - "screenshots": [], - "parent": "", - "requiredMods": [], - "dependencies": [], - "dependants": [], - "useDependencyInformation": false - }, - { - "modid": "ae2webintegration-interface", - "name": "AE2WebIntegration-Interface", + "modid": "ae2webintegration", + "name": "AE2 Web Integration", "description": "AE2 Web Integration mod", "version": "${modVersion}", "mcversion": "${minecraftVersion}", diff --git a/web-engine b/web-engine index 85c4386..d2128dd 160000 --- a/web-engine +++ b/web-engine @@ -1 +1 @@ -Subproject commit 85c4386e4bb5b6ab5acafc56afea2da2f94c5edd +Subproject commit d2128dd8901328d5c87c2ad164de138908a896ee From f266fbcbdb8e45f39e8d6b96cb906f088366bdae Mon Sep 17 00:00:00 2001 From: Jakub Date: Thu, 7 May 2026 21:15:35 +0200 Subject: [PATCH 08/29] Rename submodule web-engine -> core to match branch name --- .gitmodules | 4 ++-- web-engine => core | 0 dependencies.gradle | 4 ++-- settings.gradle | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename web-engine => core (100%) diff --git a/.gitmodules b/.gitmodules index e0b08d1..d1df2d5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ -[submodule "web-engine"] - path = web-engine +[submodule "core"] + path = core url = https://github.com/kuba6000/AE2-Web-Integration.git branch = core diff --git a/web-engine b/core similarity index 100% rename from web-engine rename to core diff --git a/dependencies.gradle b/dependencies.gradle index c7cdbdc..526bfdf 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -34,8 +34,8 @@ * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph */ dependencies { - implementation project(':web-engine') - shadowImplementation project(':web-engine') + implementation project(':core') + shadowImplementation project(':core') api("com.github.GTNewHorizons:GTNHLib:0.9.53:dev") api("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-909-GTNH:dev") diff --git a/settings.gradle b/settings.gradle index 5ab75e9..0c0b025 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,4 +19,4 @@ plugins { id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.24' } -include ':web-engine' +include ':core' From 4f02ca0201a7a21f0ba895d0e6b2f852f4c138f2 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Thu, 7 May 2026 22:43:52 +0200 Subject: [PATCH 09/29] fix: wire mod version through interface --- core | 2 +- .../ae2webintegration/ae2interface/CommonProxy.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/core b/core index d2128dd..86d143a 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit d2128dd8901328d5c87c2ad164de138908a896ee +Subproject commit 86d143a89262f4b1ef7270e2dc2818c840334962 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java index 2de70a2..44c5fd1 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java @@ -20,11 +20,13 @@ public class CommonProxy { public void preInit(FMLPreInitializationEvent event) { ForgeConfig.init(event.getModConfigurationDirectory()); ForgeConfig.synchronizeConfiguration(); - WebEngine.init(new ForgePlatform(new java.io.File(event.getModConfigurationDirectory(), "ae2webintegration"))); + WebEngine.init( + new ForgePlatform(new java.io.File(event.getModConfigurationDirectory(), "ae2webintegration")), + Tags.VERSION); WebData.loadData(); GridData.loadData(); - AE2WebIntegration.LOG.info("AE2WebIntegration loading at version " + Tags.VERSION); + AE2WebIntegration.LOG.info("AE2WebIntegration loading at version " + WebEngine.getModVersion()); if (Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated()) AE2WebIntegration.LOG.warn( "You are not on latest version ! Consider updating to {} at https://github.com/kuba6000/AE2-Web-Integration/releases/latest", VersionChecker.getLatestTag()); From ba851f4c974485223d947f7ea5b0007ee88db976 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Thu, 7 May 2026 23:17:46 +0200 Subject: [PATCH 10/29] fix: keep GTNH build passing --- dependencies.gradle | 7 ++++++- .../ae2webintegration/ae2interface/CommonProxy.java | 10 +++++++--- .../ae2interface/FMLEventHandler.java | 5 ++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 526bfdf..8ca8f1a 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -35,10 +35,15 @@ */ dependencies { implementation project(':core') - shadowImplementation project(':core') + // Select the jar explicitly so shadow resolution does not hit variant ambiguity on the submodule. + shadowImplementation project(path: ':core', configuration: 'default') api("com.github.GTNewHorizons:GTNHLib:0.9.53:dev") api("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-909-GTNH:dev") api("com.github.GTNewHorizons:AE2FluidCraft-Rework:1.5.76-gtnh:dev") runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.8.91-GTNH:dev") } + +tasks.named("shadowJar").configure { + dependsOn(project(":core").tasks.named("jar")) +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java index 44c5fd1..3f4c598 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java @@ -9,9 +9,13 @@ import cpw.mods.fml.common.event.FMLServerStoppingEvent; import pl.kuba6000.ae2webintegration.Tags; import pl.kuba6000.ae2webintegration.ae2interface.commands.BaseCommandHandler; -import pl.kuba6000.ae2webintegration.core.*; -import pl.kuba6000.ae2webintegration.core.discord.*; -import pl.kuba6000.ae2webintegration.core.utils.*; +import pl.kuba6000.ae2webintegration.core.AE2Controller; +import pl.kuba6000.ae2webintegration.core.Config; +import pl.kuba6000.ae2webintegration.core.GridData; +import pl.kuba6000.ae2webintegration.core.WebData; +import pl.kuba6000.ae2webintegration.core.WebEngine; +import pl.kuba6000.ae2webintegration.core.discord.DiscordManager; +import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; public class CommonProxy { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java index 2ce16e4..a077efb 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java @@ -7,10 +7,9 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent; import cpw.mods.fml.common.gameevent.TickEvent; -import pl.kuba6000.ae2webintegration.core.*; +import pl.kuba6000.ae2webintegration.core.AE2Controller; +import pl.kuba6000.ae2webintegration.core.Config; import pl.kuba6000.ae2webintegration.core.ae2request.sync.ISyncedRequest; -import pl.kuba6000.ae2webintegration.core.discord.*; -import pl.kuba6000.ae2webintegration.core.utils.*; import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; public class FMLEventHandler { From ee4ffc86ea7dc04bbc092e060af5ca066ec0b2b3 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Fri, 8 May 2026 01:02:09 +0200 Subject: [PATCH 11/29] =?UTF-8?q?fix:=20update=20core=20submodule=20?= =?UTF-8?q?=E2=80=94=20mark=20jar=20deobfuscated,=20remove=20GTNH=20conven?= =?UTF-8?q?tion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index 86d143a..dc81596 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 86d143a89262f4b1ef7270e2dc2818c840334962 +Subproject commit dc815965b4010619bf3d09a97985a6024686fda2 From ac466bab20f87bc90d84729682cc63f422356e14 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Fri, 8 May 2026 01:24:56 +0200 Subject: [PATCH 12/29] =?UTF-8?q?fix:=20update=20core=20submodule=20?= =?UTF-8?q?=E2=80=94=20deobfuscation=20attr=20on=20all=20consumable=20conf?= =?UTF-8?q?igs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index dc81596..a7600ee 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit dc815965b4010619bf3d09a97985a6024686fda2 +Subproject commit a7600eea0803d8cb7f1b07c314f98c3a42db9d10 From 4345ea69371dc7e3ca60fe77fa9eefcbae2bf244 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Fri, 8 May 2026 01:38:42 +0200 Subject: [PATCH 13/29] fix: avoid Log4j 2.4+ API in CommonProxy for MC 1.7.10 compat --- core | 2 +- .../kuba6000/ae2webintegration/ae2interface/CommonProxy.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core b/core index a7600ee..8fd5f24 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit a7600eea0803d8cb7f1b07c314f98c3a42db9d10 +Subproject commit 8fd5f2437172d886cb5fcef5b6a34ac41283e141 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java index 3f4c598..1793d93 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java @@ -32,8 +32,7 @@ public void preInit(FMLPreInitializationEvent event) { AE2WebIntegration.LOG.info("AE2WebIntegration loading at version " + WebEngine.getModVersion()); if (Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated()) AE2WebIntegration.LOG.warn( - "You are not on latest version ! Consider updating to {} at https://github.com/kuba6000/AE2-Web-Integration/releases/latest", - VersionChecker.getLatestTag()); + "You are not on latest version ! Consider updating to " + VersionChecker.getLatestTag() + " at https://github.com/kuba6000/AE2-Web-Integration/releases/latest"); FMLCommonHandler.instance() .bus() From dfc5fb0794947cb770288635265a799c13f2f637 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Fri, 8 May 2026 01:44:35 +0200 Subject: [PATCH 14/29] spotless --- .../kuba6000/ae2webintegration/ae2interface/CommonProxy.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java index 1793d93..b2fd9a1 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java @@ -32,7 +32,8 @@ public void preInit(FMLPreInitializationEvent event) { AE2WebIntegration.LOG.info("AE2WebIntegration loading at version " + WebEngine.getModVersion()); if (Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated()) AE2WebIntegration.LOG.warn( - "You are not on latest version ! Consider updating to " + VersionChecker.getLatestTag() + " at https://github.com/kuba6000/AE2-Web-Integration/releases/latest"); + "You are not on latest version ! Consider updating to " + VersionChecker.getLatestTag() + + " at https://github.com/kuba6000/AE2-Web-Integration/releases/latest"); FMLCommonHandler.instance() .bus() From 2c6fc20b183cd2da181eae25e4ae40d3fd48a1de Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sun, 10 May 2026 18:20:48 +0200 Subject: [PATCH 15/29] Interface: abstract config loading through IConfigProvider, delegate version/Discord logic to core --- core | 2 +- .../ae2interface/CommonProxy.java | 26 +---- .../ae2interface/FMLEventHandler.java | 19 ++-- .../ae2interface/ForgeConfig.java | 104 +++++++++++------- .../ae2interface/ForgePlayerMessenger.java | 27 +++++ .../commands/BaseCommandHandler.java | 3 +- 6 files changed, 106 insertions(+), 75 deletions(-) create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlayerMessenger.java diff --git a/core b/core index 8fd5f24..bb29b2e 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 8fd5f2437172d886cb5fcef5b6a34ac41283e141 +Subproject commit bb29b2ef2913ba0237fbd069b3c2aa82e47df06c diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java index b2fd9a1..5a19d20 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java @@ -12,10 +12,9 @@ import pl.kuba6000.ae2webintegration.core.AE2Controller; import pl.kuba6000.ae2webintegration.core.Config; import pl.kuba6000.ae2webintegration.core.GridData; +import pl.kuba6000.ae2webintegration.core.StartupHandler; import pl.kuba6000.ae2webintegration.core.WebData; import pl.kuba6000.ae2webintegration.core.WebEngine; -import pl.kuba6000.ae2webintegration.core.discord.DiscordManager; -import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; public class CommonProxy { @@ -23,7 +22,7 @@ public class CommonProxy { // GameRegistry." (Remove if not needed) public void preInit(FMLPreInitializationEvent event) { ForgeConfig.init(event.getModConfigurationDirectory()); - ForgeConfig.synchronizeConfiguration(); + ForgeConfig.synchronizeConfiguration(Config.getProvider()); WebEngine.init( new ForgePlatform(new java.io.File(event.getModConfigurationDirectory(), "ae2webintegration")), Tags.VERSION); @@ -31,9 +30,7 @@ public void preInit(FMLPreInitializationEvent event) { GridData.loadData(); AE2WebIntegration.LOG.info("AE2WebIntegration loading at version " + WebEngine.getModVersion()); - if (Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated()) AE2WebIntegration.LOG.warn( - "You are not on latest version ! Consider updating to " + VersionChecker.getLatestTag() - + " at https://github.com/kuba6000/AE2-Web-Integration/releases/latest"); + StartupHandler.logOutdatedWarning(); FMLCommonHandler.instance() .bus() @@ -44,9 +41,7 @@ public void preInit(FMLPreInitializationEvent event) { public void init(FMLInitializationEvent event) {} // postInit "Handle interaction with other mods, complete your setup based on this." (Remove if not needed) - public void postInit(FMLPostInitializationEvent event) { - - } + public void postInit(FMLPostInitializationEvent event) {} // register server commands in this event handler (Remove if not needed) public void serverStarting(FMLServerStartingEvent event) { @@ -55,21 +50,10 @@ public void serverStarting(FMLServerStartingEvent event) { public void serverStarted(FMLServerStartedEvent event) { AE2Controller.init(); - DiscordManager.init(); - if (!Config.AE_PUBLIC_MODE && !Config.DISCORD_WEBHOOK.isEmpty()) { - DiscordManager.postMessageNonBlocking( - new DiscordManager.DiscordEmbed("AE2 Web Integration", "Discord integration started!")); - } else if (Config.AE_PUBLIC_MODE && !Config.DISCORD_WEBHOOK.isEmpty()) { - DiscordManager.postMessageNonBlocking( - new DiscordManager.DiscordEmbed( - "AE2 Web Integration", - "Warning!\nDiscord integration webhook is set in the config, but the public mode is enabled!\nDiscord integration will be disabled!", - 15548997)); - } + StartupHandler.handleDiscordIntegration(); } public void serverStopping(FMLServerStoppingEvent event) { AE2Controller.stopHTTPServer(); } - } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java index a077efb..2908506 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java @@ -1,19 +1,19 @@ package pl.kuba6000.ae2webintegration.ae2interface; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.EnumChatFormatting; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent; import cpw.mods.fml.common.gameevent.TickEvent; import pl.kuba6000.ae2webintegration.core.AE2Controller; -import pl.kuba6000.ae2webintegration.core.Config; +import pl.kuba6000.ae2webintegration.core.UpdateNotifier; import pl.kuba6000.ae2webintegration.core.ae2request.sync.ISyncedRequest; -import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; +import pl.kuba6000.ae2webintegration.core.api.PlayerIdentity; public class FMLEventHandler { + private static final ForgePlayerMessenger messenger = new ForgePlayerMessenger(); + @SubscribeEvent public void tick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) return; @@ -29,12 +29,9 @@ public void tick(TickEvent.ServerTickEvent event) { @SubscribeEvent public void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { if (!(event.player instanceof EntityPlayerMP)) return; - if (Config.CHECK_FOR_UPDATES && VersionChecker.isOutdated() - && event.player.canCommandSenderUseCommand(4, "seed")) - event.player.addChatMessage( - new ChatComponentText( - EnumChatFormatting.GREEN.toString() + EnumChatFormatting.BOLD - + "----> AE2WebIntegration -> New version detected! Consider updating at https://github.com/kuba6000/AE2-Web-Integration/releases/latest")); + EntityPlayerMP player = (EntityPlayerMP) event.player; + if (!player.canCommandSenderUseCommand(4, "seed")) return; + UpdateNotifier + .notifyPlayerIfOutdated(messenger, new PlayerIdentity(player.getUniqueID(), player.getCommandSenderName())); } - } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java index a3ba7c1..87cfd4c 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java @@ -4,7 +4,8 @@ import net.minecraftforge.common.config.Configuration; -import pl.kuba6000.ae2webintegration.core.Config; +import pl.kuba6000.ae2webintegration.core.api.ConfigKey; +import pl.kuba6000.ae2webintegration.core.api.IConfigProvider; public class ForgeConfig { @@ -23,49 +24,70 @@ public static void init(File rootConfigDirectory) { } } - public static void synchronizeConfiguration() { + public static void synchronizeConfiguration(IConfigProvider provider) { Configuration configuration = new Configuration(configFile); - Config.AE_PORT = configuration - .getInt("port", Configuration.CATEGORY_GENERAL, Config.AE_PORT, 1, 65535, "Port for the hosted website"); - Config.AE_PASSWORD = configuration.getString( - "password", - Configuration.CATEGORY_GENERAL, - Config.AE_PASSWORD, - "Password for the admin account"); - Config.ALLOW_NO_PASSWORD_ON_LOCALHOST = configuration.getBoolean( - "allow_no_password_on_localhost", - Configuration.CATEGORY_GENERAL, - Config.ALLOW_NO_PASSWORD_ON_LOCALHOST, - "Don't require to login using loopback address (127.0.0.1/localhost)"); - Config.AE_PUBLIC_MODE = configuration.getBoolean( - "public_mode", - Configuration.CATEGORY_GENERAL, - Config.AE_PUBLIC_MODE, - "If enabled every player will have their own 'account' (good for public servers with multiple ME Networks)"); - Config.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE = configuration.getInt( - "max_requests_before_logged_in_per_minute", - Configuration.CATEGORY_GENERAL, - Config.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE, - 1, - 999999999, - "Max requests per minute before logging in (anti brute force)"); + provider.setValue( + ConfigKey.AE_PORT, + configuration.getInt( + ConfigKey.AE_PORT.getKey(), + ConfigKey.AE_PORT.getCategory(), + (int) ConfigKey.AE_PORT.getDefaultValue(), + 1, + 65535, + ConfigKey.AE_PORT.getDescription())); + provider.setValue( + ConfigKey.AE_PASSWORD, + configuration.getString( + ConfigKey.AE_PASSWORD.getKey(), + ConfigKey.AE_PASSWORD.getCategory(), + (String) ConfigKey.AE_PASSWORD.getDefaultValue(), + ConfigKey.AE_PASSWORD.getDescription())); + provider.setValue( + ConfigKey.ALLOW_NO_PASSWORD_ON_LOCALHOST, + configuration.getBoolean( + ConfigKey.ALLOW_NO_PASSWORD_ON_LOCALHOST.getKey(), + ConfigKey.ALLOW_NO_PASSWORD_ON_LOCALHOST.getCategory(), + (boolean) ConfigKey.ALLOW_NO_PASSWORD_ON_LOCALHOST.getDefaultValue(), + ConfigKey.ALLOW_NO_PASSWORD_ON_LOCALHOST.getDescription())); + provider.setValue( + ConfigKey.AE_PUBLIC_MODE, + configuration.getBoolean( + ConfigKey.AE_PUBLIC_MODE.getKey(), + ConfigKey.AE_PUBLIC_MODE.getCategory(), + (boolean) ConfigKey.AE_PUBLIC_MODE.getDefaultValue(), + ConfigKey.AE_PUBLIC_MODE.getDescription())); + provider.setValue( + ConfigKey.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE, + configuration.getInt( + ConfigKey.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE.getKey(), + ConfigKey.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE.getCategory(), + (int) ConfigKey.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE.getDefaultValue(), + 1, + 999999999, + ConfigKey.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE.getDescription())); - Config.DISCORD_WEBHOOK = configuration.getString( - "discord_webhook", - "discord", - Config.DISCORD_WEBHOOK, - "Webhook url for discord integration, keep empty to disable"); - Config.DISCORD_ROLE_ID = configuration.getString( - "discord_role_id", - "discord", - Config.DISCORD_ROLE_ID, - "Role id to ping on errors, keep empty to disable pinging (if webhook is empty it will do nothing)"); + provider.setValue( + ConfigKey.DISCORD_WEBHOOK, + configuration.getString( + ConfigKey.DISCORD_WEBHOOK.getKey(), + ConfigKey.DISCORD_WEBHOOK.getCategory(), + (String) ConfigKey.DISCORD_WEBHOOK.getDefaultValue(), + ConfigKey.DISCORD_WEBHOOK.getDescription())); + provider.setValue( + ConfigKey.DISCORD_ROLE_ID, + configuration.getString( + ConfigKey.DISCORD_ROLE_ID.getKey(), + ConfigKey.DISCORD_ROLE_ID.getCategory(), + (String) ConfigKey.DISCORD_ROLE_ID.getDefaultValue(), + ConfigKey.DISCORD_ROLE_ID.getDescription())); - Config.TRACKING_TRACK_MACHINE_CRAFTING = configuration.getBoolean( - "track_machine_crafting", - "tracking", - Config.TRACKING_TRACK_MACHINE_CRAFTING, - "Track crafting jobs run directly by machines ? (Not manually ordered)"); + provider.setValue( + ConfigKey.TRACKING_TRACK_MACHINE_CRAFTING, + configuration.getBoolean( + ConfigKey.TRACKING_TRACK_MACHINE_CRAFTING.getKey(), + ConfigKey.TRACKING_TRACK_MACHINE_CRAFTING.getCategory(), + (boolean) ConfigKey.TRACKING_TRACK_MACHINE_CRAFTING.getDefaultValue(), + ConfigKey.TRACKING_TRACK_MACHINE_CRAFTING.getDescription())); if (configuration.hasChanged()) { configuration.save(); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlayerMessenger.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlayerMessenger.java new file mode 100644 index 0000000..e2e94cb --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlayerMessenger.java @@ -0,0 +1,27 @@ +package pl.kuba6000.ae2webintegration.ae2interface; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; + +import cpw.mods.fml.common.FMLCommonHandler; +import pl.kuba6000.ae2webintegration.core.api.IPlayerMessenger; +import pl.kuba6000.ae2webintegration.core.api.PlayerIdentity; + +public class ForgePlayerMessenger implements IPlayerMessenger { + + @Override + public void sendMessage(PlayerIdentity player, String message) { + for (EntityPlayerMP entityPlayerMP : (java.util.List) FMLCommonHandler.instance() + .getMinecraftServerInstance() + .getConfigurationManager().playerEntityList) { + if (entityPlayerMP.getUniqueID() + .equals(player.uuid)) { + entityPlayerMP.addChatMessage( + new ChatComponentText( + EnumChatFormatting.GREEN.toString() + EnumChatFormatting.BOLD.toString() + message)); + return; + } + } + } +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java index 93b9f26..45e914b 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java @@ -13,6 +13,7 @@ import pl.kuba6000.ae2webintegration.ae2interface.ForgeConfig; import pl.kuba6000.ae2webintegration.core.AE2Controller; +import pl.kuba6000.ae2webintegration.core.Config; import pl.kuba6000.ae2webintegration.core.WebData; public class BaseCommandHandler extends CommandBase { @@ -49,7 +50,7 @@ public void processCommand(ICommandSender sender, String[] args) { sender.addChatMessage(chatcomponenttranslation2); return; } - ForgeConfig.synchronizeConfiguration(); + ForgeConfig.synchronizeConfiguration(Config.getProvider()); AE2Controller.stopHTTPServer(); AE2Controller.startHTTPServer(); sender.addChatMessage( From ab1b8386067fd2caf1d72053538ded7c6e99e702 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sun, 10 May 2026 18:49:50 +0200 Subject: [PATCH 16/29] Interface: delegate command logic to core CommandProcessor --- core | 2 +- .../commands/BaseCommandHandler.java | 38 +++++-------------- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/core b/core index bb29b2e..f55369e 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit bb29b2ef2913ba0237fbd069b3c2aa82e47df06c +Subproject commit f55369e4d95bd0574f16723997b6225007d775c2 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java index 45e914b..b6d42aa 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java @@ -9,12 +9,10 @@ import net.minecraft.util.ChatComponentTranslation; import net.minecraft.util.EnumChatFormatting; -import org.apache.commons.lang3.tuple.Pair; - import pl.kuba6000.ae2webintegration.ae2interface.ForgeConfig; -import pl.kuba6000.ae2webintegration.core.AE2Controller; +import pl.kuba6000.ae2webintegration.core.CommandProcessor; import pl.kuba6000.ae2webintegration.core.Config; -import pl.kuba6000.ae2webintegration.core.WebData; +import pl.kuba6000.ae2webintegration.core.api.CommandResult; public class BaseCommandHandler extends CommandBase { @@ -50,12 +48,11 @@ public void processCommand(ICommandSender sender, String[] args) { sender.addChatMessage(chatcomponenttranslation2); return; } - ForgeConfig.synchronizeConfiguration(Config.getProvider()); - AE2Controller.stopHTTPServer(); - AE2Controller.startHTTPServer(); + CommandResult result = CommandProcessor + .reload(() -> ForgeConfig.synchronizeConfiguration(Config.getProvider())); sender.addChatMessage( new ChatComponentText( - EnumChatFormatting.GREEN + "Successfully reloaded the config and restarted the web server!")); + (result.isSuccess() ? EnumChatFormatting.GREEN : EnumChatFormatting.RED) + result.getMessage())); } else { // auth command if (args.length < 2) { @@ -73,27 +70,10 @@ public void processCommand(ICommandSender sender, String[] args) { } UUID id = ((EntityPlayerMP) sender).getUniqueID(); - - Pair p = AE2Controller.awaitingRegistration.get(id); - if (p == null) { - sender.addChatMessage( - new ChatComponentText( - EnumChatFormatting.RED - + "You have to initialize the registration on the web interface first!")); - return; - } - - if (!p.getLeft() - .equals(token)) { - sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Invalid token!")); - return; - } - - WebData.setPassword(((EntityPlayerMP) sender).getUniqueID(), p.getRight()); - - AE2Controller.awaitingRegistration.remove(id); - - sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Registered successfully!")); + CommandResult result = CommandProcessor.registerPlayer(id, token); + sender.addChatMessage( + new ChatComponentText( + (result.isSuccess() ? EnumChatFormatting.GREEN : EnumChatFormatting.RED) + result.getMessage())); } } } From ae16d8b576867c7db4535209bdfbc8347e05bf4b Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sun, 10 May 2026 21:03:30 +0200 Subject: [PATCH 17/29] gtnh-native-fluid: Phase 4 - implement new core interfaces (IAEKey, IAEGenericStack, ICraftingMediumTracker, ICraftingPlanSummary) via mixins --- core | 2 +- .../mixins/AE2/CraftingGridCacheMixin.java | 21 ++++++- .../AECraftingCPUClusterMixin.java | 41 ++++++++++++ .../implementations/AECraftingJobMixin.java | 62 +++++++++++++++++++ .../AE2/implementations/AEItemListMixin.java | 8 +++ .../AEMeInventoryItemMixin.java | 22 +++++++ .../implementations/AEPlayerDataMixin.java | 5 ++ .../AE2/implementations/AEStackMixin.java | 27 +++++++- .../service/AECraftingGridMixin.java | 25 ++++++++ .../service/AESecurityGridMixin.java | 3 +- 10 files changed, 212 insertions(+), 4 deletions(-) diff --git a/core b/core index f55369e..f427da4 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit f55369e4d95bd0574f16723997b6225007d775c2 +Subproject commit f427da4a54e2652a0782447f0f15ec07c04f1094 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingGridCacheMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingGridCacheMixin.java index 9aa830c..169f378 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingGridCacheMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/CraftingGridCacheMixin.java @@ -1,5 +1,9 @@ package pl.kuba6000.ae2webintegration.ae2interface.mixins.AE2; +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.Map; + import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -17,16 +21,18 @@ import appeng.api.networking.crafting.ICraftingProviderHelper; import appeng.api.networking.crafting.ICraftingRequester; import appeng.api.networking.security.BaseActionSource; +import appeng.api.util.IInterfaceViewable; import appeng.me.cache.CraftingGridCache; import appeng.me.cluster.implementations.CraftingCPUCluster; import pl.kuba6000.ae2webintegration.ae2interface.CraftingMediumTracker; import pl.kuba6000.ae2webintegration.core.api.IAEMixinCallbacks; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; +import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingMediumTracker; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; @Mixin(value = CraftingGridCache.class, remap = false) -public class CraftingGridCacheMixin { +public class CraftingGridCacheMixin implements ICraftingMediumTracker { @Final @Shadow @@ -85,4 +91,17 @@ public class CraftingGridCacheMixin { CraftingMediumTracker.doneUpdatingPatterns((CraftingGridCache) (Object) this, grid); } + // --- ICraftingMediumTracker --- + + @Override + public Map web$getCraftingMediums() { + IdentityHashMap mediums = CraftingMediumTracker.mediumToViewable.get(grid); + if (mediums == null) return Collections.emptyMap(); + return (Map) (Map) mediums; + } + + // This overrides the default from AECraftingGridMixin (interface mixin on ICraftingGrid) + public ICraftingMediumTracker web$getCraftingProviders() { + return (ICraftingMediumTracker) this; + } } 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 66efbb1..6089255 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 @@ -8,6 +8,7 @@ import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEStack; import appeng.me.cluster.implementations.CraftingCPUCluster; +import pl.kuba6000.ae2webintegration.core.interfaces.IAEKey; import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingCPUCluster; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; import pl.kuba6000.ae2webintegration.core.interfaces.IStack; @@ -108,4 +109,44 @@ public abstract class AECraftingCPUClusterMixin implements ICraftingCPUCluster { public IItemList web$getWaitingFor() { return (IItemList) (Object) waitingFor; } + + @Override + public void web$getAllItems(IItemList list) { + web$getActiveItems(list); + web$getPendingItems(list); + web$getStorageItems(list); + } + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public long web$getActiveItems(IAEKey key) { + appeng.api.storage.data.IItemList items = new appeng.util.item.ItemList(); + ((CraftingCPUCluster) (Object) this).getModernListOfItem( + (appeng.api.storage.data.IItemList>) (Object) items, + CraftingItemList.ACTIVE); + IAEStack found = items.findPrecise((IAEItemStack) (Object) key); + return found == null ? 0 : found.getStackSize(); + } + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public long web$getPendingItems(IAEKey key) { + appeng.api.storage.data.IItemList items = new appeng.util.item.ItemList(); + ((CraftingCPUCluster) (Object) this).getModernListOfItem( + (appeng.api.storage.data.IItemList>) (Object) items, + CraftingItemList.PENDING); + IAEStack found = items.findPrecise((IAEItemStack) (Object) key); + return found == null ? 0 : found.getStackSize(); + } + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public long web$getStorageItems(IAEKey key) { + appeng.api.storage.data.IItemList items = new appeng.util.item.ItemList(); + ((CraftingCPUCluster) (Object) this).getModernListOfItem( + (appeng.api.storage.data.IItemList>) (Object) items, + CraftingItemList.STORAGE); + IAEStack found = items.findPrecise((IAEItemStack) (Object) key); + return found == null ? 0 : found.getStackSize(); + } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingJobMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingJobMixin.java index 9740d11..eaf6a94 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingJobMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AECraftingJobMixin.java @@ -1,10 +1,17 @@ package pl.kuba6000.ae2webintegration.ae2interface.mixins.AE2.implementations; +import java.util.ArrayList; +import java.util.List; + import org.spongepowered.asm.mixin.Mixin; import appeng.api.networking.crafting.ICraftingJob; import appeng.api.storage.data.IAEStack; import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; +import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; +import pl.kuba6000.ae2webintegration.core.interfaces.IAEKey; +import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingPlanSummary; +import pl.kuba6000.ae2webintegration.core.interfaces.ICraftingPlanSummaryEntry; import pl.kuba6000.ae2webintegration.core.interfaces.IItemList; @Mixin(value = ICraftingJob.class, remap = false) @@ -24,4 +31,59 @@ public interface AECraftingJobMixin extends IAECraftingJob { public default void web$populatePlan(IItemList plan) { ((ICraftingJob) (Object) this).populatePlan((appeng.api.storage.data.IItemList>) (Object) plan); } + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public default ICraftingPlanSummary web$generateSummary(IAEGrid grid) { + appeng.api.storage.data.IItemList plan = new appeng.util.item.ItemList(); + ((ICraftingJob) (Object) this).populatePlan(plan); + + final List entries = new ArrayList<>(); + for (Object obj : plan) { + final IAEStack captured = (IAEStack) obj; + entries.add(new ICraftingPlanSummaryEntry() { + + @Override + public IAEKey web$getWhat() { + return (IAEKey) (Object) captured; + } + + @Override + public long web$getMissingAmount() { + return Math.max(0, captured.getCountRequestable() - captured.getStackSize()); + } + + @Override + public long web$getStoredAmount() { + return captured.getStackSize(); + } + + @Override + public long web$getCraftAmount() { + return captured.getCountRequestableCrafts(); + } + }); + } + + final long bytes = ((ICraftingJob) (Object) this).getByteTotal(); + final boolean simulation = ((ICraftingJob) (Object) this).isSimulation(); + + return new ICraftingPlanSummary() { + + @Override + public long web$getUsedBytes() { + return bytes; + } + + @Override + public boolean web$isSimulation() { + return simulation; + } + + @Override + public List web$getEntries() { + return entries; + } + }; + } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemListMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemListMixin.java index 8ad32dd..fb2a46f 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemListMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEItemListMixin.java @@ -5,6 +5,7 @@ import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IItemContainer; import appeng.api.storage.data.IItemList; +import pl.kuba6000.ae2webintegration.core.interfaces.IAEKey; import pl.kuba6000.ae2webintegration.core.interfaces.IStack; @Mixin(value = IItemList.class, remap = false) @@ -16,4 +17,11 @@ public interface AEItemListMixin return (IStack) findPrecise((StackType) stack); } + @Override + @SuppressWarnings("unchecked") + default long web$findPrecise(IAEKey stack) { + StackType found = findPrecise((StackType) (Object) stack); + return found == null ? 0 : found.getStackSize(); + } + } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java index 85f9cd7..2e79746 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java @@ -5,9 +5,11 @@ import appeng.api.config.Actionable; import appeng.api.networking.security.BaseActionSource; import appeng.api.storage.IMEInventory; +import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEStack; import pl.kuba6000.ae2webintegration.core.api.AEApi.AEActionable; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; +import pl.kuba6000.ae2webintegration.core.interfaces.IAEKey; import pl.kuba6000.ae2webintegration.core.interfaces.IAEMeInventoryItem; import pl.kuba6000.ae2webintegration.core.interfaces.IStack; @@ -26,4 +28,24 @@ public interface AEMeInventoryItemMixin extends IAEMeInventoryItem { public default IStack web$getAvailableItem(IStack stack) { return (IStack) ((IMEInventory) (Object) this).getAvailableItem((IAEStack) stack); } + + @Override + @SuppressWarnings("unchecked") + public default long web$extractItems(IAEKey stack, long amount, AEActionable mode, IAEGrid grid) { + IAEItemStack template = (IAEItemStack) (Object) stack; + template = template.copy(); + template.setStackSize(amount); + IAEItemStack extracted = (IAEItemStack) ((IMEInventory) (Object) this).extractItems( + template, + mode == AEActionable.MODULATE ? Actionable.MODULATE : Actionable.SIMULATE, + (BaseActionSource) grid.web$getPlayerSource()); + return extracted == null ? 0 : extracted.getStackSize(); + } + + @Override + @SuppressWarnings("unchecked") + public default long web$getAvailableItem(IAEKey stack, IAEGrid grid) { + IAEItemStack found = (IAEItemStack) ((IMEInventory) (Object) this).getAvailableItem((IAEStack) (Object) stack); + return found == null ? 0 : found.getStackSize(); + } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java index 7dda084..b9311be 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java @@ -51,4 +51,9 @@ public int getPlayerID(@Nonnull final GameProfile profile) { public int web$getPlayerId(java.util.UUID id) { return getPlayerID(new com.mojang.authlib.GameProfile(id, null)); } + + @Override + public int web$getPlayerId(Object profile) { + return getPlayerID((GameProfile) profile); + } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java index 9a3c604..d8e0e7a 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEStackMixin.java @@ -6,10 +6,12 @@ import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEStack; import cpw.mods.fml.common.registry.GameRegistry; +import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; +import pl.kuba6000.ae2webintegration.core.interfaces.IAEKey; import pl.kuba6000.ae2webintegration.core.interfaces.IStack; @Mixin(IAEStack.class) -public interface AEStackMixin extends IAEStack, IStack { +public interface AEStackMixin extends IAEStack, IStack, IAEKey { @Override public default String web$getItemID() { @@ -25,6 +27,16 @@ public interface AEStackMixin extends IAEStack, IStack { return getDisplayName(); } + @Override + public default IAEKey web$what() { + return (IAEKey) this; + } + + @Override + public default long web$amount() { + return getStackSize(); + } + @Override public default long web$getStackSize() { return getStackSize(); @@ -69,4 +81,17 @@ public interface AEStackMixin extends IAEStack, IStack { public default boolean web$isItem() { return isItem(); } + + // --- IAEKey methods --- + + @Override + public default boolean web$isCraftable(IAEGrid grid) { + return isCraftable(); + } + + @Override + @SuppressWarnings("unchecked") + public default boolean web$isSameType(IAEKey other) { + return isSameType((IAEStack) (Object) other); + } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java index 610f3f0..04f689a 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java @@ -1,8 +1,10 @@ package pl.kuba6000.ae2webintegration.ae2interface.mixins.AE2.implementations.service; +import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; import java.util.concurrent.Future; +import java.util.function.Function; import org.spongepowered.asm.mixin.Mixin; @@ -18,7 +20,9 @@ import appeng.api.storage.data.IAEItemStack; import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; 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.ICraftingMediumTracker; import pl.kuba6000.ae2webintegration.core.interfaces.IStack; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAECraftingGrid; @@ -64,4 +68,25 @@ public interface AECraftingGridMixin extends IAECraftingGrid { Object msg = grid.web$getLastFakePlayerChatMessage(); return msg == null ? null : ((net.minecraft.util.IChatComponent) msg).getUnformattedText(); } + + @Override + @SuppressWarnings("unchecked") + public default Future web$beginCraftingJob(IAEGrid grid, IAEKey stack, long amount) { + PlayerSource actionSrc = (PlayerSource) grid.web$getPlayerSource(); + IAEItemStack aeStack = (IAEItemStack) (Object) stack; + aeStack.setStackSize(amount); + final Future job = ((ICraftingGrid) (Object) this) + .beginCraftingJob(actionSrc.player.worldObj, (IGrid) grid, actionSrc, aeStack, null); + return (Future) (Object) job; + } + + @Override + public default ICraftingMediumTracker web$getCraftingProviders() { + throw new UnsupportedOperationException("Use on CraftingGridCache implementation"); + } + + @Override + public default Set web$getCraftables(Function filter) { + return Collections.emptySet(); + } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java index 6c4fc52..fa734d3 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java @@ -10,6 +10,7 @@ import appeng.api.config.SecurityPermissions; import appeng.core.worlddata.WorldData; import appeng.me.cache.SecurityCache; +import pl.kuba6000.ae2webintegration.core.api.PlayerIdentity; import pl.kuba6000.ae2webintegration.core.interfaces.IAEPlayerData; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAESecurityGrid; @@ -39,7 +40,7 @@ public class AESecurityGridMixin implements IAESecurityGrid { public pl.kuba6000.ae2webintegration.core.api.PlayerIdentity web$getOwnerProfile() { IAEPlayerData playerData = (IAEPlayerData) WorldData.instance() .playerData(); - return playerData.web$getPlayerProfile(web$getOwner()); + return (PlayerIdentity) playerData.web$getPlayerProfile(web$getOwner()); } @Override From 5b2bb7e042ac363ad5a9d4ed2fab8a66bf84ee76 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sun, 10 May 2026 22:02:33 +0200 Subject: [PATCH 18/29] gtnh-native-fluid: config inversion - ForgeConfigBuilder/Value, core owns config definition --- core | 2 +- .../ae2interface/CommonProxy.java | 3 +- .../ae2interface/ForgeConfig.java | 86 ++++--------------- .../ae2interface/ForgeConfigBuilder.java | 49 +++++++++++ .../ae2interface/ForgeConfigValue.java | 28 ++++++ .../commands/BaseCommandHandler.java | 4 +- 6 files changed, 99 insertions(+), 73 deletions(-) create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigBuilder.java create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigValue.java diff --git a/core b/core index f427da4..1490c11 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit f427da4a54e2652a0782447f0f15ec07c04f1094 +Subproject commit 1490c1196bdf2bd1bce989bd0b16cfdcd6627731 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java index 5a19d20..84c3f63 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java @@ -10,7 +10,6 @@ import pl.kuba6000.ae2webintegration.Tags; import pl.kuba6000.ae2webintegration.ae2interface.commands.BaseCommandHandler; import pl.kuba6000.ae2webintegration.core.AE2Controller; -import pl.kuba6000.ae2webintegration.core.Config; import pl.kuba6000.ae2webintegration.core.GridData; import pl.kuba6000.ae2webintegration.core.StartupHandler; import pl.kuba6000.ae2webintegration.core.WebData; @@ -22,7 +21,7 @@ public class CommonProxy { // GameRegistry." (Remove if not needed) public void preInit(FMLPreInitializationEvent event) { ForgeConfig.init(event.getModConfigurationDirectory()); - ForgeConfig.synchronizeConfiguration(Config.getProvider()); + ForgeConfig.synchronizeConfiguration(); WebEngine.init( new ForgePlatform(new java.io.File(event.getModConfigurationDirectory(), "ae2webintegration")), Tags.VERSION); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java index 87cfd4c..3d551dd 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java @@ -4,9 +4,23 @@ import net.minecraftforge.common.config.Configuration; -import pl.kuba6000.ae2webintegration.core.api.ConfigKey; -import pl.kuba6000.ae2webintegration.core.api.IConfigProvider; - +import pl.kuba6000.ae2webintegration.core.ConfigBootstrap; + +/** + * Forge 1.7.10 config wiring. This class does NOT define what config keys + * exist — that is owned by {@link ConfigBootstrap}. Instead it: + *
    + *
  1. Sets up the config directory via {@link #init(File)}
  2. + *
  3. Creates a {@link Configuration} from the config file
  4. + *
  5. Wraps it in a {@link ForgeConfigBuilder}
  6. + *
  7. Passes the wrapper to {@link ConfigBootstrap#init} so core defines all keys
  8. + *
  9. Saves the config if any keys were modified
  10. + *
+ * + * Because Forge reads values synchronously at definition time, each call to + * {@link #synchronizeConfiguration()} creates fresh {@link ForgeConfigValue} + * snapshots holding the current on-disk values. + */ public class ForgeConfig { private static File configDirectory; @@ -24,71 +38,9 @@ public static void init(File rootConfigDirectory) { } } - public static void synchronizeConfiguration(IConfigProvider provider) { + public static void synchronizeConfiguration() { Configuration configuration = new Configuration(configFile); - provider.setValue( - ConfigKey.AE_PORT, - configuration.getInt( - ConfigKey.AE_PORT.getKey(), - ConfigKey.AE_PORT.getCategory(), - (int) ConfigKey.AE_PORT.getDefaultValue(), - 1, - 65535, - ConfigKey.AE_PORT.getDescription())); - provider.setValue( - ConfigKey.AE_PASSWORD, - configuration.getString( - ConfigKey.AE_PASSWORD.getKey(), - ConfigKey.AE_PASSWORD.getCategory(), - (String) ConfigKey.AE_PASSWORD.getDefaultValue(), - ConfigKey.AE_PASSWORD.getDescription())); - provider.setValue( - ConfigKey.ALLOW_NO_PASSWORD_ON_LOCALHOST, - configuration.getBoolean( - ConfigKey.ALLOW_NO_PASSWORD_ON_LOCALHOST.getKey(), - ConfigKey.ALLOW_NO_PASSWORD_ON_LOCALHOST.getCategory(), - (boolean) ConfigKey.ALLOW_NO_PASSWORD_ON_LOCALHOST.getDefaultValue(), - ConfigKey.ALLOW_NO_PASSWORD_ON_LOCALHOST.getDescription())); - provider.setValue( - ConfigKey.AE_PUBLIC_MODE, - configuration.getBoolean( - ConfigKey.AE_PUBLIC_MODE.getKey(), - ConfigKey.AE_PUBLIC_MODE.getCategory(), - (boolean) ConfigKey.AE_PUBLIC_MODE.getDefaultValue(), - ConfigKey.AE_PUBLIC_MODE.getDescription())); - provider.setValue( - ConfigKey.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE, - configuration.getInt( - ConfigKey.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE.getKey(), - ConfigKey.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE.getCategory(), - (int) ConfigKey.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE.getDefaultValue(), - 1, - 999999999, - ConfigKey.AE_MAX_REQUESTS_BEFORE_LOGGED_IN_PER_MINUTE.getDescription())); - - provider.setValue( - ConfigKey.DISCORD_WEBHOOK, - configuration.getString( - ConfigKey.DISCORD_WEBHOOK.getKey(), - ConfigKey.DISCORD_WEBHOOK.getCategory(), - (String) ConfigKey.DISCORD_WEBHOOK.getDefaultValue(), - ConfigKey.DISCORD_WEBHOOK.getDescription())); - provider.setValue( - ConfigKey.DISCORD_ROLE_ID, - configuration.getString( - ConfigKey.DISCORD_ROLE_ID.getKey(), - ConfigKey.DISCORD_ROLE_ID.getCategory(), - (String) ConfigKey.DISCORD_ROLE_ID.getDefaultValue(), - ConfigKey.DISCORD_ROLE_ID.getDescription())); - - provider.setValue( - ConfigKey.TRACKING_TRACK_MACHINE_CRAFTING, - configuration.getBoolean( - ConfigKey.TRACKING_TRACK_MACHINE_CRAFTING.getKey(), - ConfigKey.TRACKING_TRACK_MACHINE_CRAFTING.getCategory(), - (boolean) ConfigKey.TRACKING_TRACK_MACHINE_CRAFTING.getDefaultValue(), - ConfigKey.TRACKING_TRACK_MACHINE_CRAFTING.getDescription())); - + ConfigBootstrap.init(new ForgeConfigBuilder(configuration)); if (configuration.hasChanged()) { configuration.save(); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigBuilder.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigBuilder.java new file mode 100644 index 0000000..681df1d --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigBuilder.java @@ -0,0 +1,49 @@ +package pl.kuba6000.ae2webintegration.ae2interface; + +import net.minecraftforge.common.config.Configuration; + +import pl.kuba6000.ae2webintegration.core.api.IConfigBuilder; +import pl.kuba6000.ae2webintegration.core.api.IConfigValue; + +/** + * {@link IConfigBuilder} implementation wrapping Forge 1.7.10's + * {@link Configuration} API. + *

+ * Unlike NeoForge's lazy {@code ConfigValue}, Forge reads config values + * synchronously at definition time. Each {@code defineXxx} call invokes + * {@code configuration.getXxx(...)} immediately and returns a snapshot-based + * {@link ForgeConfigValue} holding the result. + *

+ * Config keys are mapped to the same categories ("general", "discord", + * "tracking") that the old {@code ConfigKey} enum used, preserving the + * existing config file structure across upgrades. + */ +public class ForgeConfigBuilder implements IConfigBuilder { + + private final Configuration configuration; + + public ForgeConfigBuilder(Configuration configuration) { + this.configuration = configuration; + } + + private static String category(String key) { + if (key.startsWith("discord_")) return "discord"; + if ("track_machine_crafting".equals(key)) return "tracking"; + return "general"; + } + + @Override + public IConfigValue defineInt(String key, int defaultValue, int min, int max, String comment) { + return new ForgeConfigValue<>(configuration.getInt(key, category(key), defaultValue, min, max, comment)); + } + + @Override + public IConfigValue defineString(String key, String defaultValue, String comment) { + return new ForgeConfigValue<>(configuration.getString(key, category(key), defaultValue, comment)); + } + + @Override + public IConfigValue defineBoolean(String key, boolean defaultValue, String comment) { + return new ForgeConfigValue<>(configuration.getBoolean(key, category(key), defaultValue, comment)); + } +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigValue.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigValue.java new file mode 100644 index 0000000..b93ea0a --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigValue.java @@ -0,0 +1,28 @@ +package pl.kuba6000.ae2webintegration.ae2interface; + +import pl.kuba6000.ae2webintegration.core.api.IConfigValue; + +/** + * Snapshot-based {@link IConfigValue} implementation for Forge 1.7.10's + * synchronous {@code Configuration} API. + *

+ * Forge reads config values at definition time (unlike NeoForge's lazy + * {@code ConfigValue}), so this class stores the value returned by the + * {@code configuration.getXxx(...)} call. On reload a new + * {@code ForgeConfigValue} is created with the re-read value. + * + * @param the value type (Integer, String, Boolean) + */ +public class ForgeConfigValue implements IConfigValue { + + private final T value; + + ForgeConfigValue(T value) { + this.value = value; + } + + @Override + public T get() { + return value; + } +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java index b6d42aa..4ca81aa 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java @@ -11,7 +11,6 @@ import pl.kuba6000.ae2webintegration.ae2interface.ForgeConfig; import pl.kuba6000.ae2webintegration.core.CommandProcessor; -import pl.kuba6000.ae2webintegration.core.Config; import pl.kuba6000.ae2webintegration.core.api.CommandResult; public class BaseCommandHandler extends CommandBase { @@ -48,8 +47,7 @@ public void processCommand(ICommandSender sender, String[] args) { sender.addChatMessage(chatcomponenttranslation2); return; } - CommandResult result = CommandProcessor - .reload(() -> ForgeConfig.synchronizeConfiguration(Config.getProvider())); + CommandResult result = CommandProcessor.reload(() -> ForgeConfig.synchronizeConfiguration()); sender.addChatMessage( new ChatComponentText( (result.isSuccess() ? EnumChatFormatting.GREEN : EnumChatFormatting.RED) + result.getMessage())); From ec0d2ca1f715c0f6c1aa85cc94ed696c4a6e9311 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sun, 10 May 2026 22:39:26 +0200 Subject: [PATCH 19/29] gtnh-native-fluid: command inversion - ForgeCommandContext/Registry, thin BaseCommandHandler --- core | 2 +- .../ae2interface/CommonProxy.java | 6 +- .../commands/BaseCommandHandler.java | 70 ++++++------------- .../commands/ForgeCommandContext.java | 65 +++++++++++++++++ .../commands/ForgeCommandRegistry.java | 30 ++++++++ 5 files changed, 124 insertions(+), 49 deletions(-) create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandContext.java create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandRegistry.java diff --git a/core b/core index 1490c11..6e4186c 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 1490c1196bdf2bd1bce989bd0b16cfdcd6627731 +Subproject commit 6e4186c71ecfc8988cac95f795ed1d50f67b7b7b diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java index 84c3f63..b4ba936 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java @@ -9,7 +9,9 @@ import cpw.mods.fml.common.event.FMLServerStoppingEvent; import pl.kuba6000.ae2webintegration.Tags; import pl.kuba6000.ae2webintegration.ae2interface.commands.BaseCommandHandler; +import pl.kuba6000.ae2webintegration.ae2interface.commands.ForgeCommandRegistry; import pl.kuba6000.ae2webintegration.core.AE2Controller; +import pl.kuba6000.ae2webintegration.core.CommandBootstrap; import pl.kuba6000.ae2webintegration.core.GridData; import pl.kuba6000.ae2webintegration.core.StartupHandler; import pl.kuba6000.ae2webintegration.core.WebData; @@ -44,7 +46,9 @@ public void postInit(FMLPostInitializationEvent event) {} // register server commands in this event handler (Remove if not needed) public void serverStarting(FMLServerStartingEvent event) { - event.registerServerCommand(new BaseCommandHandler()); + ForgeCommandRegistry registry = new ForgeCommandRegistry(); + CommandBootstrap.init(registry); + event.registerServerCommand(new BaseCommandHandler(registry)); } public void serverStarted(FMLServerStartedEvent event) { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java index 4ca81aa..cf4ba00 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java @@ -1,20 +1,30 @@ package pl.kuba6000.ae2webintegration.ae2interface.commands; -import java.util.UUID; +import java.util.function.Consumer; import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.EnumChatFormatting; - -import pl.kuba6000.ae2webintegration.ae2interface.ForgeConfig; -import pl.kuba6000.ae2webintegration.core.CommandProcessor; -import pl.kuba6000.ae2webintegration.core.api.CommandResult; +import pl.kuba6000.ae2webintegration.core.api.ICommandContext; + +/** + * Thin Forge 1.7.10 command wrapper. All argument parsing and dispatch logic + * lives in {@code CommandBootstrap} (core) — this class only: + *

    + *
  • Provides the required {@link CommandBase} overrides
  • + *
  • Skips command processing on the client side
  • + *
  • Creates a {@link ForgeCommandContext} and delegates to the + * handler registered via {@link ForgeCommandRegistry}
  • + *
+ */ public class BaseCommandHandler extends CommandBase { + private final ForgeCommandRegistry registry; + + public BaseCommandHandler(ForgeCommandRegistry registry) { + this.registry = registry; + } + @Override public String getCommandName() { return "ae2webintegration"; @@ -32,46 +42,12 @@ public int getRequiredPermissionLevel() { @Override public void processCommand(ICommandSender sender, String[] args) { + // Never process commands on the client side if (sender.getEntityWorld().isRemote) return; - if (args.length == 0 || (!args[0].equals("reload") && !args[0].equals("auth"))) { - sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "/ae2webintegration ")); - return; - } - if (args[0].equals("reload")) { - if (!sender.canCommandSenderUseCommand(4, getCommandName())) { - ChatComponentTranslation chatcomponenttranslation2 = new ChatComponentTranslation( - "commands.generic.permission", - new Object[0]); - chatcomponenttranslation2.getChatStyle() - .setColor(EnumChatFormatting.RED); - sender.addChatMessage(chatcomponenttranslation2); - return; - } - CommandResult result = CommandProcessor.reload(() -> ForgeConfig.synchronizeConfiguration()); - sender.addChatMessage( - new ChatComponentText( - (result.isSuccess() ? EnumChatFormatting.GREEN : EnumChatFormatting.RED) + result.getMessage())); - } else { - // auth command - if (args.length < 2) { - sender - .addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "/ae2webintegration auth ")); - return; - } - - String token = args[1]; - - if (!(sender instanceof EntityPlayerMP)) { - sender.addChatMessage( - new ChatComponentText(EnumChatFormatting.RED + "This command can only be used by players!")); - return; - } - UUID id = ((EntityPlayerMP) sender).getUniqueID(); - CommandResult result = CommandProcessor.registerPlayer(id, token); - sender.addChatMessage( - new ChatComponentText( - (result.isSuccess() ? EnumChatFormatting.GREEN : EnumChatFormatting.RED) + result.getMessage())); + Consumer handler = registry.getHandler(); + if (handler != null) { + handler.accept(new ForgeCommandContext(sender, args)); } } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandContext.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandContext.java new file mode 100644 index 0000000..b077a32 --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandContext.java @@ -0,0 +1,65 @@ +package pl.kuba6000.ae2webintegration.ae2interface.commands; + +import java.util.UUID; + +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; + +import pl.kuba6000.ae2webintegration.ae2interface.ForgeConfig; +import pl.kuba6000.ae2webintegration.core.api.ICommandContext; + +/** + * {@link ICommandContext} implementation wrapping Forge 1.7.10's + * {@link ICommandSender} and the raw command arguments. + */ +public class ForgeCommandContext implements ICommandContext { + + private final ICommandSender sender; + private final String[] args; + + public ForgeCommandContext(ICommandSender sender, String[] args) { + this.sender = sender; + this.args = args; + } + + @Override + public String[] getArgs() { + return args; + } + + @Override + public UUID getPlayerUUID() { + if (sender instanceof EntityPlayerMP) { + return ((EntityPlayerMP) sender).getUniqueID(); + } + return null; + } + + @Override + public boolean hasPermission(int level) { + return sender.canCommandSenderUseCommand(level, "ae2webintegration"); + } + + @Override + public void sendMessage(String text) { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + text)); + } + + @Override + public void sendError(String text) { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + text)); + } + + /** + * Returns a Runnable that re-reads the Forge config file via + * {@link ForgeConfig#synchronizeConfiguration()} and restarts the + * HTTP server. {@link pl.kuba6000.ae2webintegration.core.CommandProcessor#reload} + * handles the actual stop/start — this runnable only re-reads the config. + */ + @Override + public Runnable getReloader() { + return () -> ForgeConfig.synchronizeConfiguration(); + } +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandRegistry.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandRegistry.java new file mode 100644 index 0000000..a89a842 --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandRegistry.java @@ -0,0 +1,30 @@ +package pl.kuba6000.ae2webintegration.ae2interface.commands; + +import java.util.function.Consumer; + +import pl.kuba6000.ae2webintegration.core.api.ICommandContext; +import pl.kuba6000.ae2webintegration.core.api.ICommandRegistry; + +/** + * {@link ICommandRegistry} implementation for Forge 1.7.10. + *

+ * Forge's command system requires a {@code CommandBase} subclass to be + * registered via {@code FMLServerStartingEvent}. This registry stores the + * handler from {@code CommandBootstrap.init()}; the thin + * {@link BaseCommandHandler} retrieves it via {@link #getHandler()} when + * the command is executed. + */ +public class ForgeCommandRegistry implements ICommandRegistry { + + private Consumer handler; + + @Override + public void registerCommand(String name, int defaultPermission, Consumer handler) { + this.handler = handler; + } + + /** Returns the handler registered by {@code CommandBootstrap.init()}. */ + public Consumer getHandler() { + return handler; + } +} From 0d0a5dde924a71649a178e1653474a7ed59ebba7 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sun, 10 May 2026 23:42:51 +0200 Subject: [PATCH 20/29] gtnh-native-fluid: fix registration crash + admin password default --- .../core/worlddata/IWorldPlayerMapping.java | 42 +++++++++++++++++++ core | 2 +- .../implementations/AEPlayerDataMixin.java | 18 +++++++- 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 appeng/core/worlddata/IWorldPlayerMapping.java diff --git a/appeng/core/worlddata/IWorldPlayerMapping.java b/appeng/core/worlddata/IWorldPlayerMapping.java new file mode 100644 index 0000000..de70ae0 --- /dev/null +++ b/appeng/core/worlddata/IWorldPlayerMapping.java @@ -0,0 +1,42 @@ +/* + * This file is part of Applied Energistics 2. Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved. Applied + * Energistics 2 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. Applied Energistics 2 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 + * Applied Energistics 2. If not, see . + */ + +package appeng.core.worlddata; + +import java.util.UUID; + +import javax.annotation.Nonnull; + +import com.google.common.base.Optional; + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +public interface IWorldPlayerMapping { + + /** + * Tries to retrieve the UUID of a player. Might not be stored inside of the map. Should not happen though. + * + * @param id ID of the to be searched player + * @return maybe the UUID of the searched player + */ + @Nonnull + Optional get(int id); + + /** + * Put in new players when they join the server + * + * @param id id of new player + * @param uuid UUID of new player + */ + void put(int id, @Nonnull UUID uuid); +} diff --git a/core b/core index 6e4186c..b8cf691 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 6e4186c71ecfc8988cac95f795ed1d50f67b7b7b +Subproject commit b8cf691cf2bc613435f76c431c3c2f41c7210622 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java index b9311be..f9f64b3 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEPlayerDataMixin.java @@ -49,7 +49,23 @@ public int getPlayerID(@Nonnull final GameProfile profile) { @Override public int web$getPlayerId(java.util.UUID id) { - return getPlayerID(new com.mojang.authlib.GameProfile(id, null)); + // getPlayerID requires a complete GameProfile (both UUID and name). + // First try the server's profile cache (the player is online for + // the /ae2webintegration auth flow, so their profile should be cached). + try { + GameProfile cached = FMLCommonHandler.instance() + .getMinecraftServerInstance() + .func_152358_ax() + .func_152652_a(id); + if (cached != null && cached.isComplete()) { + return getPlayerID(cached); + } + } catch (Exception ignored) {} + + // Graceful fallback — the caller (e.g. WebData.setPassword) will save + // the password hash but skip UUID↔ID map population until the player + // logs in via the game (which triggers PlayerData registration). + return -1; } @Override From 64a2fa12f3dab2828aafab39d275128ca0f2f4be Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sun, 10 May 2026 23:44:14 +0200 Subject: [PATCH 21/29] Remove accidentally committed AE2 source file --- .../core/worlddata/IWorldPlayerMapping.java | 42 ------------------- 1 file changed, 42 deletions(-) delete mode 100644 appeng/core/worlddata/IWorldPlayerMapping.java diff --git a/appeng/core/worlddata/IWorldPlayerMapping.java b/appeng/core/worlddata/IWorldPlayerMapping.java deleted file mode 100644 index de70ae0..0000000 --- a/appeng/core/worlddata/IWorldPlayerMapping.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Applied Energistics 2. Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved. Applied - * Energistics 2 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. Applied Energistics 2 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 - * Applied Energistics 2. If not, see . - */ - -package appeng.core.worlddata; - -import java.util.UUID; - -import javax.annotation.Nonnull; - -import com.google.common.base.Optional; - -/** - * @author thatsIch - * @version rv3 - 30.05.2015 - * @since rv3 30.05.2015 - */ -public interface IWorldPlayerMapping { - - /** - * Tries to retrieve the UUID of a player. Might not be stored inside of the map. Should not happen though. - * - * @param id ID of the to be searched player - * @return maybe the UUID of the searched player - */ - @Nonnull - Optional get(int id); - - /** - * Put in new players when they join the server - * - * @param id id of new player - * @param uuid UUID of new player - */ - void put(int id, @Nonnull UUID uuid); -} From e6049758e8ce789fe3cb1f48c62fddb8998352cc Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Thu, 14 May 2026 23:34:54 +0200 Subject: [PATCH 22/29] gtnh-native-fluid: full command inversion - ForgeCommandBuilder tree replacing ForgeCommandRegistry --- core | 2 +- .../ae2interface/CommonProxy.java | 8 +- .../commands/BaseCommandHandler.java | 72 ++++++++++---- .../commands/ForgeCommandBuilder.java | 94 +++++++++++++++++++ .../commands/ForgeCommandRegistry.java | 30 ------ 5 files changed, 154 insertions(+), 52 deletions(-) create mode 100644 src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandBuilder.java delete mode 100644 src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandRegistry.java diff --git a/core b/core index b8cf691..c8c7e56 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit b8cf691cf2bc613435f76c431c3c2f41c7210622 +Subproject commit c8c7e5611bf534f88adb37fa39c00dc3cefdec52 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java index b4ba936..5267b9f 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java @@ -9,7 +9,7 @@ import cpw.mods.fml.common.event.FMLServerStoppingEvent; import pl.kuba6000.ae2webintegration.Tags; import pl.kuba6000.ae2webintegration.ae2interface.commands.BaseCommandHandler; -import pl.kuba6000.ae2webintegration.ae2interface.commands.ForgeCommandRegistry; +import pl.kuba6000.ae2webintegration.ae2interface.commands.ForgeCommandBuilder; import pl.kuba6000.ae2webintegration.core.AE2Controller; import pl.kuba6000.ae2webintegration.core.CommandBootstrap; import pl.kuba6000.ae2webintegration.core.GridData; @@ -46,9 +46,9 @@ public void postInit(FMLPostInitializationEvent event) {} // register server commands in this event handler (Remove if not needed) public void serverStarting(FMLServerStartingEvent event) { - ForgeCommandRegistry registry = new ForgeCommandRegistry(); - CommandBootstrap.init(registry); - event.registerServerCommand(new BaseCommandHandler(registry)); + ForgeCommandBuilder builder = new ForgeCommandBuilder(); + CommandBootstrap.init(builder); + event.registerServerCommand(new BaseCommandHandler(builder.getRootNodes())); } public void serverStarted(FMLServerStartedEvent event) { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java index cf4ba00..e49eb4d 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java @@ -1,28 +1,25 @@ package pl.kuba6000.ae2webintegration.ae2interface.commands; -import java.util.function.Consumer; +import java.util.List; import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; -import pl.kuba6000.ae2webintegration.core.api.ICommandContext; +import pl.kuba6000.ae2webintegration.ae2interface.commands.ForgeCommandBuilder.ForgeCommandNode; /** - * Thin Forge 1.7.10 command wrapper. All argument parsing and dispatch logic - * lives in {@code CommandBootstrap} (core) — this class only: - *

    - *
  • Provides the required {@link CommandBase} overrides
  • - *
  • Skips command processing on the client side
  • - *
  • Creates a {@link ForgeCommandContext} and delegates to the - * handler registered via {@link ForgeCommandRegistry}
  • - *
+ * Forge 1.7.10 command handler. Traverses the command tree built by + * {@link ForgeCommandBuilder} to find the matching handler for the + * player's arguments, then delegates to it via {@link ForgeCommandContext}. */ public class BaseCommandHandler extends CommandBase { - private final ForgeCommandRegistry registry; + private final List rootNodes; - public BaseCommandHandler(ForgeCommandRegistry registry) { - this.registry = registry; + public BaseCommandHandler(List rootNodes) { + this.rootNodes = rootNodes; } @Override @@ -42,12 +39,53 @@ public int getRequiredPermissionLevel() { @Override public void processCommand(ICommandSender sender, String[] args) { - // Never process commands on the client side if (sender.getEntityWorld().isRemote) return; - Consumer handler = registry.getHandler(); - if (handler != null) { - handler.accept(new ForgeCommandContext(sender, args)); + if (rootNodes.isEmpty()) return; + ForgeCommandNode root = rootNodes.get(0); // "ae2webintegration" + + ForgeCommandNode matched = walkTree(root, args, 0); + if (matched != null && matched.handler != null) { + // Check permission on the matched node + if (matched.permission > 0 && !sender.canCommandSenderUseCommand(matched.permission, getCommandName())) { + sender.addChatMessage( + new ChatComponentText(EnumChatFormatting.RED + "You do not have permission to use this command!")); + return; + } + matched.handler.accept(new ForgeCommandContext(sender, args)); + } else { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "/ae2webintegration ")); + } + } + + /** + * Recursively walks the command tree, matching arguments against literal + * names and argument placeholders. Returns the deepest matching node that + * has a handler, or {@code null} if no path matches. + */ + private static ForgeCommandNode walkTree(ForgeCommandNode node, String[] args, int index) { + if (index >= args.length) { + return node.handler != null ? node : null; + } + + String current = args[index]; + + // Try to match a literal child by name + for (ForgeCommandNode child : node.children) { + if (!child.isArgument && child.name.equals(current)) { + ForgeCommandNode result = walkTree(child, args, index + 1); + if (result != null) return result; + } } + + // Try to match an argument child (matches any token) + for (ForgeCommandNode child : node.children) { + if (child.isArgument) { + ForgeCommandNode result = walkTree(child, args, index + 1); + if (result != null) return result; + } + } + + return null; } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandBuilder.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandBuilder.java new file mode 100644 index 0000000..90aecaa --- /dev/null +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandBuilder.java @@ -0,0 +1,94 @@ +package pl.kuba6000.ae2webintegration.ae2interface.commands; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import pl.kuba6000.ae2webintegration.core.api.ICommandBuilder; +import pl.kuba6000.ae2webintegration.core.api.ICommandContext; + +/** + * {@link ICommandBuilder} implementation for Forge 1.7.10. + *

+ * Builds a tree of {@link ForgeCommandNode} instances as + * {@code CommandBootstrap.init()} calls the fluent API. The tree is then + * traversed by {@link BaseCommandHandler} at runtime to find the matching + * handler for the given arguments. + *

+ * {@link #register()} is a no-op because Forge commands are registered via + * {@code FMLServerStartingEvent} + a {@code CommandBase} subclass, not via + * the builder. + */ +public class ForgeCommandBuilder implements ICommandBuilder { + + /** A node in the command tree. */ + public static class ForgeCommandNode { + + public final String name; + public final int permission; + public final boolean isArgument; + public final List children = new ArrayList<>(); + public Consumer handler; + + ForgeCommandNode(String name, int permission, boolean isArgument) { + this.name = name; + this.permission = permission; + this.isArgument = isArgument; + } + + void addChild(ForgeCommandNode child) { + children.add(child); + } + } + + private final ForgeCommandNode currentNode; + private final ICommandBuilder parent; + private final List rootNodes; + + /** Root constructor. */ + public ForgeCommandBuilder() { + this.currentNode = null; + this.parent = null; + this.rootNodes = new ArrayList<>(); + } + + private ForgeCommandBuilder(ForgeCommandNode currentNode, ICommandBuilder parent, + List rootNodes) { + this.currentNode = currentNode; + this.parent = parent; + this.rootNodes = rootNodes; + } + + @Override + public ICommandBuilder literal(String name, int permission) { + ForgeCommandNode child = new ForgeCommandNode(name, permission, false); + if (parent == null) { + rootNodes.add(child); + } else if (currentNode != null) { + currentNode.addChild(child); + } + return new ForgeCommandBuilder(child, this, rootNodes); + } + + @Override + public ICommandBuilder argument(String name) { + ForgeCommandNode child = new ForgeCommandNode(name, 0, true); + if (currentNode != null) { + currentNode.addChild(child); + } + return new ForgeCommandBuilder(child, this, rootNodes); + } + + @Override + public ICommandBuilder executes(Consumer handler) { + if (currentNode != null) { + currentNode.handler = handler; + } + return parent; + } + + /** Returns the top-level nodes built by the fluent calls. */ + public List getRootNodes() { + return rootNodes; + } +} diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandRegistry.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandRegistry.java deleted file mode 100644 index a89a842..0000000 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandRegistry.java +++ /dev/null @@ -1,30 +0,0 @@ -package pl.kuba6000.ae2webintegration.ae2interface.commands; - -import java.util.function.Consumer; - -import pl.kuba6000.ae2webintegration.core.api.ICommandContext; -import pl.kuba6000.ae2webintegration.core.api.ICommandRegistry; - -/** - * {@link ICommandRegistry} implementation for Forge 1.7.10. - *

- * Forge's command system requires a {@code CommandBase} subclass to be - * registered via {@code FMLServerStartingEvent}. This registry stores the - * handler from {@code CommandBootstrap.init()}; the thin - * {@link BaseCommandHandler} retrieves it via {@link #getHandler()} when - * the command is executed. - */ -public class ForgeCommandRegistry implements ICommandRegistry { - - private Consumer handler; - - @Override - public void registerCommand(String name, int defaultPermission, Consumer handler) { - this.handler = handler; - } - - /** Returns the handler registered by {@code CommandBootstrap.init()}. */ - public Consumer getHandler() { - return handler; - } -} From 04c5b33bc8afa6ebf0e108fddddf8f98bb9ad78a Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Fri, 15 May 2026 00:57:16 +0200 Subject: [PATCH 23/29] =?UTF-8?q?gtnh-native-fluid:=20rename=20Forge*?= =?UTF-8?q?=E2=86=92unprefixed,=20organize=20into=20config/platform/proxy/?= =?UTF-8?q?commands=20subpackages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core | 2 +- .../ae2interface/AE2WebIntegration.java | 6 ++-- .../ae2interface/FMLEventHandler.java | 2 +- ...yerMessenger.java => PlayerMessenger.java} | 2 +- .../commands/BaseCommandHandler.java | 26 +++++++-------- ...ommandBuilder.java => CommandBuilder.java} | 32 +++++++++---------- ...ommandContext.java => CommandContext.java} | 10 +++--- .../{ForgeConfig.java => config/Config.java} | 18 +++++------ .../ConfigBuilder.java} | 14 ++++---- .../ConfigValue.java} | 8 ++--- .../Platform.java} | 6 ++-- .../ae2interface/{ => proxy}/ClientProxy.java | 2 +- .../ae2interface/{ => proxy}/CommonProxy.java | 16 ++++++---- 13 files changed, 74 insertions(+), 70 deletions(-) rename src/main/java/pl/kuba6000/ae2webintegration/ae2interface/{ForgePlayerMessenger.java => PlayerMessenger.java} (93%) rename src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/{ForgeCommandBuilder.java => CommandBuilder.java} (68%) rename src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/{ForgeCommandContext.java => CommandContext.java} (83%) rename src/main/java/pl/kuba6000/ae2webintegration/ae2interface/{ForgeConfig.java => config/Config.java} (69%) rename src/main/java/pl/kuba6000/ae2webintegration/ae2interface/{ForgeConfigBuilder.java => config/ConfigBuilder.java} (71%) rename src/main/java/pl/kuba6000/ae2webintegration/ae2interface/{ForgeConfigValue.java => config/ConfigValue.java} (73%) rename src/main/java/pl/kuba6000/ae2webintegration/ae2interface/{ForgePlatform.java => platform/Platform.java} (89%) rename src/main/java/pl/kuba6000/ae2webintegration/ae2interface/{ => proxy}/ClientProxy.java (79%) rename src/main/java/pl/kuba6000/ae2webintegration/ae2interface/{ => proxy}/CommonProxy.java (77%) diff --git a/core b/core index c8c7e56..995ad61 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit c8c7e5611bf534f88adb37fa39c00dc3cefdec52 +Subproject commit 995ad6128b378595a41a041132a25ac788064a09 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/AE2WebIntegration.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/AE2WebIntegration.java index 0e129df..ee975ee 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/AE2WebIntegration.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/AE2WebIntegration.java @@ -30,9 +30,9 @@ public class AE2WebIntegration { public static final Logger LOG = LogManager.getLogger(MODID); @SidedProxy( - clientSide = "pl.kuba6000.ae2webintegration.ae2interface.ClientProxy", - serverSide = "pl.kuba6000.ae2webintegration.ae2interface.CommonProxy") - public static CommonProxy proxy; + clientSide = "pl.kuba6000.ae2webintegration.ae2interface.proxy.ClientProxy", + serverSide = "pl.kuba6000.ae2webintegration.ae2interface.proxy.CommonProxy") + public static pl.kuba6000.ae2webintegration.ae2interface.proxy.CommonProxy proxy; @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java index 2908506..95dba08 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/FMLEventHandler.java @@ -12,7 +12,7 @@ public class FMLEventHandler { - private static final ForgePlayerMessenger messenger = new ForgePlayerMessenger(); + private static final PlayerMessenger messenger = new PlayerMessenger(); @SubscribeEvent public void tick(TickEvent.ServerTickEvent event) { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlayerMessenger.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/PlayerMessenger.java similarity index 93% rename from src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlayerMessenger.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/PlayerMessenger.java index e2e94cb..dc1e934 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlayerMessenger.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/PlayerMessenger.java @@ -8,7 +8,7 @@ import pl.kuba6000.ae2webintegration.core.api.IPlayerMessenger; import pl.kuba6000.ae2webintegration.core.api.PlayerIdentity; -public class ForgePlayerMessenger implements IPlayerMessenger { +public class PlayerMessenger implements IPlayerMessenger { @Override public void sendMessage(PlayerIdentity player, String message) { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java index e49eb4d..9b31006 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/BaseCommandHandler.java @@ -7,18 +7,18 @@ import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; -import pl.kuba6000.ae2webintegration.ae2interface.commands.ForgeCommandBuilder.ForgeCommandNode; +import pl.kuba6000.ae2webintegration.ae2interface.commands.CommandBuilder.CommandNode; /** * Forge 1.7.10 command handler. Traverses the command tree built by - * {@link ForgeCommandBuilder} to find the matching handler for the - * player's arguments, then delegates to it via {@link ForgeCommandContext}. + * {@link CommandBuilder} to find the matching handler for the + * player's arguments, then delegates to it via {@link CommandContext}. */ public class BaseCommandHandler extends CommandBase { - private final List rootNodes; + private final List rootNodes; - public BaseCommandHandler(List rootNodes) { + public BaseCommandHandler(List rootNodes) { this.rootNodes = rootNodes; } @@ -42,9 +42,9 @@ public void processCommand(ICommandSender sender, String[] args) { if (sender.getEntityWorld().isRemote) return; if (rootNodes.isEmpty()) return; - ForgeCommandNode root = rootNodes.get(0); // "ae2webintegration" + CommandNode root = rootNodes.get(0); // "ae2webintegration" - ForgeCommandNode matched = walkTree(root, args, 0); + CommandNode matched = walkTree(root, args, 0); if (matched != null && matched.handler != null) { // Check permission on the matched node if (matched.permission > 0 && !sender.canCommandSenderUseCommand(matched.permission, getCommandName())) { @@ -52,7 +52,7 @@ public void processCommand(ICommandSender sender, String[] args) { new ChatComponentText(EnumChatFormatting.RED + "You do not have permission to use this command!")); return; } - matched.handler.accept(new ForgeCommandContext(sender, args)); + matched.handler.accept(new CommandContext(sender, args)); } else { sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "/ae2webintegration ")); } @@ -63,7 +63,7 @@ public void processCommand(ICommandSender sender, String[] args) { * names and argument placeholders. Returns the deepest matching node that * has a handler, or {@code null} if no path matches. */ - private static ForgeCommandNode walkTree(ForgeCommandNode node, String[] args, int index) { + private static CommandNode walkTree(CommandNode node, String[] args, int index) { if (index >= args.length) { return node.handler != null ? node : null; } @@ -71,17 +71,17 @@ private static ForgeCommandNode walkTree(ForgeCommandNode node, String[] args, i String current = args[index]; // Try to match a literal child by name - for (ForgeCommandNode child : node.children) { + for (CommandNode child : node.children) { if (!child.isArgument && child.name.equals(current)) { - ForgeCommandNode result = walkTree(child, args, index + 1); + CommandNode result = walkTree(child, args, index + 1); if (result != null) return result; } } // Try to match an argument child (matches any token) - for (ForgeCommandNode child : node.children) { + for (CommandNode child : node.children) { if (child.isArgument) { - ForgeCommandNode result = walkTree(child, args, index + 1); + CommandNode result = walkTree(child, args, index + 1); if (result != null) return result; } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandBuilder.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/CommandBuilder.java similarity index 68% rename from src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandBuilder.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/CommandBuilder.java index 90aecaa..06cebab 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandBuilder.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/CommandBuilder.java @@ -10,7 +10,7 @@ /** * {@link ICommandBuilder} implementation for Forge 1.7.10. *

- * Builds a tree of {@link ForgeCommandNode} instances as + * Builds a tree of {@link CommandNode} instances as * {@code CommandBootstrap.init()} calls the fluent API. The tree is then * traversed by {@link BaseCommandHandler} at runtime to find the matching * handler for the given arguments. @@ -19,41 +19,41 @@ * {@code FMLServerStartingEvent} + a {@code CommandBase} subclass, not via * the builder. */ -public class ForgeCommandBuilder implements ICommandBuilder { +public class CommandBuilder implements ICommandBuilder { /** A node in the command tree. */ - public static class ForgeCommandNode { + public static class CommandNode { public final String name; public final int permission; public final boolean isArgument; - public final List children = new ArrayList<>(); + public final List children = new ArrayList<>(); public Consumer handler; - ForgeCommandNode(String name, int permission, boolean isArgument) { + CommandNode(String name, int permission, boolean isArgument) { this.name = name; this.permission = permission; this.isArgument = isArgument; } - void addChild(ForgeCommandNode child) { + void addChild(CommandNode child) { children.add(child); } } - private final ForgeCommandNode currentNode; + private final CommandNode currentNode; private final ICommandBuilder parent; - private final List rootNodes; + private final List rootNodes; /** Root constructor. */ - public ForgeCommandBuilder() { + public CommandBuilder() { this.currentNode = null; this.parent = null; this.rootNodes = new ArrayList<>(); } - private ForgeCommandBuilder(ForgeCommandNode currentNode, ICommandBuilder parent, - List rootNodes) { + private CommandBuilder(CommandNode currentNode, ICommandBuilder parent, + List rootNodes) { this.currentNode = currentNode; this.parent = parent; this.rootNodes = rootNodes; @@ -61,22 +61,22 @@ private ForgeCommandBuilder(ForgeCommandNode currentNode, ICommandBuilder parent @Override public ICommandBuilder literal(String name, int permission) { - ForgeCommandNode child = new ForgeCommandNode(name, permission, false); + CommandNode child = new CommandNode(name, permission, false); if (parent == null) { rootNodes.add(child); } else if (currentNode != null) { currentNode.addChild(child); } - return new ForgeCommandBuilder(child, this, rootNodes); + return new CommandBuilder(child, this, rootNodes); } @Override public ICommandBuilder argument(String name) { - ForgeCommandNode child = new ForgeCommandNode(name, 0, true); + CommandNode child = new CommandNode(name, 0, true); if (currentNode != null) { currentNode.addChild(child); } - return new ForgeCommandBuilder(child, this, rootNodes); + return new CommandBuilder(child, this, rootNodes); } @Override @@ -88,7 +88,7 @@ public ICommandBuilder executes(Consumer handler) { } /** Returns the top-level nodes built by the fluent calls. */ - public List getRootNodes() { + public List getRootNodes() { return rootNodes; } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandContext.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/CommandContext.java similarity index 83% rename from src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandContext.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/CommandContext.java index b077a32..61d9fb3 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/ForgeCommandContext.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/CommandContext.java @@ -7,19 +7,19 @@ import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; -import pl.kuba6000.ae2webintegration.ae2interface.ForgeConfig; +import pl.kuba6000.ae2webintegration.ae2interface.config.Config; import pl.kuba6000.ae2webintegration.core.api.ICommandContext; /** * {@link ICommandContext} implementation wrapping Forge 1.7.10's * {@link ICommandSender} and the raw command arguments. */ -public class ForgeCommandContext implements ICommandContext { +public class CommandContext implements ICommandContext { private final ICommandSender sender; private final String[] args; - public ForgeCommandContext(ICommandSender sender, String[] args) { + public CommandContext(ICommandSender sender, String[] args) { this.sender = sender; this.args = args; } @@ -54,12 +54,12 @@ public void sendError(String text) { /** * Returns a Runnable that re-reads the Forge config file via - * {@link ForgeConfig#synchronizeConfiguration()} and restarts the + * {@link Config#synchronizeConfiguration()} and restarts the * HTTP server. {@link pl.kuba6000.ae2webintegration.core.CommandProcessor#reload} * handles the actual stop/start — this runnable only re-reads the config. */ @Override public Runnable getReloader() { - return () -> ForgeConfig.synchronizeConfiguration(); + return () -> Config.synchronizeConfiguration(); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/Config.java similarity index 69% rename from src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/Config.java index 3d551dd..d201511 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfig.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/Config.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.ae2interface; +package pl.kuba6000.ae2webintegration.ae2interface.config; import java.io.File; @@ -10,18 +10,18 @@ * Forge 1.7.10 config wiring. This class does NOT define what config keys * exist — that is owned by {@link ConfigBootstrap}. Instead it: *

    - *
  1. Sets up the config directory via {@link #init(File)}
  2. - *
  3. Creates a {@link Configuration} from the config file
  4. - *
  5. Wraps it in a {@link ForgeConfigBuilder}
  6. - *
  7. Passes the wrapper to {@link ConfigBootstrap#init} so core defines all keys
  8. - *
  9. Saves the config if any keys were modified
  10. + *
  11. Sets up the config directory via {@link #init(File)}
  12. + *
  13. Creates a {@link Configuration} from the config file
  14. + *
  15. Wraps it in a {@link ConfigBuilder}
  16. + *
  17. Passes the wrapper to {@link ConfigBootstrap#init} so core defines all keys
  18. + *
  19. Saves the config if any keys were modified
  20. *
* * Because Forge reads values synchronously at definition time, each call to - * {@link #synchronizeConfiguration()} creates fresh {@link ForgeConfigValue} + * {@link #synchronizeConfiguration()} creates fresh {@link ConfigValue} * snapshots holding the current on-disk values. */ -public class ForgeConfig { +public class Config { private static File configDirectory; private static File configFile; @@ -40,7 +40,7 @@ public static void init(File rootConfigDirectory) { public static void synchronizeConfiguration() { Configuration configuration = new Configuration(configFile); - ConfigBootstrap.init(new ForgeConfigBuilder(configuration)); + ConfigBootstrap.init(new ConfigBuilder(configuration)); if (configuration.hasChanged()) { configuration.save(); } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigBuilder.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/ConfigBuilder.java similarity index 71% rename from src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigBuilder.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/ConfigBuilder.java index 681df1d..fef0d6b 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigBuilder.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/ConfigBuilder.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.ae2interface; +package pl.kuba6000.ae2webintegration.ae2interface.config; import net.minecraftforge.common.config.Configuration; @@ -12,17 +12,17 @@ * Unlike NeoForge's lazy {@code ConfigValue}, Forge reads config values * synchronously at definition time. Each {@code defineXxx} call invokes * {@code configuration.getXxx(...)} immediately and returns a snapshot-based - * {@link ForgeConfigValue} holding the result. + * {@link ConfigValue} holding the result. *

* Config keys are mapped to the same categories ("general", "discord", * "tracking") that the old {@code ConfigKey} enum used, preserving the * existing config file structure across upgrades. */ -public class ForgeConfigBuilder implements IConfigBuilder { +public class ConfigBuilder implements IConfigBuilder { private final Configuration configuration; - public ForgeConfigBuilder(Configuration configuration) { + public ConfigBuilder(Configuration configuration) { this.configuration = configuration; } @@ -34,16 +34,16 @@ private static String category(String key) { @Override public IConfigValue defineInt(String key, int defaultValue, int min, int max, String comment) { - return new ForgeConfigValue<>(configuration.getInt(key, category(key), defaultValue, min, max, comment)); + return new ConfigValue<>(configuration.getInt(key, category(key), defaultValue, min, max, comment)); } @Override public IConfigValue defineString(String key, String defaultValue, String comment) { - return new ForgeConfigValue<>(configuration.getString(key, category(key), defaultValue, comment)); + return new ConfigValue<>(configuration.getString(key, category(key), defaultValue, comment)); } @Override public IConfigValue defineBoolean(String key, boolean defaultValue, String comment) { - return new ForgeConfigValue<>(configuration.getBoolean(key, category(key), defaultValue, comment)); + return new ConfigValue<>(configuration.getBoolean(key, category(key), defaultValue, comment)); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigValue.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/ConfigValue.java similarity index 73% rename from src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigValue.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/ConfigValue.java index b93ea0a..76a112f 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgeConfigValue.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/ConfigValue.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.ae2interface; +package pl.kuba6000.ae2webintegration.ae2interface.config; import pl.kuba6000.ae2webintegration.core.api.IConfigValue; @@ -9,15 +9,15 @@ * Forge reads config values at definition time (unlike NeoForge's lazy * {@code ConfigValue}), so this class stores the value returned by the * {@code configuration.getXxx(...)} call. On reload a new - * {@code ForgeConfigValue} is created with the re-read value. + * {@code ConfigValue} is created with the re-read value. * * @param the value type (Integer, String, Boolean) */ -public class ForgeConfigValue implements IConfigValue { +public class ConfigValue implements IConfigValue { private final T value; - ForgeConfigValue(T value) { + ConfigValue(T value) { this.value = value; } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlatform.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/platform/Platform.java similarity index 89% rename from src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlatform.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/platform/Platform.java index 5cdbb00..e6a5040 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ForgePlatform.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/platform/Platform.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.ae2interface; +package pl.kuba6000.ae2webintegration.ae2interface.platform; import java.io.File; import java.util.UUID; @@ -10,11 +10,11 @@ import cpw.mods.fml.common.FMLCommonHandler; import pl.kuba6000.ae2webintegration.core.api.IServerPlatform; -public class ForgePlatform implements IServerPlatform { +public class Platform implements IServerPlatform { private final File configDir; - public ForgePlatform(File configDir) { + public Platform(File configDir) { this.configDir = configDir; } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ClientProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/proxy/ClientProxy.java similarity index 79% rename from src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ClientProxy.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/proxy/ClientProxy.java index df7254a..fda304a 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/ClientProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/proxy/ClientProxy.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.ae2interface; +package pl.kuba6000.ae2webintegration.ae2interface.proxy; public class ClientProxy extends CommonProxy { diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/proxy/CommonProxy.java similarity index 77% rename from src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java rename to src/main/java/pl/kuba6000/ae2webintegration/ae2interface/proxy/CommonProxy.java index 5267b9f..12ada30 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/proxy/CommonProxy.java @@ -1,4 +1,4 @@ -package pl.kuba6000.ae2webintegration.ae2interface; +package pl.kuba6000.ae2webintegration.ae2interface.proxy; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.event.FMLInitializationEvent; @@ -8,8 +8,12 @@ import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.event.FMLServerStoppingEvent; import pl.kuba6000.ae2webintegration.Tags; +import pl.kuba6000.ae2webintegration.ae2interface.AE2WebIntegration; +import pl.kuba6000.ae2webintegration.ae2interface.FMLEventHandler; import pl.kuba6000.ae2webintegration.ae2interface.commands.BaseCommandHandler; -import pl.kuba6000.ae2webintegration.ae2interface.commands.ForgeCommandBuilder; +import pl.kuba6000.ae2webintegration.ae2interface.commands.CommandBuilder; +import pl.kuba6000.ae2webintegration.ae2interface.config.Config; +import pl.kuba6000.ae2webintegration.ae2interface.platform.Platform; import pl.kuba6000.ae2webintegration.core.AE2Controller; import pl.kuba6000.ae2webintegration.core.CommandBootstrap; import pl.kuba6000.ae2webintegration.core.GridData; @@ -22,10 +26,10 @@ public class CommonProxy { // preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the // GameRegistry." (Remove if not needed) public void preInit(FMLPreInitializationEvent event) { - ForgeConfig.init(event.getModConfigurationDirectory()); - ForgeConfig.synchronizeConfiguration(); + Config.init(event.getModConfigurationDirectory()); + Config.synchronizeConfiguration(); WebEngine.init( - new ForgePlatform(new java.io.File(event.getModConfigurationDirectory(), "ae2webintegration")), + new Platform(new java.io.File(event.getModConfigurationDirectory(), "ae2webintegration")), Tags.VERSION); WebData.loadData(); GridData.loadData(); @@ -46,7 +50,7 @@ public void postInit(FMLPostInitializationEvent event) {} // register server commands in this event handler (Remove if not needed) public void serverStarting(FMLServerStartingEvent event) { - ForgeCommandBuilder builder = new ForgeCommandBuilder(); + CommandBuilder builder = new CommandBuilder(); CommandBootstrap.init(builder); event.registerServerCommand(new BaseCommandHandler(builder.getRootNodes())); } From 810b590940626a837240bfa00ea7720f9b65fe8b Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Fri, 15 May 2026 01:08:56 +0200 Subject: [PATCH 24/29] spotlessApply --- core | 2 +- .../ae2interface/commands/CommandBuilder.java | 3 +-- .../ae2webintegration/ae2interface/config/Config.java | 10 +++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/core b/core index 995ad61..894bbd7 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 995ad6128b378595a41a041132a25ac788064a09 +Subproject commit 894bbd7340ba5afd7e93b9aaeb5e170ef8b92c86 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/CommandBuilder.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/CommandBuilder.java index 06cebab..0bee4c7 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/CommandBuilder.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/commands/CommandBuilder.java @@ -52,8 +52,7 @@ public CommandBuilder() { this.rootNodes = new ArrayList<>(); } - private CommandBuilder(CommandNode currentNode, ICommandBuilder parent, - List rootNodes) { + private CommandBuilder(CommandNode currentNode, ICommandBuilder parent, List rootNodes) { this.currentNode = currentNode; this.parent = parent; this.rootNodes = rootNodes; diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/Config.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/Config.java index d201511..4ae85d7 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/Config.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/config/Config.java @@ -10,11 +10,11 @@ * Forge 1.7.10 config wiring. This class does NOT define what config keys * exist — that is owned by {@link ConfigBootstrap}. Instead it: *

    - *
  1. Sets up the config directory via {@link #init(File)}
  2. - *
  3. Creates a {@link Configuration} from the config file
  4. - *
  5. Wraps it in a {@link ConfigBuilder}
  6. - *
  7. Passes the wrapper to {@link ConfigBootstrap#init} so core defines all keys
  8. - *
  9. Saves the config if any keys were modified
  10. + *
  11. Sets up the config directory via {@link #init(File)}
  12. + *
  13. Creates a {@link Configuration} from the config file
  14. + *
  15. Wraps it in a {@link ConfigBuilder}
  16. + *
  17. Passes the wrapper to {@link ConfigBootstrap#init} so core defines all keys
  18. + *
  19. Saves the config if any keys were modified
  20. *
* * Because Forge reads values synchronously at definition time, each call to From 266aecffed0e5f91d94aaabae0ef6e559a9f7291 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sat, 16 May 2026 15:38:42 +0200 Subject: [PATCH 25/29] Set VERSION_IDENTIFIER to -forge-1.7.10 in CommonProxy preInit --- core | 2 +- .../ae2webintegration/ae2interface/proxy/CommonProxy.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core b/core index 894bbd7..93d2113 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 894bbd7340ba5afd7e93b9aaeb5e170ef8b92c86 +Subproject commit 93d2113a1b5b5ee582e8654e5bcc0b5cc81f6368 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/proxy/CommonProxy.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/proxy/CommonProxy.java index 12ada30..a2514c2 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/proxy/CommonProxy.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/proxy/CommonProxy.java @@ -20,12 +20,14 @@ import pl.kuba6000.ae2webintegration.core.StartupHandler; import pl.kuba6000.ae2webintegration.core.WebData; import pl.kuba6000.ae2webintegration.core.WebEngine; +import pl.kuba6000.ae2webintegration.core.utils.VersionChecker; public class CommonProxy { // preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the // GameRegistry." (Remove if not needed) public void preInit(FMLPreInitializationEvent event) { + VersionChecker.setVersionIdentifier("-forge-1.7.10"); Config.init(event.getModConfigurationDirectory()); Config.synchronizeConfiguration(); WebEngine.init( From 6e6a8404236839ca4d1ac9dc669f340f410ad8e7 Mon Sep 17 00:00:00 2001 From: kuba6000 Date: Sat, 16 May 2026 16:03:18 +0200 Subject: [PATCH 26/29] Update core submodule (UTF-8 encoding fix) --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index 93d2113..00d3453 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 93d2113a1b5b5ee582e8654e5bcc0b5cc81f6368 +Subproject commit 00d34534fac216915e24940bcce195c95accd478 From 9f00eed2b20394fac38fa481fa105516f203cb72 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 27 May 2026 17:22:21 +0200 Subject: [PATCH 27/29] update core --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index 00d3453..4ef658b 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 00d34534fac216915e24940bcce195c95accd478 +Subproject commit 4ef658b49be6ca58b17a9c63ecc40ba9d2b80f35 From f2ad0e2e259ce5a17f7a294f331ad847468b4e3d Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 9 Jun 2026 23:19:05 +0200 Subject: [PATCH 28/29] Update core --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index 4ef658b..69330d7 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 4ef658b49be6ca58b17a9c63ecc40ba9d2b80f35 +Subproject commit 69330d71e1a22699d9054deb18bd9244393c819a From 373a3e0ba689ef8233b563a8a874d7a7655a1329 Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 9 Jun 2026 23:23:38 +0200 Subject: [PATCH 29/29] Fix fluid crafting in interface mixins and update core submodule. Use IAEStack overload for beginCraftingJob, fix IAEKey inventory ops for fluids, drop redundant PlayerIdentity cast. --- core | 2 +- .../AE2/implementations/AEMeInventoryItemMixin.java | 8 +++----- .../AE2/implementations/service/AECraftingGridMixin.java | 7 ++++--- .../AE2/implementations/service/AESecurityGridMixin.java | 3 +-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/core b/core index 69330d7..eb7a313 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 69330d71e1a22699d9054deb18bd9244393c819a +Subproject commit eb7a31329a458cb32dc110581e333a029e4e93e0 diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java index 2e79746..3dfd3bd 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/AEMeInventoryItemMixin.java @@ -5,7 +5,6 @@ import appeng.api.config.Actionable; import appeng.api.networking.security.BaseActionSource; import appeng.api.storage.IMEInventory; -import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEStack; import pl.kuba6000.ae2webintegration.core.api.AEApi.AEActionable; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; @@ -32,10 +31,9 @@ public interface AEMeInventoryItemMixin extends IAEMeInventoryItem { @Override @SuppressWarnings("unchecked") public default long web$extractItems(IAEKey stack, long amount, AEActionable mode, IAEGrid grid) { - IAEItemStack template = (IAEItemStack) (Object) stack; - template = template.copy(); + IAEStack template = ((IAEStack) (Object) stack).copy(); template.setStackSize(amount); - IAEItemStack extracted = (IAEItemStack) ((IMEInventory) (Object) this).extractItems( + IAEStack extracted = ((IMEInventory) (Object) this).extractItems( template, mode == AEActionable.MODULATE ? Actionable.MODULATE : Actionable.SIMULATE, (BaseActionSource) grid.web$getPlayerSource()); @@ -45,7 +43,7 @@ public interface AEMeInventoryItemMixin extends IAEMeInventoryItem { @Override @SuppressWarnings("unchecked") public default long web$getAvailableItem(IAEKey stack, IAEGrid grid) { - IAEItemStack found = (IAEItemStack) ((IMEInventory) (Object) this).getAvailableItem((IAEStack) (Object) stack); + IAEStack found = (IAEStack) ((IMEInventory) (Object) this).getAvailableItem((IAEStack) (Object) stack); return found == null ? 0 : found.getStackSize(); } } diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java index 04f689a..3773202 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AECraftingGridMixin.java @@ -17,7 +17,7 @@ import appeng.api.networking.crafting.ICraftingLink; import appeng.api.networking.security.BaseActionSource; import appeng.api.networking.security.PlayerSource; -import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; import pl.kuba6000.ae2webintegration.core.interfaces.IAECraftingJob; import pl.kuba6000.ae2webintegration.core.interfaces.IAEGrid; import pl.kuba6000.ae2webintegration.core.interfaces.IAEKey; @@ -48,10 +48,11 @@ public interface AECraftingGridMixin extends IAECraftingGrid { } @Override + @SuppressWarnings("unchecked") public default Future web$beginCraftingJob(IAEGrid grid, IStack stack) { PlayerSource actionSrc = (PlayerSource) grid.web$getPlayerSource(); final Future job = ((ICraftingGrid) (Object) this) - .beginCraftingJob(actionSrc.player.worldObj, (IGrid) grid, actionSrc, (IAEItemStack) stack, null); + .beginCraftingJob(actionSrc.player.worldObj, (IGrid) grid, actionSrc, (IAEStack) (Object) stack, null); return (Future) (Object) job; } @@ -73,7 +74,7 @@ public interface AECraftingGridMixin extends IAECraftingGrid { @SuppressWarnings("unchecked") public default Future web$beginCraftingJob(IAEGrid grid, IAEKey stack, long amount) { PlayerSource actionSrc = (PlayerSource) grid.web$getPlayerSource(); - IAEItemStack aeStack = (IAEItemStack) (Object) stack; + IAEStack aeStack = ((IAEStack) (Object) stack).copy(); aeStack.setStackSize(amount); final Future job = ((ICraftingGrid) (Object) this) .beginCraftingJob(actionSrc.player.worldObj, (IGrid) grid, actionSrc, aeStack, null); diff --git a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java index fa734d3..6c4fc52 100644 --- a/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java +++ b/src/main/java/pl/kuba6000/ae2webintegration/ae2interface/mixins/AE2/implementations/service/AESecurityGridMixin.java @@ -10,7 +10,6 @@ import appeng.api.config.SecurityPermissions; import appeng.core.worlddata.WorldData; import appeng.me.cache.SecurityCache; -import pl.kuba6000.ae2webintegration.core.api.PlayerIdentity; import pl.kuba6000.ae2webintegration.core.interfaces.IAEPlayerData; import pl.kuba6000.ae2webintegration.core.interfaces.service.IAESecurityGrid; @@ -40,7 +39,7 @@ public class AESecurityGridMixin implements IAESecurityGrid { public pl.kuba6000.ae2webintegration.core.api.PlayerIdentity web$getOwnerProfile() { IAEPlayerData playerData = (IAEPlayerData) WorldData.instance() .playerData(); - return (PlayerIdentity) playerData.web$getPlayerProfile(web$getOwner()); + return playerData.web$getPlayerProfile(web$getOwner()); } @Override