Skip to content
Permalink
Browse files

Use an interface instead of method reflection to call the API

This is originally based on dan200/ComputerCraft#523, but being more
liberal in how it breaks backwards compatibility. 1.14 and all that
after all.

There's several reasons for this change:
 - Make the API code cleaner and less error prone by removing
   reflection.
 - Try to make ComputerCraft.java less monolithic by moving
   functionality into separate module-specific classes.
 - Hopefully make the core class less Minecraft dependent, meaning
   emulators are a little less dependent on anything outside of /core.
  • Loading branch information...
SquidDev committed Dec 10, 2018
1 parent 6267377 commit 80f4841a0af3b5936d958356711c755358ace773
Showing with 787 additions and 649 deletions.
  1. +4 −279 src/main/java/dan200/computercraft/ComputerCraft.java
  2. +140 −0 src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java
  3. +65 −271 src/main/java/dan200/computercraft/api/ComputerCraftAPI.java
  4. +0 −42 src/main/java/dan200/computercraft/api/permissions/ITurtlePermissionProvider.java
  5. +26 −0 src/main/java/dan200/computercraft/api/turtle/event/FakePlayer.java
  6. +36 −0 src/main/java/dan200/computercraft/core/apis/ApiFactories.java
  7. +3 −6 src/main/java/dan200/computercraft/core/computer/Computer.java
  8. +69 −0 src/main/java/dan200/computercraft/shared/BundledRedstone.java
  9. +49 −0 src/main/java/dan200/computercraft/shared/MediaProviders.java
  10. +57 −0 src/main/java/dan200/computercraft/shared/Peripherals.java
  11. +76 −0 src/main/java/dan200/computercraft/shared/PocketUpgrades.java
  12. +4 −3 src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java
  13. +1 −1 src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java
  14. +2 −1 src/main/java/dan200/computercraft/shared/computer/items/ItemComputerBase.java
  15. +1 −1 src/main/java/dan200/computercraft/shared/media/items/ItemDisk.java
  16. +2 −1 src/main/java/dan200/computercraft/shared/media/items/ItemTreasureDisk.java
  17. +2 −1 src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java
  18. +6 −11 src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java
  19. +2 −1 src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java
  20. +242 −0 src/main/java/dan200/computercraft/shared/turtle/items/ItemTurtle.java
  21. +0 −20 src/main/java/dan200/computercraft/shared/util/PeripheralUtil.java
  22. +0 −11 src/main/java/dan200/computercraft/shared/util/RedstoneUtil.java
@@ -7,18 +7,6 @@
package dan200.computercraft;

import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount;
import dan200.computercraft.api.lua.ILuaAPIFactory;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.media.IMediaProvider;
import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.permissions.ITurtlePermissionProvider;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.client.proxy.CCTurtleProxyClient;
import dan200.computercraft.client.proxy.ComputerCraftProxyClient;
@@ -29,7 +17,6 @@
import dan200.computercraft.server.proxy.CCTurtleProxyServer;
import dan200.computercraft.server.proxy.ComputerCraftProxyServer;
import dan200.computercraft.shared.common.ContainerHeldItem;
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
@@ -49,15 +36,10 @@
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.proxy.ICCTurtleProxy;
import dan200.computercraft.shared.proxy.IComputerCraftProxy;
import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
import dan200.computercraft.shared.wired.WiredNode;
import io.netty.buffer.Unpooled;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.FabricLoader;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.packet.CustomPayloadClientPacket;
import net.minecraft.container.Container;
@@ -75,9 +57,7 @@
import net.minecraft.util.Hand;
import net.minecraft.util.PacketByteBuf;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Facing;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
@@ -90,7 +70,9 @@
import java.net.URL;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceConfigurationError;
import java.util.function.Function;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -104,16 +86,6 @@
public static final String MOD_ID = "computercraft";
public static final int DATAFIXER_VERSION = 0;

// GUI IDs
public static final int diskDriveGUIID = 100;
public static final int computerGUIID = 101;
public static final int printerGUIID = 102;
public static final int turtleGUIID = 103;
// ComputerCraftEdu uses ID 104
public static final int printoutGUIID = 105;
public static final int pocketComputerGUIID = 106;
public static final int viewComputerGUIID = 110;

// Configuration options
private static final String[] DEFAULT_HTTP_WHITELIST = new String[]{ "*" };
private static final String[] DEFAULT_HTTP_BLACKLIST = new String[]{
@@ -267,14 +239,6 @@
// Logging
public static Logger log = LogManager.getLogger( MOD_ID );

// API users
private static List<IPeripheralProvider> peripheralProviders = new ArrayList<>();
private static List<IBundledRedstoneProvider> bundledRedstoneProviders = new ArrayList<>();
private static List<IMediaProvider> mediaProviders = new ArrayList<>();
private static List<ITurtlePermissionProvider> permissionProviders = new ArrayList<>();
private static final Map<String, IPocketUpgrade> pocketUpgrades = new HashMap<>();
private static final Set<ILuaAPIFactory> apiFactories = new LinkedHashSet<>();

// Implementation
public static ComputerCraft instance;
public static IComputerCraftProxy proxy;
@@ -335,11 +299,6 @@ public void onServerStopped( FMLServerStoppedEvent event )
}
*/

public static String getVersion()
{
return "${version}";
}

public static boolean isClient()
{
return proxy.isClient();
@@ -505,14 +464,6 @@ public static boolean isPlayerOpped( PlayerEntity player )
return false;
}

public static void registerPermissionProvider( ITurtlePermissionProvider provider )
{
if( provider != null && !permissionProviders.contains( provider ) )
{
permissionProviders.add( provider );
}
}

public static boolean isBlockEnterable( World world, BlockPos pos, PlayerEntity player )
{
MinecraftServer server = player.getServer();
@@ -524,13 +475,6 @@ public static boolean isBlockEnterable( World world, BlockPos pos, PlayerEntity
}
}

for( ITurtlePermissionProvider provider : permissionProviders )
{
if( !provider.isBlockEnterable( world, pos ) )
{
return false;
}
}
return true;
}

@@ -545,229 +489,10 @@ public static boolean isBlockEditable( World world, BlockPos pos, PlayerEntity p
}
}

for( ITurtlePermissionProvider provider : permissionProviders )
{
if( !provider.isBlockEditable( world, pos ) )
{
return false;
}
}
return true;
}

public static void registerPocketUpgrade( IPocketUpgrade upgrade )
{
String id = upgrade.getUpgradeID().toString();
IPocketUpgrade existing = pocketUpgrades.get( id );
if( existing != null )
{
throw new RuntimeException( "Error registering '" + upgrade.getUnlocalisedAdjective() + " pocket computer'. UpgradeID '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " pocket computer'" );
}

pocketUpgrades.put( id, upgrade );
}

public static void registerPeripheralProvider( IPeripheralProvider provider )
{
if( provider != null && !peripheralProviders.contains( provider ) )
{
peripheralProviders.add( provider );
}
}

public static void registerBundledRedstoneProvider( IBundledRedstoneProvider provider )
{
if( provider != null && !bundledRedstoneProviders.contains( provider ) )
{
bundledRedstoneProviders.add( provider );
}
}

public static void registerMediaProvider( IMediaProvider provider )
{
if( provider != null && !mediaProviders.contains( provider ) )
{
mediaProviders.add( provider );
}
}

public static void registerAPIFactory( ILuaAPIFactory provider )
{
if( provider != null )
{
apiFactories.add( provider );
}
}

public static IWiredNode createWiredNodeForElement( IWiredElement element )
{
return new WiredNode( element );
}

public static IPeripheral getPeripheralAt( World world, BlockPos pos, Facing side )
{
// Try the handlers in order:
for( IPeripheralProvider peripheralProvider : peripheralProviders )
{
try
{
IPeripheral peripheral = peripheralProvider.getPeripheral( world, pos, side );
if( peripheral != null )
{
return peripheral;
}
}
catch( Exception e )
{
ComputerCraft.log.error( "Peripheral provider " + peripheralProvider + " errored.", e );
}
}
return null;
}

public static IWiredElement getWiredElementAt( BlockView world, BlockPos pos, Facing side )
{
BlockEntity tile = world.getBlockEntity( pos );
return null; /* tile != null && tile.hasCapability( CapabilityWiredElement.CAPABILITY, side )
? tile.getCapability( CapabilityWiredElement.CAPABILITY, side )
: null; */
}

public static int getDefaultBundledRedstoneOutput( World world, BlockPos pos, Facing side )
{
if( WorldUtil.isBlockInWorld( world, pos ) )
{
return DefaultBundledRedstoneProvider.getDefaultBundledRedstoneOutput( world, pos, side );
}
return -1;
}

public static int getBundledRedstoneOutput( World world, BlockPos pos, Facing side )
{
int y = pos.getY();
if( y < 0 || y >= world.getHeight() )
{
return -1;
}

// Try the handlers in order:
int combinedSignal = -1;
for( IBundledRedstoneProvider bundledRedstoneProvider : bundledRedstoneProviders )
{
try
{
int signal = bundledRedstoneProvider.getBundledRedstoneOutput( world, pos, side );
if( signal >= 0 )
{
if( combinedSignal < 0 )
{
combinedSignal = (signal & 0xffff);
}
else
{
combinedSignal = combinedSignal | (signal & 0xffff);
}
}
}
catch( Exception e )
{
ComputerCraft.log.error( "Bundled redstone provider " + bundledRedstoneProvider + " errored.", e );
}
}
return combinedSignal;
}

public static IMedia getMedia( @Nonnull ItemStack stack )
{
if( !stack.isEmpty() )
{
// Try the handlers in order:
for( IMediaProvider mediaProvider : mediaProviders )
{
try
{
IMedia media = mediaProvider.getMedia( stack );
if( media != null )
{
return media;
}
}
catch( Exception e )
{
// mod misbehaved, ignore it
ComputerCraft.log.error( "Media provider " + mediaProvider + " errored.", e );
}
}
return null;
}
return null;
}

public static IPocketUpgrade getPocketUpgrade( String id )
{
return pocketUpgrades.get( id );
}

public static IPocketUpgrade getPocketUpgrade( @Nonnull ItemStack stack )
{
if( stack.isEmpty() ) return null;

for( IPocketUpgrade upgrade : pocketUpgrades.values() )
{
ItemStack craftingStack = upgrade.getCraftingItem();
if( !craftingStack.isEmpty() && InventoryUtil.areItemsStackable( stack, craftingStack ) )
{
return upgrade;
}
}

return null;
}

public static Iterable<IPocketUpgrade> getVanillaPocketUpgrades()
{
List<IPocketUpgrade> upgrades = new ArrayList<>();
for( IPocketUpgrade upgrade : pocketUpgrades.values() )
{
/*
if( upgrade instanceof PocketModem || upgrade instanceof PocketSpeaker )
{
upgrades.add( upgrade );
}
*/
}

return upgrades;
}

public static IPacketNetwork getWirelessNetwork()
{
return null; // TODO: WirelessNetwork.getUniversal();
}

public static Iterable<ILuaAPIFactory> getAPIFactories()
{
return apiFactories;
}

public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
{
return IDAssigner.getNextIDFromDirectory( new File( getWorldDir( world ), parentSubPath ) );
}

public static IWritableMount createSaveDirMount( World world, String subPath, long capacity )
{
try
{
return new FileMount( new File( getWorldDir( world ), subPath ), capacity );
}
catch( Exception e )
{
return null;
}
}

public static IMount createResourceMount( Class<?> modClass, String domain, String subPath )
static IMount createResourceMount( Class<?> modClass, String domain, String subPath )
{
// Start building list of mounts
List<IMount> mounts = new ArrayList<>();
Oops, something went wrong.

0 comments on commit 80f4841

Please sign in to comment.
You can’t perform that action at this time.