diff --git a/build.gradle b/build.gradle index ba50ebc5..0c573546 100644 --- a/build.gradle +++ b/build.gradle @@ -111,6 +111,12 @@ repositories { includeGroup "curse.maven" } } + maven { + url "https://squiddev.cc/maven/" + content { + includeGroup("cc.tweaked") + } + } mavenCentral() } @@ -151,6 +157,10 @@ dependencies { exclude group: "it.unimi.dsi", module: "fastutil" } implementation fg.deobf("icyllis.modernui:ModernUI-Forge:${minecraft_version}-${modernui_forge_version}") + + compileOnly("cc.tweaked:cc-tweaked-${minecraft_version}-core-api:1.110.3") + compileOnly(fg.deobf("cc.tweaked:cc-tweaked-${minecraft_version}-forge-api:1.110.3")) + runtimeOnly(fg.deobf("cc.tweaked:cc-tweaked-${minecraft_version}-forge:1.110.3")) } processResources { diff --git a/src/main/java/sonar/fluxnetworks/FluxNetworks.java b/src/main/java/sonar/fluxnetworks/FluxNetworks.java index 8b060e69..51316178 100644 --- a/src/main/java/sonar/fluxnetworks/FluxNetworks.java +++ b/src/main/java/sonar/fluxnetworks/FluxNetworks.java @@ -5,6 +5,7 @@ import net.minecraftforge.fml.common.Mod; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import sonar.fluxnetworks.common.integration.cctweaked.PeripheralHandlerWrapper; import javax.annotation.Nonnull; @@ -19,12 +20,17 @@ public class FluxNetworks { private static boolean sCuriosLoaded; private static boolean sModernUILoaded; + private static boolean sComputercraftLoaded; public FluxNetworks() { sCuriosLoaded = ModList.get().isLoaded("curios"); sModernUILoaded = ModList.get().isLoaded("modernui"); + sComputercraftLoaded = ModList.get().isLoaded("computercraft"); FluxConfig.init(); + + if (sComputercraftLoaded) + PeripheralHandlerWrapper.init(); } public static boolean isCuriosLoaded() { @@ -34,6 +40,9 @@ public static boolean isCuriosLoaded() { public static boolean isModernUILoaded() { return sModernUILoaded; } + public static boolean issComputercraftLoaded() { + return sComputercraftLoaded; + } @Nonnull public static ResourceLocation location(String path) { diff --git a/src/main/java/sonar/fluxnetworks/common/integration/cctweaked/CCTPeripheral.java b/src/main/java/sonar/fluxnetworks/common/integration/cctweaked/CCTPeripheral.java new file mode 100644 index 00000000..ec8d361d --- /dev/null +++ b/src/main/java/sonar/fluxnetworks/common/integration/cctweaked/CCTPeripheral.java @@ -0,0 +1,184 @@ +package sonar.fluxnetworks.common.integration.cctweaked; + +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.lua.ObjectLuaTable; +import dan200.computercraft.api.peripheral.IPeripheral; +import org.jetbrains.annotations.Nullable; +import sonar.fluxnetworks.api.device.IFluxDevice; +import sonar.fluxnetworks.common.device.TileFluxDevice; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +public class CCTPeripheral implements IPeripheral { + + record NetworkMemberRecord(String name, String accessLevel) { + } + + record NetworkDeviceRecord( + String type, + long maxTransferLimit, + boolean isChunkLoaded, + + boolean isForcedChunkLoaded, + String customName, + boolean limitDisabled, + + Map position, + boolean surgeMode, + long transferBuffer, + long transferChange + ) {} + + private final TileFluxDevice device; + + public CCTPeripheral(TileFluxDevice device) { + this.device = device; + } + + @Override + public String getType() { + return "flux-device"; + } + + @Override + public boolean equals(@Nullable IPeripheral other) { + return false; + } + + @LuaFunction(mainThread = true) + public String getNetworkName() { + if (!isValid()) return null; + + String name = device.getNetwork().getNetworkName(); + if (name.isEmpty()) + return null; + return name; + } + + private Map objectToMap(Object object) { + Map map = new HashMap<>(); + Field[] fields = object.getClass().getDeclaredFields(); + + for (Field field: fields) { + field.setAccessible(true); + try { + map.put(field.getName(), field.get(object)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + return map; + } + + @LuaFunction(mainThread = true) + public int getNetworkID() { + return device.getNetwork().getNetworkID(); + } + + @LuaFunction(mainThread = true) + public long getEnergyInput() { + return device.getNetwork().getStatistics().energyInput; + } + + @LuaFunction(mainThread = true) + public long getEnergyOutput() { + return device.getNetwork().getStatistics().energyOutput; + } + + @LuaFunction(mainThread = true) + public long getEnergy() { + return device.getNetwork().getStatistics().totalEnergy; + } + + @LuaFunction(mainThread = true) + public long getEnergyBuffer() { + return device.getNetwork().getStatistics().totalBuffer; + } + + @LuaFunction(mainThread = true) + public long getPlugsCount() { + return device.getNetwork().getStatistics().fluxPlugCount; + } + + @LuaFunction(mainThread = true) + public long getPointCount() { + return device.getNetwork().getStatistics().fluxPointCount; + } + + @LuaFunction(mainThread = true) + public long getStorageCount() { + return device.getNetwork().getStatistics().fluxStorageCount; + } + + @LuaFunction(mainThread = true) + public long getControllerCount() { + return device.getNetwork().getStatistics().fluxControllerCount; + } + + @LuaFunction(mainThread = true) + public long getAVGTickUs() { + return device.getNetwork().getStatistics().averageTickMicro; + } + + @LuaFunction(mainThread = true) + public String getSecurityLevel() { + return device.getNetwork().getSecurityLevel().toString(); + } + + @LuaFunction(mainThread = true) + public String getOwner() { + if (!isValid()) return null; + + return device.getNetwork().getOwnerUUID().toString(); + } + + @LuaFunction(mainThread = true) + public ObjectLuaTable getMembers() { + if (!isValid()) return null; + + return new ObjectLuaTable( + device.getNetwork().getAllMembers().stream().collect(Collectors.toMap( + item -> item.getPlayerUUID().toString(), + item -> objectToMap(new NetworkMemberRecord(item.getCachedName(), item.getAccessLevel().toString())) + ) + ) + ); + } + + @LuaFunction(mainThread = true) + public ObjectLuaTable getConnections() { + if (!isValid()) return null; + + Map map = new HashMap<>(); + int i = 0; + for (IFluxDevice device : device.getNetwork().getAllConnections()) { + map.put( + i++, + objectToMap( + new NetworkDeviceRecord( + device.getDeviceType().toString(), + device.getMaxTransferLimit(), + device.isChunkLoaded(), + device.isForcedLoading(), + device.getCustomName(), + device.getDisableLimit(), + objectToMap(device.getGlobalPos()), + device.getSurgeMode(), + device.getTransferBuffer(), + device.getTransferChange() + ) + ) + ); + } + + return new ObjectLuaTable(map); + } + + @LuaFunction(mainThread = true) + public boolean isValid() { + return device.getNetwork().isValid(); + } +} diff --git a/src/main/java/sonar/fluxnetworks/common/integration/cctweaked/PeripheralHandler.java b/src/main/java/sonar/fluxnetworks/common/integration/cctweaked/PeripheralHandler.java new file mode 100644 index 00000000..c7580856 --- /dev/null +++ b/src/main/java/sonar/fluxnetworks/common/integration/cctweaked/PeripheralHandler.java @@ -0,0 +1,22 @@ +package sonar.fluxnetworks.common.integration.cctweaked; + +import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.api.peripheral.IPeripheralProvider; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraftforge.common.util.LazyOptional; +import sonar.fluxnetworks.common.device.TileFluxController; +import sonar.fluxnetworks.common.device.TileFluxDevice; + +public class PeripheralHandler implements IPeripheralProvider { + + @Override + public LazyOptional getPeripheral(Level world, BlockPos pos, Direction side) { + BlockEntity tile = world.getBlockEntity(pos); + + if (tile instanceof TileFluxDevice fluxDevice) return LazyOptional.of(() -> new CCTPeripheral(fluxDevice)); + return LazyOptional.empty(); + } +} \ No newline at end of file diff --git a/src/main/java/sonar/fluxnetworks/common/integration/cctweaked/PeripheralHandlerWrapper.java b/src/main/java/sonar/fluxnetworks/common/integration/cctweaked/PeripheralHandlerWrapper.java new file mode 100644 index 00000000..a5e789fb --- /dev/null +++ b/src/main/java/sonar/fluxnetworks/common/integration/cctweaked/PeripheralHandlerWrapper.java @@ -0,0 +1,16 @@ +package sonar.fluxnetworks.common.integration.cctweaked; + +import dan200.computercraft.api.ForgeComputerCraftAPI; + +/** + * This class exists, so we do not import PeripheralHandler directly into the FluxNetworks class + * as PeripheralHandler implements a computercraft class. This would break if the computercraft mod + * is not available + */ +public class PeripheralHandlerWrapper { + + public static void init() { + ForgeComputerCraftAPI.registerPeripheralProvider(new PeripheralHandler()); + } + +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 3965f801..40df1a39 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -31,6 +31,12 @@ license="MIT" versionRange="[3.7.0,)" ordering="NONE" side="BOTH" +[[dependencies.fluxnetworks]] + modId="computercraft" + mandatory=false + versionRange="[1.110.3,)" + ordering="NONE" + side="BOTH" [[dependencies.fluxnetworks]] modId="jei" mandatory=false