diff --git a/build.gradle b/build.gradle
index 3a992c35b..a260bd0d2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -127,9 +127,6 @@ accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3")
- compileOnly 'com.google.auto.service:auto-service:1.0-rc7'
- annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'
-
shade 'org.squiddev:Cobalt:0.5.2-SNAPSHOT'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
@@ -140,7 +137,7 @@ accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
testImplementation 'org.jetbrains.kotlin:kotlin-reflect:1.3.72'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
- cctJavadoc 'cc.tweaked:cct-javadoc:1.3.0'
+ cctJavadoc 'cc.tweaked:cct-javadoc:1.4.0'
}
// Compile tasks
diff --git a/src/main/java/dan200/computercraft/ComputerCraft.java b/src/main/java/dan200/computercraft/ComputerCraft.java
index 70eab1e72..a51773124 100644
--- a/src/main/java/dan200/computercraft/ComputerCraft.java
+++ b/src/main/java/dan200/computercraft/ComputerCraft.java
@@ -8,7 +8,6 @@
import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.http.options.Action;
import dan200.computercraft.core.apis.http.options.AddressRule;
-import dan200.computercraft.core.asm.GenericSource;
import dan200.computercraft.shared.Config;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
@@ -17,7 +16,6 @@
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
import dan200.computercraft.shared.turtle.upgrades.*;
-import dan200.computercraft.shared.util.ServiceUtil;
import net.minecraftforge.fml.common.Mod;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -117,6 +115,5 @@ public ComputerCraft()
{
Config.setup();
Registry.setup();
- GenericSource.setup( () -> ServiceUtil.loadServicesForge( GenericSource.class ) );
}
}
diff --git a/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java b/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java
index 116b3135b..351fd3b91 100644
--- a/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java
+++ b/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java
@@ -8,6 +8,7 @@
import dan200.computercraft.api.ComputerCraftAPI.IComputerCraftAPI;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount;
+import dan200.computercraft.api.lua.GenericSource;
import dan200.computercraft.api.lua.ILuaAPIFactory;
import dan200.computercraft.api.media.IMediaProvider;
import dan200.computercraft.api.network.IPacketNetwork;
@@ -18,9 +19,11 @@
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.core.apis.ApiFactories;
+import dan200.computercraft.core.asm.GenericMethod;
import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.*;
+import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.wired.WiredNode;
@@ -31,6 +34,7 @@
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
+import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
@@ -108,6 +112,18 @@ public void registerPeripheralProvider( @Nonnull IPeripheralProvider provider )
Peripherals.register( provider );
}
+ @Override
+ public void registerGenericSource( @Nonnull GenericSource source )
+ {
+ GenericMethod.register( source );
+ }
+
+ @Override
+ public void registerGenericCapability( @Nonnull Capability> capability )
+ {
+ GenericPeripheralProvider.addCapability( capability );
+ }
+
@Override
public void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade )
{
diff --git a/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java b/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java
index 2c4223725..e7f05ab33 100644
--- a/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java
+++ b/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java
@@ -7,6 +7,7 @@
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount;
+import dan200.computercraft.api.lua.GenericSource;
import dan200.computercraft.api.lua.ILuaAPIFactory;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.media.IMediaProvider;
@@ -23,6 +24,7 @@
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
+import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
@@ -116,7 +118,7 @@ public static IMount createResourceMount( @Nonnull String domain, @Nonnull Strin
}
/**
- * Registers a peripheral provider to convert blocks into {@link IPeripheral} implementations.
+ * rers a peripheral provider to convert blocks into {@link IPeripheral} implementations.
*
* @param provider The peripheral provider to register.
* @see IPeripheral
@@ -127,6 +129,28 @@ public static void registerPeripheralProvider( @Nonnull IPeripheralProvider prov
getInstance().registerPeripheralProvider( provider );
}
+ /**
+ * Registers a method source for generic peripherals.
+ *
+ * @param source The method source to register.
+ * @see GenericSource
+ */
+ public static void registerGenericSource( @Nonnull GenericSource source )
+ {
+ getInstance().registerGenericSource( source );
+ }
+
+ /**
+ * Registers a capability that can be used by generic peripherals.
+ *
+ * @param capability The capability to register.
+ * @see GenericSource
+ */
+ public static void registerGenericCapability( @Nonnull Capability> capability )
+ {
+ getInstance().registerGenericCapability( capability );
+ }
+
/**
* Registers a new turtle turtle for use in ComputerCraft. After calling this,
* users should be able to craft Turtles with your new turtle. It is recommended to call
@@ -258,6 +282,10 @@ public interface IComputerCraftAPI
void registerPeripheralProvider( @Nonnull IPeripheralProvider provider );
+ void registerGenericSource( @Nonnull GenericSource source );
+
+ void registerGenericCapability( @Nonnull Capability> capability );
+
void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade );
void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider );
diff --git a/src/main/java/dan200/computercraft/api/lua/GenericSource.java b/src/main/java/dan200/computercraft/api/lua/GenericSource.java
new file mode 100644
index 000000000..f5a3178a3
--- /dev/null
+++ b/src/main/java/dan200/computercraft/api/lua/GenericSource.java
@@ -0,0 +1,60 @@
+/*
+ * This file is part of ComputerCraft - http://www.computercraft.info
+ * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
+ * Send enquiries to dratcliffe@gmail.com
+ */
+package dan200.computercraft.api.lua;
+
+import dan200.computercraft.api.ComputerCraftAPI;
+import dan200.computercraft.api.peripheral.IPeripheral;
+import dan200.computercraft.api.peripheral.IPeripheralProvider;
+import dan200.computercraft.core.asm.LuaMethod;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.common.capabilities.Capability;
+import net.minecraftforge.items.IItemHandler;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A generic source of {@link LuaMethod} functions.
+ *
+ * Unlike normal objects ({@link IDynamicLuaObject} or {@link IPeripheral}), methods do not target this object but
+ * instead are defined as {@code static} and accept their target as the first parameter. This allows you to inject
+ * methods onto objects you do not own, as well as declaring methods for a specific "trait" (for instance, a
+ * {@link Capability}).
+ *
+ * Currently the "generic peripheral" system is incompatible with normal peripherals. Normal {@link IPeripheralProvider}
+ * or {@link IPeripheral} implementations take priority. Tile entities which use this system are given a peripheral name
+ * determined by their id, rather than any peripheral provider. This will hopefully change in the future, once a suitable
+ * design has been established.
+ *
+ * For example, the main CC: Tweaked mod defines a generic source for inventories, which works on {@link IItemHandler}s:
+ *
+ *
{@code
+ * public class InventoryMethods implements GenericSource {
+ * @LuaFunction( mainThread = true )
+ * public static int size(IItemHandler inventory) {
+ * return inventory.getSlots();
+ * }
+ *
+ * // ...
+ * }
+ * }
+ *
+ * @see ComputerCraftAPI#registerGenericSource(GenericSource)
+ * @see ComputerCraftAPI#registerGenericCapability(Capability) New capabilities (those not built into Forge) must be
+ * explicitly given to the generic peripheral system, as there is no way to enumerate all capabilities.
+ */
+public interface GenericSource
+{
+ /**
+ * A unique identifier for this generic source.
+ *
+ * This is currently unused, but may be used in the future to allow disabling specific sources. It is recommended
+ * to return an identifier using your mod's ID.
+ *
+ * @return This source's identifier.
+ */
+ @Nonnull
+ ResourceLocation id();
+}
diff --git a/src/main/java/dan200/computercraft/core/asm/Generator.java b/src/main/java/dan200/computercraft/core/asm/Generator.java
index c559c4112..c630b140f 100644
--- a/src/main/java/dan200/computercraft/core/asm/Generator.java
+++ b/src/main/java/dan200/computercraft/core/asm/Generator.java
@@ -11,10 +11,7 @@
import com.google.common.primitives.Primitives;
import com.google.common.reflect.TypeToken;
import dan200.computercraft.ComputerCraft;
-import dan200.computercraft.api.lua.IArguments;
-import dan200.computercraft.api.lua.LuaException;
-import dan200.computercraft.api.lua.LuaFunction;
-import dan200.computercraft.api.lua.MethodResult;
+import dan200.computercraft.api.lua.*;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
@@ -111,7 +108,7 @@ private List> build( Class> klass )
addMethod( methods, method, annotation, instance );
}
- for( GenericSource.GenericMethod method : GenericSource.GenericMethod.all() )
+ for( GenericMethod method : GenericMethod.all() )
{
if( !method.target.isAssignableFrom( klass ) ) continue;
diff --git a/src/main/java/dan200/computercraft/core/asm/GenericMethod.java b/src/main/java/dan200/computercraft/core/asm/GenericMethod.java
new file mode 100644
index 000000000..ebd589112
--- /dev/null
+++ b/src/main/java/dan200/computercraft/core/asm/GenericMethod.java
@@ -0,0 +1,85 @@
+package dan200.computercraft.core.asm;
+
+import dan200.computercraft.ComputerCraft;
+import dan200.computercraft.api.lua.GenericSource;
+import dan200.computercraft.api.lua.LuaFunction;
+
+import javax.annotation.Nonnull;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * A generic method is a method belonging to a {@link GenericSource} with a known target.
+ */
+public class GenericMethod
+{
+ final Method method;
+ final LuaFunction annotation;
+ final Class> target;
+
+ private static final List sources = new ArrayList<>();
+ private static List cache;
+
+ GenericMethod( Method method, LuaFunction annotation, Class> target )
+ {
+ this.method = method;
+ this.annotation = annotation;
+ this.target = target;
+ }
+
+ /**
+ * Find all public static methods annotated with {@link LuaFunction} which belong to a {@link GenericSource}.
+ *
+ * @return All available generic methods.
+ */
+ static List all()
+ {
+ if( cache != null ) return cache;
+ return cache = sources.stream()
+ .flatMap( x -> Arrays.stream( x.getClass().getDeclaredMethods() ) )
+ .map( method ->
+ {
+ LuaFunction annotation = method.getAnnotation( LuaFunction.class );
+ if( annotation == null ) return null;
+
+ if( !Modifier.isStatic( method.getModifiers() ) )
+ {
+ ComputerCraft.log.error( "GenericSource method {}.{} should be static.", method.getDeclaringClass(), method.getName() );
+ return null;
+ }
+
+ Type[] types = method.getGenericParameterTypes();
+ if( types.length == 0 )
+ {
+ ComputerCraft.log.error( "GenericSource method {}.{} has no parameters.", method.getDeclaringClass(), method.getName() );
+ return null;
+ }
+
+ Class> target = Reflect.getRawType( method, types[0], false );
+ if( target == null ) return null;
+
+ return new GenericMethod( method, annotation, target );
+ } )
+ .filter( Objects::nonNull )
+ .collect( Collectors.toList() );
+ }
+
+
+ public static synchronized void register( @Nonnull GenericSource source )
+ {
+ Objects.requireNonNull( source, "Source cannot be null" );
+
+ if( cache != null )
+ {
+ ComputerCraft.log.warn( "Registering a generic source {} after cache has been built. This source will be ignored.", cache );
+ }
+
+ sources.add( source );
+ }
+}
diff --git a/src/main/java/dan200/computercraft/core/asm/GenericSource.java b/src/main/java/dan200/computercraft/core/asm/GenericSource.java
deleted file mode 100644
index ff28ea6e1..000000000
--- a/src/main/java/dan200/computercraft/core/asm/GenericSource.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * This file is part of ComputerCraft - http://www.computercraft.info
- * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
- * Send enquiries to dratcliffe@gmail.com
- */
-package dan200.computercraft.core.asm;
-
-import dan200.computercraft.ComputerCraft;
-import dan200.computercraft.api.lua.LuaFunction;
-import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
-import dan200.computercraft.shared.util.ServiceUtil;
-import net.minecraft.util.ResourceLocation;
-
-import javax.annotation.Nonnull;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * A generic source of {@link LuaMethod} functions. This allows for injecting methods onto objects you do not own.
- *
- * Unlike conventional Lua objects, the annotated methods should be {@code static}, with their target as the first
- * parameter.
- *
- * This is used by the generic peripheral system ({@link GenericPeripheralProvider}) to provide methods for arbitrary
- * tile entities. Eventually this'll be be exposed in the public API. Until it is stabilised, it will remain in this
- * package - do not use it in external mods!
- */
-public interface GenericSource
-{
- /**
- * A unique identifier for this generic source. This may be used in the future to allow disabling specific sources.
- *
- * @return This source's identifier.
- */
- @Nonnull
- ResourceLocation id();
-
- /**
- * Register a stream of generic sources.
- *
- * @param sources The source of generic methods.
- * @see ServiceUtil For ways to load this. Sadly {@link java.util.ServiceLoader} is broken under Forge, but we don't
- * want to add a hard-dep on Forge within core either.
- */
- static void setup( Supplier> sources )
- {
- GenericMethod.sources = sources;
- }
-
- /**
- * A generic method is a method belonging to a {@link GenericSource} with a known target.
- */
- class GenericMethod
- {
- final Method method;
- final LuaFunction annotation;
- final Class> target;
-
- static Supplier> sources;
- private static List cache;
-
- GenericMethod( Method method, LuaFunction annotation, Class> target )
- {
- this.method = method;
- this.annotation = annotation;
- this.target = target;
- }
-
- /**
- * Find all public static methods annotated with {@link LuaFunction} which belong to a {@link GenericSource}.
- *
- * @return All available generic methods.
- */
- static List all()
- {
- if( cache != null ) return cache;
- if( sources == null )
- {
- ComputerCraft.log.warn( "Getting GenericMethods without a provider" );
- return cache = Collections.emptyList();
- }
-
- return cache = sources.get()
- .flatMap( x -> Arrays.stream( x.getClass().getDeclaredMethods() ) )
- .map( method ->
- {
- LuaFunction annotation = method.getAnnotation( LuaFunction.class );
- if( annotation == null ) return null;
-
- if( !Modifier.isStatic( method.getModifiers() ) )
- {
- ComputerCraft.log.error( "GenericSource method {}.{} should be static.", method.getDeclaringClass(), method.getName() );
- return null;
- }
-
- Type[] types = method.getGenericParameterTypes();
- if( types.length == 0 )
- {
- ComputerCraft.log.error( "GenericSource method {}.{} has no parameters.", method.getDeclaringClass(), method.getName() );
- return null;
- }
-
- Class> target = Reflect.getRawType( method, types[0], false );
- if( target == null ) return null;
-
- return new GenericMethod( method, annotation, target );
- } )
- .filter( Objects::nonNull )
- .collect( Collectors.toList() );
- }
- }
-}
diff --git a/src/main/java/dan200/computercraft/shared/Registry.java b/src/main/java/dan200/computercraft/shared/Registry.java
index dd9240465..a3a347fe5 100644
--- a/src/main/java/dan200/computercraft/shared/Registry.java
+++ b/src/main/java/dan200/computercraft/shared/Registry.java
@@ -245,7 +245,7 @@ private static void registerTurtleUpgrades()
{
// Upgrades
ComputerCraft.TurtleUpgrades.wirelessModemNormal = new TurtleModem( false, new ResourceLocation( ComputerCraft.MOD_ID, "wireless_modem_normal" ) );
- TurtleUpgrades.register( ComputerCraft.TurtleUpgrades.wirelessModemNormal );
+ ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.wirelessModemNormal );
ComputerCraft.TurtleUpgrades.wirelessModemAdvanced = new TurtleModem( true, new ResourceLocation( ComputerCraft.MOD_ID, "wireless_modem_advanced" ) );
ComputerCraftAPI.registerTurtleUpgrade( ComputerCraft.TurtleUpgrades.wirelessModemAdvanced );
diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralProvider.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralProvider.java
index 7f81033d0..8eab46f11 100644
--- a/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralProvider.java
+++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralProvider.java
@@ -15,22 +15,22 @@
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.common.util.NonNullConsumer;
-import net.minecraftforge.energy.CapabilityEnergy;
-import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
-import net.minecraftforge.items.CapabilityItemHandler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
public class GenericPeripheralProvider
{
- private static final Capability>[] CAPABILITIES = new Capability>[] {
- CapabilityItemHandler.ITEM_HANDLER_CAPABILITY,
- CapabilityEnergy.ENERGY,
- CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
- };
+ private static final ArrayList> capabilities = new ArrayList<>();
+
+ public static synchronized void addCapability( Capability> capability )
+ {
+ Objects.requireNonNull( capability, "Capability cannot be null" );
+ if( !capabilities.contains( capability ) ) capabilities.add( capability );
+ }
@Nullable
public static IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side, NonNullConsumer> invalidate )
@@ -43,7 +43,7 @@ public static IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos
List> tileMethods = PeripheralMethod.GENERATOR.getMethods( tile.getClass() );
if( !tileMethods.isEmpty() ) addSaturated( saturated, tile, tileMethods );
- for( Capability> capability : CAPABILITIES )
+ for( Capability> capability : capabilities )
{
LazyOptional> wrapper = tile.getCapability( capability );
wrapper.ifPresent( contents -> {
diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/EnergyMethods.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/EnergyMethods.java
index a7ae044af..4bf894a24 100644
--- a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/EnergyMethods.java
+++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/EnergyMethods.java
@@ -5,12 +5,11 @@
*/
package dan200.computercraft.shared.peripheral.generic.methods;
-import com.google.auto.service.AutoService;
+import dan200.computercraft.ComputerCraft;
+import dan200.computercraft.api.lua.GenericSource;
import dan200.computercraft.api.lua.LuaFunction;
-import dan200.computercraft.core.asm.GenericSource;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.energy.IEnergyStorage;
-import net.minecraftforge.versions.forge.ForgeVersion;
import javax.annotation.Nonnull;
@@ -26,14 +25,13 @@
*
* @cc.module energy_storage
*/
-@AutoService( GenericSource.class )
public class EnergyMethods implements GenericSource
{
@Nonnull
@Override
public ResourceLocation id()
{
- return new ResourceLocation( ForgeVersion.MOD_ID, "energy" );
+ return new ResourceLocation( ComputerCraft.MOD_ID, "energy" );
}
/**
diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java
index 9c994aa6e..3a66f809a 100644
--- a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java
+++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java
@@ -5,12 +5,12 @@
*/
package dan200.computercraft.shared.peripheral.generic.methods;
-import com.google.auto.service.AutoService;
+import dan200.computercraft.ComputerCraft;
+import dan200.computercraft.api.lua.GenericSource;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
-import dan200.computercraft.core.asm.GenericSource;
import dan200.computercraft.shared.peripheral.generic.data.FluidData;
import net.minecraft.fluid.Fluid;
import net.minecraft.util.ResourceLocation;
@@ -20,7 +20,6 @@
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.registries.ForgeRegistries;
-import net.minecraftforge.versions.forge.ForgeVersion;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -35,14 +34,13 @@
*
* @cc.module fluid_storage
*/
-@AutoService( GenericSource.class )
public class FluidMethods implements GenericSource
{
@Nonnull
@Override
public ResourceLocation id()
{
- return new ResourceLocation( ForgeVersion.MOD_ID, "fluid" );
+ return new ResourceLocation( ComputerCraft.MOD_ID, "fluid" );
}
/**
diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java
index 8d044bf69..d247d7aee 100644
--- a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java
+++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java
@@ -5,12 +5,12 @@
*/
package dan200.computercraft.shared.peripheral.generic.methods;
-import com.google.auto.service.AutoService;
+import dan200.computercraft.ComputerCraft;
+import dan200.computercraft.api.lua.GenericSource;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
-import dan200.computercraft.core.asm.GenericSource;
import dan200.computercraft.shared.peripheral.generic.data.ItemData;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
@@ -21,7 +21,6 @@
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.InvWrapper;
-import net.minecraftforge.versions.forge.ForgeVersion;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -36,14 +35,13 @@
*
* @cc.module inventory
*/
-@AutoService( GenericSource.class )
public class InventoryMethods implements GenericSource
{
@Nonnull
@Override
public ResourceLocation id()
{
- return new ResourceLocation( ForgeVersion.MOD_ID, "inventory" );
+ return new ResourceLocation( ComputerCraft.MOD_ID, "inventory" );
}
/**
diff --git a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java
index 38eb89930..f75f99f2a 100644
--- a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java
+++ b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java
@@ -24,6 +24,9 @@
import dan200.computercraft.shared.data.PlayerCreativeLootCondition;
import dan200.computercraft.shared.media.items.RecordMedia;
import dan200.computercraft.shared.network.NetworkHandler;
+import dan200.computercraft.shared.peripheral.generic.methods.EnergyMethods;
+import dan200.computercraft.shared.peripheral.generic.methods.FluidMethods;
+import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.util.NullStorage;
import net.minecraft.inventory.container.Container;
@@ -36,15 +39,19 @@
import net.minecraft.world.storage.loot.TableLootEntry;
import net.minecraft.world.storage.loot.conditions.LootConditionManager;
import net.minecraftforge.common.capabilities.CapabilityManager;
+import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.event.LootTableLoadEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
+import net.minecraftforge.fml.DeferredWorkQueue;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
+import net.minecraftforge.items.CapabilityItemHandler;
import java.util.Arrays;
import java.util.HashSet;
@@ -59,11 +66,15 @@ public static void init( FMLCommonSetupEvent event )
{
NetworkHandler.setup();
- net.minecraftforge.fml.DeferredWorkQueue.runLater( () -> {
+ DeferredWorkQueue.runLater( () -> {
registerProviders();
ArgumentSerializers.register();
registerLoot();
} );
+
+ ComputerCraftAPI.registerGenericSource( new InventoryMethods() );
+ ComputerCraftAPI.registerGenericSource( new FluidMethods() );
+ ComputerCraftAPI.registerGenericSource( new EnergyMethods() );
}
public static void registerLoot()
@@ -103,6 +114,12 @@ private static void registerProviders()
// Register capabilities
CapabilityManager.INSTANCE.register( IWiredElement.class, new NullStorage<>(), () -> null );
CapabilityManager.INSTANCE.register( IPeripheral.class, new NullStorage<>(), () -> null );
+
+ // Register generic capabilities. This can technically be done off-thread, but we need it to happen
+ // after Forge's common setup, so this is easiest.
+ ComputerCraftAPI.registerGenericCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY );
+ ComputerCraftAPI.registerGenericCapability( CapabilityEnergy.ENERGY );
+ ComputerCraftAPI.registerGenericCapability( CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY );
}
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
diff --git a/src/main/java/dan200/computercraft/shared/util/ServiceUtil.java b/src/main/java/dan200/computercraft/shared/util/ServiceUtil.java
deleted file mode 100644
index c21861dda..000000000
--- a/src/main/java/dan200/computercraft/shared/util/ServiceUtil.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * This file is part of ComputerCraft - http://www.computercraft.info
- * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
- * Send enquiries to dratcliffe@gmail.com
- */
-package dan200.computercraft.shared.util;
-
-import dan200.computercraft.ComputerCraft;
-import dan200.computercraft.api.ComputerCraftAPI;
-import net.minecraftforge.fml.ModList;
-import org.objectweb.asm.Type;
-
-import java.util.List;
-import java.util.ServiceLoader;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
-public final class ServiceUtil
-{
- private static final Type AUTO_SERVICE = Type.getType( "Lcom/google/auto/service/AutoService;" );
-
- private ServiceUtil()
- {
- }
-
- public static Stream loadServices( Class target )
- {
- return StreamSupport.stream( ServiceLoader.load( target, ServiceUtil.class.getClassLoader() ).spliterator(), false );
- }
-
- public static Stream loadServicesForge( Class target )
- {
- Type type = Type.getType( target );
- ClassLoader loader = ComputerCraftAPI.class.getClassLoader();
- return ModList.get().getAllScanData().stream()
- .flatMap( x -> x.getAnnotations().stream() )
- .filter( x -> x.getAnnotationType().equals( AUTO_SERVICE ) )
- .filter( x -> {
- Object value = x.getAnnotationData().get( "value" );
- return value instanceof List> && ((List>) value).contains( type );
- } )
- .flatMap( x -> {
- try
- {
- Class> klass = loader.loadClass( x.getClassType().getClassName() );
- if( !target.isAssignableFrom( klass ) )
- {
- ComputerCraft.log.error( "{} is not a subtype of {}", x.getClassType().getClassName(), target.getName() );
- return Stream.empty();
- }
-
- Class extends T> casted = klass.asSubclass( target );
- return Stream.of( casted.newInstance() );
- }
- catch( ReflectiveOperationException e )
- {
- ComputerCraft.log.error( "Cannot load {}", x.getClassType(), e );
- return Stream.empty();
- }
- } );
- }
-}