mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-10 09:20:28 +00:00
d50a08a549
This moves monitor networking into its own packet, rather than serialising using NBT. This allows us to be more flexible with how monitors are serialised. We now compress terminal data using gzip. This reduces the packet size of a max-sized-monitor from ~25kb to as little as 100b. On my test set of images (what I would consider to be the extreme end of the "reasonable" case), we have packets from 1.4kb bytes up to 12kb, with a mean of 6kb. Even in the worst case, this is a 2x reduction in packet size. While this is a fantastic win for the common case, it is not abuse-proof. One can create a terminal with high entropy (and so uncompressible). This will still be close to the original packet size. In order to prevent any other abuse, we also limit the amount of monitor data a client can possibly receive to 1MB (configurable).
668 lines
23 KiB
Java
668 lines
23 KiB
Java
/*
|
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
|
* Send enquiries to dratcliffe@gmail.com
|
|
*/
|
|
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.api.turtle.event.TurtleAction;
|
|
import dan200.computercraft.core.apis.AddressPredicate;
|
|
import dan200.computercraft.core.apis.ApiFactories;
|
|
import dan200.computercraft.core.computer.MainThread;
|
|
import dan200.computercraft.core.filesystem.ComboMount;
|
|
import dan200.computercraft.core.filesystem.FileMount;
|
|
import dan200.computercraft.core.filesystem.JarMount;
|
|
import dan200.computercraft.core.tracking.Tracking;
|
|
import dan200.computercraft.shared.*;
|
|
import dan200.computercraft.shared.computer.blocks.BlockCommandComputer;
|
|
import dan200.computercraft.shared.computer.blocks.BlockComputer;
|
|
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
|
|
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
|
|
import dan200.computercraft.shared.computer.items.ItemCommandComputer;
|
|
import dan200.computercraft.shared.computer.items.ItemComputer;
|
|
import dan200.computercraft.shared.media.items.ItemDiskExpanded;
|
|
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
|
|
import dan200.computercraft.shared.media.items.ItemPrintout;
|
|
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
|
|
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
|
|
import dan200.computercraft.shared.peripheral.common.ItemPeripheral;
|
|
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
|
|
import dan200.computercraft.shared.peripheral.modem.wired.BlockWiredModemFull;
|
|
import dan200.computercraft.shared.peripheral.modem.wired.ItemCable;
|
|
import dan200.computercraft.shared.peripheral.modem.wireless.BlockAdvancedModem;
|
|
import dan200.computercraft.shared.peripheral.modem.wireless.ItemAdvancedModem;
|
|
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
|
|
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
|
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
|
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
|
|
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
|
|
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
|
|
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
|
|
import dan200.computercraft.shared.turtle.items.ItemTurtleAdvanced;
|
|
import dan200.computercraft.shared.turtle.items.ItemTurtleLegacy;
|
|
import dan200.computercraft.shared.turtle.items.ItemTurtleNormal;
|
|
import dan200.computercraft.shared.turtle.upgrades.*;
|
|
import dan200.computercraft.shared.util.CreativeTabMain;
|
|
import dan200.computercraft.shared.util.IDAssigner;
|
|
import dan200.computercraft.shared.util.IoUtil;
|
|
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
|
import dan200.computercraft.shared.wired.WiredNode;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.item.ItemBlock;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.server.MinecraftServer;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraft.util.EnumFacing;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.world.IBlockAccess;
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.common.DimensionManager;
|
|
import net.minecraftforge.fml.common.*;
|
|
import net.minecraftforge.fml.common.event.*;
|
|
import net.minecraftforge.fml.relauncher.Side;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
import java.io.*;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URISyntaxException;
|
|
import java.net.URL;
|
|
import java.util.*;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.zip.ZipEntry;
|
|
import java.util.zip.ZipFile;
|
|
|
|
@Mod(
|
|
modid = ComputerCraft.MOD_ID, name = ComputerCraft.NAME, version = ComputerCraft.VERSION,
|
|
guiFactory = "dan200.computercraft.client.gui.GuiConfigCC$Factory",
|
|
dependencies = "required:forge@[14.23.4.2746,)"
|
|
)
|
|
public class ComputerCraft
|
|
{
|
|
public static final String MOD_ID = "computercraft";
|
|
static final String VERSION = "${version}";
|
|
static final String NAME = "CC: Tweaked";
|
|
|
|
// Configuration options
|
|
public static final String[] DEFAULT_HTTP_WHITELIST = new String[] { "*" };
|
|
public static final String[] DEFAULT_HTTP_BLACKLIST = new String[] {
|
|
"127.0.0.0/8",
|
|
"10.0.0.0/8",
|
|
"172.16.0.0/12",
|
|
"192.168.0.0/16",
|
|
"fd00::/8",
|
|
};
|
|
|
|
public static int computerSpaceLimit = 1000 * 1000;
|
|
public static int floppySpaceLimit = 125 * 1000;
|
|
public static int maximumFilesOpen = 128;
|
|
public static boolean disable_lua51_features = false;
|
|
public static String default_computer_settings = "";
|
|
public static boolean debug_enable = true;
|
|
public static boolean logPeripheralErrors = true;
|
|
public static boolean commandRequireCreative = true;
|
|
|
|
public static int computer_threads = 1;
|
|
public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos( 10 );
|
|
public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos( 5 );
|
|
|
|
public static boolean http_enable = true;
|
|
public static boolean http_websocket_enable = true;
|
|
public static AddressPredicate http_whitelist = new AddressPredicate( DEFAULT_HTTP_WHITELIST );
|
|
public static AddressPredicate http_blacklist = new AddressPredicate( DEFAULT_HTTP_BLACKLIST );
|
|
|
|
public static int httpTimeout = 30000;
|
|
public static int httpMaxRequests = 16;
|
|
public static long httpMaxDownload = 16 * 1024 * 1024;
|
|
public static long httpMaxUpload = 4 * 1024 * 1024;
|
|
public static int httpMaxWebsockets = 4;
|
|
public static int httpMaxWebsocketMessage = 128 * 1024;
|
|
|
|
public static boolean enableCommandBlock = false;
|
|
public static int modem_range = 64;
|
|
public static int modem_highAltitudeRange = 384;
|
|
public static int modem_rangeDuringStorm = 64;
|
|
public static int modem_highAltitudeRangeDuringStorm = 384;
|
|
public static int maxNotesPerTick = 8;
|
|
public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST;
|
|
public static long monitorBandwidth = 1_000_000;
|
|
|
|
public static boolean turtlesNeedFuel = true;
|
|
public static int turtleFuelLimit = 20000;
|
|
public static int advancedTurtleFuelLimit = 100000;
|
|
public static boolean turtlesObeyBlockProtection = true;
|
|
public static boolean turtlesCanPush = true;
|
|
public static EnumSet<TurtleAction> turtleDisabledActions = EnumSet.noneOf( TurtleAction.class );
|
|
|
|
public static final int terminalWidth_computer = 51;
|
|
public static final int terminalHeight_computer = 19;
|
|
|
|
public static final int terminalWidth_turtle = 39;
|
|
public static final int terminalHeight_turtle = 13;
|
|
|
|
public static final int terminalWidth_pocketComputer = 26;
|
|
public static final int terminalHeight_pocketComputer = 20;
|
|
|
|
// Blocks and Items
|
|
public static final class Blocks
|
|
{
|
|
public static BlockComputer computer;
|
|
public static BlockCommandComputer commandComputer;
|
|
|
|
public static BlockTurtle turtle;
|
|
public static BlockTurtle turtleExpanded;
|
|
public static BlockTurtle turtleAdvanced;
|
|
|
|
public static BlockPeripheral peripheral;
|
|
public static BlockCable cable;
|
|
public static BlockAdvancedModem advancedModem;
|
|
public static BlockWiredModemFull wiredModemFull;
|
|
}
|
|
|
|
public static final class Items
|
|
{
|
|
public static ItemComputer computer;
|
|
public static ItemCommandComputer commandComputer;
|
|
|
|
public static ItemTurtleLegacy turtle;
|
|
public static ItemTurtleNormal turtleExpanded;
|
|
public static ItemTurtleAdvanced turtleAdvanced;
|
|
|
|
public static ItemPocketComputer pocketComputer;
|
|
|
|
public static ItemDiskLegacy disk;
|
|
public static ItemDiskExpanded diskExpanded;
|
|
public static ItemTreasureDisk treasureDisk;
|
|
|
|
public static ItemPrintout printout;
|
|
|
|
public static ItemPeripheral peripheral;
|
|
public static ItemAdvancedModem advancedModem;
|
|
public static ItemCable cable;
|
|
public static ItemBlock wiredModemFull;
|
|
}
|
|
|
|
public static final class TurtleUpgrades
|
|
{
|
|
public static TurtleModem wirelessModem;
|
|
public static TurtleModem advancedModem;
|
|
public static TurtleSpeaker speaker;
|
|
|
|
public static TurtleCraftingTable craftingTable;
|
|
public static TurtleSword diamondSword;
|
|
public static TurtleShovel diamondShovel;
|
|
public static TurtleTool diamondPickaxe;
|
|
public static TurtleAxe diamondAxe;
|
|
public static TurtleHoe diamondHoe;
|
|
}
|
|
|
|
public static final class PocketUpgrades
|
|
{
|
|
public static PocketModem wirelessModem;
|
|
public static PocketModem advancedModem;
|
|
public static PocketSpeaker speaker;
|
|
|
|
@Deprecated
|
|
public static PocketSpeaker pocketSpeaker;
|
|
}
|
|
|
|
@Deprecated
|
|
public static final class Upgrades
|
|
{
|
|
public static TurtleModem advancedModem;
|
|
}
|
|
|
|
// Registries
|
|
public static final ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry();
|
|
public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();
|
|
|
|
// Creative
|
|
public static CreativeTabMain mainCreativeTab;
|
|
|
|
// Logging
|
|
public static Logger log;
|
|
|
|
// Peripheral providers. This is still here to ensure compatibility with Plethora and Computronics
|
|
public static List<IPeripheralProvider> peripheralProviders = new ArrayList<>();
|
|
|
|
// Implementation
|
|
@Mod.Instance( ComputerCraft.MOD_ID )
|
|
public static ComputerCraft instance;
|
|
|
|
@SidedProxy(
|
|
clientSide = "dan200.computercraft.client.proxy.ComputerCraftProxyClient",
|
|
serverSide = "dan200.computercraft.shared.proxy.ComputerCraftProxyCommon"
|
|
)
|
|
private static ComputerCraftProxyCommon proxy;
|
|
|
|
@Mod.EventHandler
|
|
public void preInit( FMLPreInitializationEvent event )
|
|
{
|
|
log = event.getModLog();
|
|
|
|
// Load config
|
|
Config.load( event.getSuggestedConfigurationFile() );
|
|
|
|
proxy.preInit();
|
|
}
|
|
|
|
@Mod.EventHandler
|
|
public void init( FMLInitializationEvent event )
|
|
{
|
|
proxy.init();
|
|
}
|
|
|
|
@Mod.EventHandler
|
|
public void onServerStarting( FMLServerStartingEvent event )
|
|
{
|
|
ComputerCraftProxyCommon.initServer( event.getServer() );
|
|
}
|
|
|
|
@Mod.EventHandler
|
|
public void onServerStart( FMLServerStartedEvent event )
|
|
{
|
|
if( FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER )
|
|
{
|
|
ComputerCraft.serverComputerRegistry.reset();
|
|
WirelessNetwork.resetNetworks();
|
|
MainThread.reset();
|
|
Tracking.reset();
|
|
}
|
|
}
|
|
|
|
@Mod.EventHandler
|
|
public void onServerStopped( FMLServerStoppedEvent event )
|
|
{
|
|
if( FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER )
|
|
{
|
|
ComputerCraft.serverComputerRegistry.reset();
|
|
WirelessNetwork.resetNetworks();
|
|
MainThread.reset();
|
|
Tracking.reset();
|
|
}
|
|
}
|
|
|
|
public static String getVersion()
|
|
{
|
|
return VERSION;
|
|
}
|
|
|
|
private static File getBaseDir()
|
|
{
|
|
return FMLCommonHandler.instance().getMinecraftServerInstance().getDataDirectory();
|
|
}
|
|
|
|
private static File getResourcePackDir()
|
|
{
|
|
return new File( getBaseDir(), "resourcepacks" );
|
|
}
|
|
|
|
@Deprecated
|
|
public static void registerPermissionProvider( ITurtlePermissionProvider provider )
|
|
{
|
|
TurtlePermissions.register( provider );
|
|
}
|
|
|
|
@Deprecated
|
|
public static void registerPocketUpgrade( IPocketUpgrade upgrade )
|
|
{
|
|
dan200.computercraft.shared.PocketUpgrades.register( upgrade );
|
|
}
|
|
|
|
@Deprecated
|
|
public static void registerPeripheralProvider( IPeripheralProvider provider )
|
|
{
|
|
Peripherals.register( provider );
|
|
}
|
|
|
|
@Deprecated
|
|
public static void registerBundledRedstoneProvider( IBundledRedstoneProvider provider )
|
|
{
|
|
BundledRedstone.register( provider );
|
|
}
|
|
|
|
@Deprecated
|
|
public static void registerMediaProvider( IMediaProvider provider )
|
|
{
|
|
MediaProviders.register( provider );
|
|
}
|
|
|
|
@Deprecated
|
|
public static void registerAPIFactory( ILuaAPIFactory factory )
|
|
{
|
|
ApiFactories.register( factory );
|
|
}
|
|
|
|
@Deprecated
|
|
public static IWiredNode createWiredNodeForElement( IWiredElement element )
|
|
{
|
|
return new WiredNode( element );
|
|
}
|
|
|
|
@Deprecated
|
|
public static IWiredElement getWiredElementAt( IBlockAccess world, BlockPos pos, EnumFacing side )
|
|
{
|
|
TileEntity tile = world.getTileEntity( pos );
|
|
return tile != null && tile.hasCapability( CapabilityWiredElement.CAPABILITY, side )
|
|
? tile.getCapability( CapabilityWiredElement.CAPABILITY, side )
|
|
: null;
|
|
}
|
|
|
|
@Deprecated
|
|
public static int getDefaultBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side )
|
|
{
|
|
return BundledRedstone.getDefaultOutput( world, pos, side );
|
|
}
|
|
|
|
@Deprecated
|
|
public static IPacketNetwork getWirelessNetwork()
|
|
{
|
|
return WirelessNetwork.getUniversal();
|
|
}
|
|
|
|
@Deprecated
|
|
public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
|
|
{
|
|
return IDAssigner.getNextIDFromDirectory( parentSubPath );
|
|
}
|
|
|
|
@Deprecated
|
|
public static IWritableMount createSaveDirMount( World world, String subPath, long capacity )
|
|
{
|
|
try
|
|
{
|
|
return new FileMount( new File( getWorldDir(), subPath ), capacity );
|
|
}
|
|
catch( Exception e )
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static void loadFromFile( List<IMount> mounts, File file, String path, boolean allowMissing )
|
|
{
|
|
try
|
|
{
|
|
if( file.isFile() )
|
|
{
|
|
mounts.add( new JarMount( file, path ) );
|
|
}
|
|
else
|
|
{
|
|
File subResource = new File( file, path );
|
|
if( subResource.exists() ) mounts.add( new FileMount( subResource, 0 ) );
|
|
}
|
|
}
|
|
catch( IOException | RuntimeException e )
|
|
{
|
|
if( allowMissing && e instanceof FileNotFoundException ) return;
|
|
ComputerCraft.log.error( "Could not load mount '" + path + " 'from '" + file.getName() + "'", e );
|
|
}
|
|
}
|
|
|
|
@Deprecated
|
|
public static IMount createResourceMount( Class<?> modClass, String domain, String subPath )
|
|
{
|
|
// Start building list of mounts
|
|
List<IMount> mounts = new ArrayList<>();
|
|
subPath = "assets/" + domain + "/" + subPath;
|
|
|
|
// Mount from debug dir
|
|
File codeDir = getDebugCodeDir( modClass );
|
|
if( codeDir != null )
|
|
{
|
|
File subResource = new File( codeDir, subPath );
|
|
if( subResource.exists() )
|
|
{
|
|
IMount resourcePackMount = new FileMount( subResource, 0 );
|
|
mounts.add( resourcePackMount );
|
|
}
|
|
}
|
|
|
|
// Mount from mod jars, preferring the specified one.
|
|
File modJar = getContainingJar( modClass );
|
|
Set<File> otherMods = new HashSet<>();
|
|
for( ModContainer container : Loader.instance().getActiveModList() )
|
|
{
|
|
File modFile = container.getSource();
|
|
if( modFile != null && !modFile.equals( modJar ) && modFile.exists() )
|
|
{
|
|
otherMods.add( container.getSource() );
|
|
}
|
|
}
|
|
|
|
for( File file : otherMods )
|
|
{
|
|
loadFromFile( mounts, file, subPath, true );
|
|
}
|
|
|
|
if( modJar != null )
|
|
{
|
|
loadFromFile( mounts, modJar, subPath, false );
|
|
}
|
|
|
|
// Mount from resource packs
|
|
File resourcePackDir = getResourcePackDir();
|
|
if( resourcePackDir.exists() && resourcePackDir.isDirectory() )
|
|
{
|
|
String[] resourcePacks = resourcePackDir.list();
|
|
for( String resourcePackName : resourcePacks )
|
|
{
|
|
File resourcePack = new File( resourcePackDir, resourcePackName );
|
|
loadFromFile( mounts, resourcePack, subPath, true );
|
|
}
|
|
}
|
|
|
|
// Return the combination of all the mounts found
|
|
if( mounts.size() >= 2 )
|
|
{
|
|
IMount[] mountArray = new IMount[mounts.size()];
|
|
mounts.toArray( mountArray );
|
|
return new ComboMount( mountArray );
|
|
}
|
|
else if( mounts.size() == 1 )
|
|
{
|
|
return mounts.get( 0 );
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static InputStream getResourceFile( Class<?> modClass, String domain, String subPath )
|
|
{
|
|
// Start searching in possible locations
|
|
subPath = "assets/" + domain + "/" + subPath;
|
|
|
|
// Look in resource packs
|
|
File resourcePackDir = getResourcePackDir();
|
|
if( resourcePackDir.exists() && resourcePackDir.isDirectory() )
|
|
{
|
|
String[] resourcePacks = resourcePackDir.list();
|
|
for( String resourcePackPath : resourcePacks )
|
|
{
|
|
File resourcePack = new File( resourcePackDir, resourcePackPath );
|
|
if( resourcePack.isDirectory() )
|
|
{
|
|
// Mount a resource pack from a folder
|
|
File subResource = new File( resourcePack, subPath );
|
|
if( subResource.exists() && subResource.isFile() )
|
|
{
|
|
try
|
|
{
|
|
return new FileInputStream( subResource );
|
|
}
|
|
catch( FileNotFoundException ignored )
|
|
{
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ZipFile zipFile = null;
|
|
try
|
|
{
|
|
final ZipFile zip = zipFile = new ZipFile( resourcePack );
|
|
ZipEntry entry = zipFile.getEntry( subPath );
|
|
if( entry != null )
|
|
{
|
|
// Return a custom InputStream which will close the original zip when finished.
|
|
return new FilterInputStream( zipFile.getInputStream( entry ) )
|
|
{
|
|
@Override
|
|
public void close() throws IOException
|
|
{
|
|
super.close();
|
|
zip.close();
|
|
}
|
|
};
|
|
}
|
|
else
|
|
{
|
|
IoUtil.closeQuietly( zipFile );
|
|
}
|
|
}
|
|
catch( IOException e )
|
|
{
|
|
IoUtil.closeQuietly( zipFile );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Look in debug dir
|
|
File codeDir = getDebugCodeDir( modClass );
|
|
if( codeDir != null )
|
|
{
|
|
File subResource = new File( codeDir, subPath );
|
|
if( subResource.exists() && subResource.isFile() )
|
|
{
|
|
try
|
|
{
|
|
return new FileInputStream( subResource );
|
|
}
|
|
catch( FileNotFoundException ignored )
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
// Look in class loader
|
|
return modClass.getClassLoader().getResourceAsStream( subPath );
|
|
}
|
|
|
|
private static File getContainingJar( Class<?> modClass )
|
|
{
|
|
String path = modClass.getProtectionDomain().getCodeSource().getLocation().getPath();
|
|
int bangIndex = path.indexOf( '!' );
|
|
if( bangIndex >= 0 )
|
|
{
|
|
path = path.substring( 0, bangIndex );
|
|
}
|
|
|
|
URL url;
|
|
try
|
|
{
|
|
url = new URL( path );
|
|
}
|
|
catch( MalformedURLException e1 )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
File file;
|
|
try
|
|
{
|
|
file = new File( url.toURI() );
|
|
}
|
|
catch( URISyntaxException e )
|
|
{
|
|
file = new File( url.getPath() );
|
|
}
|
|
return file;
|
|
}
|
|
|
|
private static File getDebugCodeDir( Class<?> modClass )
|
|
{
|
|
String path = modClass.getProtectionDomain().getCodeSource().getLocation().getPath();
|
|
int bangIndex = path.indexOf( '!' );
|
|
return bangIndex >= 0 ? null : new File( new File( path ).getParentFile(), "../.." );
|
|
}
|
|
|
|
@Deprecated
|
|
public static void registerTurtleUpgrade( ITurtleUpgrade upgrade )
|
|
{
|
|
dan200.computercraft.shared.TurtleUpgrades.register( upgrade );
|
|
}
|
|
|
|
public static File getWorldDir()
|
|
{
|
|
return DimensionManager.getCurrentSaveRootDirectory();
|
|
}
|
|
|
|
//region Compatibility
|
|
@Deprecated
|
|
public static File getWorldDir( World world )
|
|
{
|
|
return DimensionManager.getCurrentSaveRootDirectory();
|
|
}
|
|
|
|
@Deprecated
|
|
public static IMedia getMedia( ItemStack stack )
|
|
{
|
|
return MediaProviders.get( stack );
|
|
}
|
|
|
|
@Deprecated
|
|
public static IPocketUpgrade getPocketUpgrade( ItemStack stack )
|
|
{
|
|
return dan200.computercraft.shared.PocketUpgrades.get( stack );
|
|
}
|
|
|
|
@Deprecated
|
|
public static ITurtleUpgrade getTurtleUpgrade( ItemStack stack )
|
|
{
|
|
return dan200.computercraft.shared.TurtleUpgrades.get( stack );
|
|
}
|
|
|
|
@Deprecated
|
|
public static IPocketUpgrade getPocketUpgrade( String id )
|
|
{
|
|
return dan200.computercraft.shared.PocketUpgrades.get( id );
|
|
}
|
|
|
|
@Deprecated
|
|
public static ITurtleUpgrade getTurtleUpgrade( String id )
|
|
{
|
|
return dan200.computercraft.shared.TurtleUpgrades.get( id );
|
|
}
|
|
|
|
@Deprecated
|
|
public static IPeripheral getPeripheralAt( World world, BlockPos pos, EnumFacing side )
|
|
{
|
|
return Peripherals.getPeripheral( world, pos, side );
|
|
}
|
|
|
|
@Deprecated
|
|
public static boolean canPlayerUseCommands( EntityPlayer player )
|
|
{
|
|
MinecraftServer server = player.getServer();
|
|
return server != null && server.getPlayerList().canSendCommands( player.getGameProfile() );
|
|
}
|
|
//endregion
|
|
}
|