Mostly used for the recipe system, but can also be used for debugging purposes. Debug options needs to be ticked to use the full information gain. Recipes only require the normal localization and the specific name plus metadata. Shifted the recipes into a recipes folder where the CSV will also reside. This will also elevate the copying of the readme to the user directory since it can reside in the recipes folder. Fixed a bug where the copier would copy the would also copy empty folders
This commit is contained in:
parent
b560382e80
commit
37ae2131fe
|
@ -45,10 +45,6 @@ buildscript {
|
|||
}
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.cacheDynamicVersionsFor 7200, 'hours'
|
||||
}
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_6
|
||||
targetCompatibility = JavaVersion.VERSION_1_6
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ invtweaks_version=1.58
|
|||
#########################################################
|
||||
fmp_version=1.2.0.345
|
||||
code_chicken_lib_version=1.1.3.138
|
||||
code_chicken_core_version=1.0.7.46
|
||||
code_chicken_core_version=1.0.7.47
|
||||
nei_version=1.0.5.111
|
||||
bc_version=7.0.9
|
||||
opencomputers_version=1.5.12.26
|
||||
|
|
|
@ -135,5 +135,5 @@ dependencies {
|
|||
compile(group: 'api', name: 'railcraft', version: "${api_railcraft_version}")
|
||||
compile(group: 'api', name: 'rf', version: "${api_rf_version}")
|
||||
|
||||
testCompile "junit:junit:4.11"
|
||||
testCompile "junit:junit:4.12"
|
||||
}
|
||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,4 +1,4 @@
|
|||
#Mon Aug 31 16:41:19 CEST 2015
|
||||
#Tue Sep 01 22:00:39 CEST 2015
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
@ -50,6 +50,6 @@ public class ItemCraftingStorage extends AEBaseItemBlock
|
|||
@Override
|
||||
public boolean hasContainerItem( final ItemStack stack )
|
||||
{
|
||||
return AEConfig.instance.isFeatureEnabled( AEFeature.enableDisassemblyCrafting );
|
||||
return AEConfig.instance.isFeatureEnabled( AEFeature.EnableDisassemblyCrafting );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
|||
|
||||
for( final AEFeature feature : AEFeature.values() )
|
||||
{
|
||||
if( feature.isVisible )
|
||||
if( feature.isVisible() )
|
||||
{
|
||||
if( this.get( "Features." + feature.category, feature.name(), feature.defaultValue ).getBoolean( feature.defaultValue ) )
|
||||
{
|
||||
|
|
|
@ -100,4 +100,12 @@ public final class AELog
|
|||
log( Level.INFO, format, data );
|
||||
}
|
||||
}
|
||||
|
||||
public static void debug( String format, Object... data )
|
||||
{
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.DebugLogging ) )
|
||||
{
|
||||
log( Level.DEBUG, format, data );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,12 @@ package appeng.core;
|
|||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.Mod;
|
||||
|
@ -48,8 +49,13 @@ import appeng.core.sync.network.NetworkHandler;
|
|||
import appeng.core.worlddata.WorldData;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.integration.IntegrationRegistry;
|
||||
import appeng.recipes.CustomRecipeConfig;
|
||||
import appeng.recipes.CustomRecipeForgeConfiguration;
|
||||
import appeng.server.AECommand;
|
||||
import appeng.services.VersionChecker;
|
||||
import appeng.services.export.ExportConfig;
|
||||
import appeng.services.export.ExportProcess;
|
||||
import appeng.services.export.ForgeExportConfig;
|
||||
import appeng.services.version.VersionCheckerConfig;
|
||||
import appeng.util.Platform;
|
||||
|
||||
|
@ -74,15 +80,28 @@ public final class AppEng
|
|||
@Nonnull
|
||||
private static final AppEng INSTANCE = new AppEng();
|
||||
|
||||
private final IMCHandler imcHandler;
|
||||
private final Registration registration;
|
||||
|
||||
private File configDirectory;
|
||||
private CustomRecipeConfig customRecipeConfig;
|
||||
|
||||
/**
|
||||
* Folder for recipes
|
||||
*
|
||||
* used for CSV item names and the recipes
|
||||
*/
|
||||
private File recipeDirectory;
|
||||
|
||||
/**
|
||||
* determined in pre-init but used in init
|
||||
*/
|
||||
private ExportConfig exportConfig;
|
||||
|
||||
AppEng()
|
||||
{
|
||||
this.imcHandler = new IMCHandler();
|
||||
|
||||
FMLCommonHandler.instance().registerCrashCallable( new ModCrashEnhancement( CrashInfo.MOD_VERSION ) );
|
||||
|
||||
this.registration = new Registration();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -92,9 +111,10 @@ public final class AppEng
|
|||
return INSTANCE;
|
||||
}
|
||||
|
||||
public final File getConfigDirectory()
|
||||
@Nonnull
|
||||
public final Registration getRegistration()
|
||||
{
|
||||
return this.configDirectory;
|
||||
return this.registration;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -107,14 +127,19 @@ public final class AppEng
|
|||
|
||||
final Stopwatch watch = Stopwatch.createStarted();
|
||||
this.configDirectory = new File( event.getModConfigurationDirectory().getPath(), "AppliedEnergistics2" );
|
||||
this.recipeDirectory = new File( this.configDirectory, "recipes" );
|
||||
|
||||
final File configFile = new File( this.configDirectory, "AppliedEnergistics2.cfg" );
|
||||
final File facadeFile = new File( this.configDirectory, "Facades.cfg" );
|
||||
final File versionFile = new File( this.configDirectory, "VersionChecker.cfg" );
|
||||
final File recipeFile = new File( this.configDirectory, "CustomRecipes.cfg" );
|
||||
final Configuration recipeConfiguration = new Configuration( recipeFile );
|
||||
|
||||
AEConfig.instance = new AEConfig( configFile );
|
||||
FacadeConfig.instance = new FacadeConfig( facadeFile );
|
||||
final VersionCheckerConfig versionCheckerConfig = new VersionCheckerConfig( versionFile );
|
||||
this.customRecipeConfig = new CustomRecipeForgeConfiguration( recipeConfiguration );
|
||||
this.exportConfig = new ForgeExportConfig( recipeConfiguration );
|
||||
|
||||
AELog.info( "Pre Initialization ( started )" );
|
||||
|
||||
|
@ -129,9 +154,9 @@ public final class AppEng
|
|||
CommonHelper.proxy.init();
|
||||
}
|
||||
|
||||
Registration.INSTANCE.preInitialize( event );
|
||||
this.registration.preInitialize( event );
|
||||
|
||||
if( versionCheckerConfig.isEnabled() )
|
||||
if( versionCheckerConfig.isVersionCheckingEnabled() )
|
||||
{
|
||||
final VersionChecker versionChecker = new VersionChecker( versionCheckerConfig );
|
||||
final Thread versionCheckerThread = new Thread( versionChecker );
|
||||
|
@ -154,22 +179,30 @@ public final class AppEng
|
|||
@EventHandler
|
||||
private void init( final FMLInitializationEvent event )
|
||||
{
|
||||
final Stopwatch star = Stopwatch.createStarted();
|
||||
final Stopwatch start = Stopwatch.createStarted();
|
||||
AELog.info( "Initialization ( started )" );
|
||||
|
||||
Registration.INSTANCE.initialize( event );
|
||||
if( exportConfig.isExportingItemNamesEnabled() )
|
||||
{
|
||||
final ExportProcess process = new ExportProcess( this.recipeDirectory, exportConfig );
|
||||
final Thread exportProcessThread = new Thread( process );
|
||||
|
||||
this.startService( "AE2 CSV Export", exportProcessThread );
|
||||
}
|
||||
|
||||
this.registration.initialize( event, this.recipeDirectory, this.customRecipeConfig );
|
||||
IntegrationRegistry.INSTANCE.init();
|
||||
|
||||
AELog.info( "Initialization ( ended after " + star.elapsed( TimeUnit.MILLISECONDS ) + "ms )" );
|
||||
AELog.info( "Initialization ( ended after " + start.elapsed( TimeUnit.MILLISECONDS ) + "ms )" );
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
private void postInit( final FMLPostInitializationEvent event )
|
||||
{
|
||||
final Stopwatch star = Stopwatch.createStarted();
|
||||
final Stopwatch start = Stopwatch.createStarted();
|
||||
AELog.info( "Post Initialization ( started )" );
|
||||
|
||||
Registration.INSTANCE.postInit( event );
|
||||
this.registration.postInit( event );
|
||||
IntegrationRegistry.INSTANCE.postInit();
|
||||
FMLCommonHandler.instance().registerCrashCallable( new IntegrationCrashEnhancement() );
|
||||
|
||||
|
@ -179,13 +212,15 @@ public final class AppEng
|
|||
NetworkRegistry.INSTANCE.registerGuiHandler( this, GuiBridge.GUI_Handler );
|
||||
NetworkHandler.instance = new NetworkHandler( "AE2" );
|
||||
|
||||
AELog.info( "Post Initialization ( ended after " + star.elapsed( TimeUnit.MILLISECONDS ) + "ms )" );
|
||||
AELog.info( "Post Initialization ( ended after " + start.elapsed( TimeUnit.MILLISECONDS ) + "ms )" );
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
private void handleIMCEvent( final FMLInterModComms.IMCEvent event )
|
||||
{
|
||||
this.imcHandler.handleIMCEvent( event );
|
||||
final IMCHandler imcHandler = new IMCHandler();
|
||||
|
||||
imcHandler.handleIMCEvent( event );
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
|
|
@ -22,7 +22,6 @@ package appeng.core;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
@ -30,6 +29,7 @@ import com.google.common.base.Preconditions;
|
|||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import appeng.api.recipes.IRecipeHandler;
|
||||
import appeng.recipes.CustomRecipeConfig;
|
||||
import appeng.recipes.loader.ConfigLoader;
|
||||
import appeng.recipes.loader.JarLoader;
|
||||
import appeng.recipes.loader.RecipeResourceCopier;
|
||||
|
@ -44,57 +44,74 @@ import appeng.recipes.loader.RecipeResourceCopier;
|
|||
*/
|
||||
public class RecipeLoader implements Runnable
|
||||
{
|
||||
/**
|
||||
* recipe path in the jar
|
||||
*/
|
||||
private static final String ASSETS_RECIPE_PATH = "/assets/appliedenergistics2/recipes/";
|
||||
|
||||
@Nonnull
|
||||
private final IRecipeHandler handler;
|
||||
@Nonnull
|
||||
private final CustomRecipeConfig config;
|
||||
@Nonnull
|
||||
private final File recipeDirectory;
|
||||
|
||||
/**
|
||||
* @param config configuration for the knowledge how to handle the loading process
|
||||
* @param handler handler to load the recipes
|
||||
*
|
||||
* @throws NullPointerException if handler is <tt>null</tt>
|
||||
*/
|
||||
public RecipeLoader( @Nonnull final IRecipeHandler handler )
|
||||
public RecipeLoader( @Nonnull final File recipeDirectory, @Nonnull final CustomRecipeConfig config, @Nonnull final IRecipeHandler handler )
|
||||
{
|
||||
Preconditions.checkNotNull( handler );
|
||||
|
||||
this.handler = handler;
|
||||
this.recipeDirectory = Preconditions.checkNotNull( recipeDirectory );
|
||||
Preconditions.checkArgument( !recipeDirectory.isFile() );
|
||||
this.config = Preconditions.checkNotNull( config );
|
||||
this.handler = Preconditions.checkNotNull( handler );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
public final void run()
|
||||
{
|
||||
// setup copying
|
||||
final RecipeResourceCopier copier = new RecipeResourceCopier( "assets/appliedenergistics2/recipes/" );
|
||||
final File configDirectory = AppEng.instance().getConfigDirectory();
|
||||
final File generatedRecipesDir = new File( configDirectory, "generated-recipes" );
|
||||
final File userRecipesDir = new File( configDirectory, "user-recipes" );
|
||||
final File readmeGenDest = new File( generatedRecipesDir, "README.html" );
|
||||
final File readmeUserDest = new File( userRecipesDir, "README.html" );
|
||||
|
||||
// generates generated and user recipes dir
|
||||
// will clean the generated every time to keep it up to date
|
||||
// copies over the recipes in the jar over to the generated folder
|
||||
// copies over the readmes
|
||||
try
|
||||
if( this.config.isEnabled() )
|
||||
{
|
||||
FileUtils.forceMkdir( generatedRecipesDir );
|
||||
FileUtils.forceMkdir( userRecipesDir );
|
||||
FileUtils.cleanDirectory( generatedRecipesDir );
|
||||
// setup copying
|
||||
final RecipeResourceCopier copier = new RecipeResourceCopier( "assets/appliedenergistics2/recipes/" );
|
||||
|
||||
copier.copyTo( generatedRecipesDir );
|
||||
FileUtils.copyFile( readmeGenDest, readmeUserDest );
|
||||
final File generatedRecipesDir = new File( this.recipeDirectory, "generated" );
|
||||
final File userRecipesDir = new File( this.recipeDirectory, "user" );
|
||||
|
||||
// parse recipes prioritising the user scripts by using the generated as template
|
||||
this.handler.parseRecipes( new ConfigLoader( generatedRecipesDir, userRecipesDir ), "index.recipe" );
|
||||
// generates generated and user recipes dir
|
||||
// will clean the generated every time to keep it up to date
|
||||
// copies over the recipes in the jar over to the generated folder
|
||||
// copies over the readmes
|
||||
try
|
||||
{
|
||||
FileUtils.forceMkdir( generatedRecipesDir );
|
||||
FileUtils.forceMkdir( userRecipesDir );
|
||||
FileUtils.cleanDirectory( generatedRecipesDir );
|
||||
|
||||
copier.copyTo( ".recipe", generatedRecipesDir );
|
||||
copier.copyTo( ".html", recipeDirectory );
|
||||
|
||||
// parse recipes prioritising the user scripts by using the generated as template
|
||||
this.handler.parseRecipes( new ConfigLoader( generatedRecipesDir, userRecipesDir ), "index.recipe" );
|
||||
}
|
||||
// on failure use jar parsing
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.error( e );
|
||||
this.handler.parseRecipes( new JarLoader( ASSETS_RECIPE_PATH ), "index.recipe" );
|
||||
}
|
||||
catch( final URISyntaxException e )
|
||||
{
|
||||
AELog.error( e );
|
||||
this.handler.parseRecipes( new JarLoader( ASSETS_RECIPE_PATH ), "index.recipe" );
|
||||
}
|
||||
}
|
||||
// on failure use jar parsing
|
||||
catch( final IOException e )
|
||||
else
|
||||
{
|
||||
AELog.error( e );
|
||||
this.handler.parseRecipes( new JarLoader( "/assets/appliedenergistics2/recipes/" ), "index.recipe" );
|
||||
}
|
||||
catch( final URISyntaxException e )
|
||||
{
|
||||
AELog.error( e );
|
||||
this.handler.parseRecipes( new JarLoader( "/assets/appliedenergistics2/recipes/" ), "index.recipe" );
|
||||
this.handler.parseRecipes( new JarLoader( ASSETS_RECIPE_PATH ), "index.recipe" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
package appeng.core;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -88,6 +93,7 @@ import appeng.me.cache.TickManagerCache;
|
|||
import appeng.me.storage.AEExternalHandler;
|
||||
import appeng.parts.PartPlacement;
|
||||
import appeng.recipes.AEItemResolver;
|
||||
import appeng.recipes.CustomRecipeConfig;
|
||||
import appeng.recipes.RecipeHandler;
|
||||
import appeng.recipes.game.DisassembleRecipe;
|
||||
import appeng.recipes.game.FacadeRecipe;
|
||||
|
@ -117,18 +123,21 @@ import appeng.worldgen.QuartzWorldGen;
|
|||
|
||||
public final class Registration
|
||||
{
|
||||
public static final Registration INSTANCE = new Registration();
|
||||
|
||||
private final RecipeHandler recipeHandler;
|
||||
private final DefinitionConverter converter;
|
||||
public BiomeGenBase storageBiome;
|
||||
private BiomeGenBase storageBiome;
|
||||
|
||||
private Registration()
|
||||
Registration()
|
||||
{
|
||||
this.converter = new DefinitionConverter();
|
||||
this.recipeHandler = new RecipeHandler();
|
||||
}
|
||||
|
||||
public BiomeGenBase getStorageBiome()
|
||||
{
|
||||
return this.storageBiome;
|
||||
}
|
||||
|
||||
public void preInitialize( final FMLPreInitializationEvent event )
|
||||
{
|
||||
this.registerSpatial( false );
|
||||
|
@ -503,8 +512,13 @@ public final class Registration
|
|||
target.itemLumenPaintBall = source.coloredLumenPaintBall();
|
||||
}
|
||||
|
||||
public void initialize( final FMLInitializationEvent event )
|
||||
public void initialize( @Nonnull final FMLInitializationEvent event, @Nonnull final File recipeDirectory, @Nonnull final CustomRecipeConfig customRecipeConfig )
|
||||
{
|
||||
Preconditions.checkNotNull( event );
|
||||
Preconditions.checkNotNull( recipeDirectory );
|
||||
Preconditions.checkArgument( !recipeDirectory.isFile() );
|
||||
Preconditions.checkNotNull( customRecipeConfig );
|
||||
|
||||
final IAppEngApi api = AEApi.instance();
|
||||
final IPartHelper partHelper = api.partHelper();
|
||||
final IRegistryContainer registries = api.registries();
|
||||
|
@ -512,7 +526,7 @@ public final class Registration
|
|||
// Perform ore camouflage!
|
||||
ItemMultiMaterial.instance.makeUnique();
|
||||
|
||||
final Runnable recipeLoader = new RecipeLoader( this.recipeHandler );
|
||||
final Runnable recipeLoader = new RecipeLoader( recipeDirectory, customRecipeConfig, this.recipeHandler );
|
||||
recipeLoader.run();
|
||||
|
||||
partHelper.registerNewLayer( "appeng.parts.layers.LayerISidedInventory", "net.minecraft.inventory.ISidedInventory" );
|
||||
|
@ -554,13 +568,13 @@ public final class Registration
|
|||
registration.registerAchievementHandlers();
|
||||
registration.registerAchievements();
|
||||
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.enableDisassemblyCrafting ) )
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.EnableDisassemblyCrafting ) )
|
||||
{
|
||||
GameRegistry.addRecipe( new DisassembleRecipe() );
|
||||
RecipeSorter.register( "appliedenergistics2:disassemble", DisassembleRecipe.class, Category.SHAPELESS, "after:minecraft:shapeless" );
|
||||
}
|
||||
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.enableFacadeCrafting ) )
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.EnableFacadeCrafting ) )
|
||||
{
|
||||
GameRegistry.addRecipe( new FacadeRecipe() );
|
||||
RecipeSorter.register( "appliedenergistics2:facade", FacadeRecipe.class, Category.SHAPED, "after:minecraft:shaped" );
|
||||
|
|
|
@ -21,60 +21,124 @@ package appeng.core.features;
|
|||
|
||||
public enum AEFeature
|
||||
{
|
||||
Core( null ), // stuff that has no reason for ever being turned off, or that
|
||||
// stuff that has no reason for ever being turned off, or that
|
||||
// is just flat out required by tons of
|
||||
// important stuff.
|
||||
Core( null )
|
||||
{
|
||||
@Override
|
||||
public boolean isVisible()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
CertusQuartzWorldGen( "World" ), MeteoriteWorldGen( "World" ),
|
||||
CertusQuartzWorldGen( Constants.CATEGORY_WORLD ),
|
||||
MeteoriteWorldGen( Constants.CATEGORY_WORLD ),
|
||||
DecorativeLights( Constants.CATEGORY_WORLD ),
|
||||
DecorativeQuartzBlocks( Constants.CATEGORY_WORLD ),
|
||||
SkyStoneChests( Constants.CATEGORY_WORLD ),
|
||||
SpawnPressesInMeteorites( Constants.CATEGORY_WORLD ),
|
||||
GrindStone( Constants.CATEGORY_WORLD ),
|
||||
Flour( Constants.CATEGORY_WORLD ),
|
||||
Inscriber( Constants.CATEGORY_WORLD ),
|
||||
ChestLoot( Constants.CATEGORY_WORLD ),
|
||||
VillagerTrading( Constants.CATEGORY_WORLD ),
|
||||
TinyTNT( Constants.CATEGORY_WORLD ),
|
||||
|
||||
DecorativeLights( "World" ), DecorativeQuartzBlocks( "World" ), SkyStoneChests( "World" ), SpawnPressesInMeteorites( "World" ),
|
||||
PoweredTools( Constants.CATEGORY_TOOLS_CLASSIFICATIONS ),
|
||||
CertusQuartzTools( Constants.CATEGORY_TOOLS_CLASSIFICATIONS ),
|
||||
NetherQuartzTools( Constants.CATEGORY_TOOLS_CLASSIFICATIONS ),
|
||||
|
||||
GrindStone( "World" ), Flour( "World" ), Inscriber( "World" ),
|
||||
QuartzHoe( Constants.CATEGORY_TOOLS ),
|
||||
QuartzSpade( Constants.CATEGORY_TOOLS ),
|
||||
QuartzSword( Constants.CATEGORY_TOOLS ),
|
||||
QuartzPickaxe( Constants.CATEGORY_TOOLS ),
|
||||
QuartzAxe( Constants.CATEGORY_TOOLS ),
|
||||
QuartzKnife( Constants.CATEGORY_TOOLS ),
|
||||
QuartzWrench( Constants.CATEGORY_TOOLS ),
|
||||
ChargedStaff( Constants.CATEGORY_TOOLS ),
|
||||
EntropyManipulator( Constants.CATEGORY_TOOLS ),
|
||||
MatterCannon( Constants.CATEGORY_TOOLS ),
|
||||
WirelessAccessTerminal( Constants.CATEGORY_TOOLS ),
|
||||
ColorApplicator( Constants.CATEGORY_TOOLS ),
|
||||
MeteoriteCompass( Constants.CATEGORY_TOOLS ),
|
||||
|
||||
ChestLoot( "World" ), VillagerTrading( "World" ),
|
||||
PowerGen( Constants.CATEGORY_NETWORK_FEATURES ),
|
||||
Security( Constants.CATEGORY_NETWORK_FEATURES ),
|
||||
SpatialIO( Constants.CATEGORY_NETWORK_FEATURES ),
|
||||
QuantumNetworkBridge( Constants.CATEGORY_NETWORK_FEATURES ),
|
||||
Channels( Constants.CATEGORY_NETWORK_FEATURES ),
|
||||
|
||||
TinyTNT( "World" ),
|
||||
LevelEmitter( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
CraftingTerminal( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
StorageMonitor( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
P2PTunnel( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
FormationPlane( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
AnnihilationPlane( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
IdentityAnnihilationPlane( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
ImportBus( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
ExportBus( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
StorageBus( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
PartConversionMonitor( Constants.CATEGORY_NETWORK_BUSES ),
|
||||
|
||||
PoweredTools( "ToolsClassifications" ),
|
||||
PortableCell( Constants.CATEGORY_PORTABLE_CELL ),
|
||||
|
||||
CertusQuartzTools( "ToolsClassifications" ),
|
||||
StorageCells( Constants.CATEGORY_STORAGE ),
|
||||
MEChest( Constants.CATEGORY_STORAGE ),
|
||||
MEDrive( Constants.CATEGORY_STORAGE ),
|
||||
IOPort( Constants.CATEGORY_STORAGE ),
|
||||
|
||||
NetherQuartzTools( "ToolsClassifications" ),
|
||||
NetworkTool( Constants.CATEGORY_NETWORK_TOOL ),
|
||||
|
||||
QuartzHoe( "Tools" ), QuartzSpade( "Tools" ), QuartzSword( "Tools" ), QuartzPickaxe( "Tools" ), QuartzAxe( "Tools" ), QuartzKnife( "Tools" ), QuartzWrench( "Tools" ),
|
||||
DenseEnergyCells( Constants.CATEGORY_HIGHER_CAPACITY ),
|
||||
DenseCables( Constants.CATEGORY_HIGHER_CAPACITY ),
|
||||
|
||||
ChargedStaff( "Tools" ), EntropyManipulator( "Tools" ), MatterCannon( "Tools" ), WirelessAccessTerminal( "Tools" ), ColorApplicator( "Tools" ),
|
||||
P2PTunnelRF( Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2PTunnelME( Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2PTunnelItems( Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2PTunnelRedstone( Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2PTunnelEU( Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2PTunnelLiquids( Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2PTunnelLight( Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2PTunnelOpenComputers( Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2PTunnelPressure( Constants.CATEGORY_P2P_TUNNELS ),
|
||||
|
||||
CraftingCPU( "CraftingFeatures" ), PowerGen( "NetworkFeatures" ), Security( "NetworkFeatures" ),
|
||||
MassCannonBlockDamage( Constants.CATEGORY_BLOCK_FEATURES ),
|
||||
TinyTNTBlockDamage( Constants.CATEGORY_BLOCK_FEATURES ),
|
||||
|
||||
SpatialIO( "NetworkFeatures" ), QuantumNetworkBridge( "NetworkFeatures" ), Channels( "NetworkFeatures" ),
|
||||
Facades( Constants.CATEGORY_FACADES ),
|
||||
|
||||
LevelEmitter( "NetworkBuses" ), CraftingTerminal( "NetworkBuses" ), StorageMonitor( "NetworkBuses" ), P2PTunnel( "NetworkBuses" ), FormationPlane( "NetworkBuses" ), AnnihilationPlane( "NetworkBuses" ), IdentityAnnihilationPlane( "NetworkBuses" ), ImportBus( "NetworkBuses" ), ExportBus( "NetworkBuses" ), StorageBus( "NetworkBuses" ), PartConversionMonitor( "NetworkBuses" ),
|
||||
UnsupportedDeveloperTools( Constants.CATEGORY_MISC, false ),
|
||||
Creative( Constants.CATEGORY_MISC ),
|
||||
GrinderLogging( Constants.CATEGORY_MISC, false ),
|
||||
Logging( Constants.CATEGORY_MISC ),
|
||||
IntegrationLogging( Constants.CATEGORY_MISC, false ),
|
||||
WebsiteRecipes( Constants.CATEGORY_MISC, false ),
|
||||
LogSecurityAudits( Constants.CATEGORY_MISC, false ),
|
||||
Achievements( Constants.CATEGORY_MISC ),
|
||||
UpdateLogging( Constants.CATEGORY_MISC, false ),
|
||||
PacketLogging( Constants.CATEGORY_MISC, false ),
|
||||
CraftingLog( Constants.CATEGORY_MISC, false ),
|
||||
LightDetector( Constants.CATEGORY_MISC ),
|
||||
DebugLogging( Constants.CATEGORY_MISC, false ),
|
||||
|
||||
StorageCells( "Storage" ), PortableCell( "PortableCell" ), MEChest( "Storage" ), MEDrive( "Storage" ), IOPort( "Storage" ),
|
||||
EnableFacadeCrafting( Constants.CATEGORY_CRAFTING ),
|
||||
InWorldSingularity( Constants.CATEGORY_CRAFTING ),
|
||||
InWorldFluix( Constants.CATEGORY_CRAFTING ),
|
||||
InWorldPurification( Constants.CATEGORY_CRAFTING ),
|
||||
InterfaceTerminal( Constants.CATEGORY_CRAFTING ),
|
||||
EnableDisassemblyCrafting( Constants.CATEGORY_CRAFTING ),
|
||||
|
||||
NetworkTool( "NetworkTool" ),
|
||||
AlphaPass( Constants.CATEGORY_RENDERING ), PaintBalls( Constants.CATEGORY_TOOLS ),
|
||||
|
||||
DenseEnergyCells( "HigherCapacity" ), DenseCables( "HigherCapacity" ),
|
||||
MolecularAssembler( Constants.CATEGORY_CRAFTING_FEATURES ),
|
||||
Patterns( Constants.CATEGORY_CRAFTING_FEATURES ),
|
||||
CraftingCPU( Constants.CATEGORY_CRAFTING_FEATURES ),
|
||||
|
||||
P2PTunnelRF( "P2PTunnels" ), P2PTunnelME( "P2PTunnels" ), P2PTunnelItems( "P2PTunnels" ), P2PTunnelRedstone( "P2PTunnels" ), P2PTunnelEU( "P2PTunnels" ), P2PTunnelLiquids( "P2PTunnels" ), P2PTunnelLight( "P2PTunnels" ), P2PTunnelOpenComputers( "P2PTunnels" ), P2PTunnelPressure( "P2PTunnels" ),
|
||||
|
||||
MassCannonBlockDamage( "BlockFeatures" ), TinyTNTBlockDamage( "BlockFeatures" ), Facades( "Facades" ),
|
||||
|
||||
UnsupportedDeveloperTools( "Misc", false ), Creative( "Misc" ),
|
||||
|
||||
GrinderLogging( "Misc", false ), Logging( "Misc" ), IntegrationLogging( "Misc", false ), WebsiteRecipes( "Misc", false ),
|
||||
|
||||
enableFacadeCrafting( "Crafting" ), inWorldSingularity( "Crafting" ), inWorldFluix( "Crafting" ), inWorldPurification( "Crafting" ), UpdateLogging( "Misc", false ),
|
||||
|
||||
AlphaPass( "Rendering" ), PaintBalls( "Tools" ), PacketLogging( "Misc", false ), CraftingLog( "Misc", false ), InterfaceTerminal( "Crafting" ), LightDetector( "Misc" ),
|
||||
|
||||
enableDisassemblyCrafting( "Crafting" ), MolecularAssembler( "CraftingFeatures" ), MeteoriteCompass( "Tools" ), Patterns( "CraftingFeatures" ),
|
||||
|
||||
ChunkLoggerTrace( "Commands", false ), LogSecurityAudits( "Misc", false ), Achievements( "Misc" );
|
||||
ChunkLoggerTrace( Constants.CATEGORY_COMMANDS, false );
|
||||
|
||||
public final String category;
|
||||
public final boolean isVisible;
|
||||
public final boolean defaultValue;
|
||||
|
||||
AEFeature( final String cat )
|
||||
|
@ -85,7 +149,39 @@ public enum AEFeature
|
|||
AEFeature( final String cat, final boolean defaultValue )
|
||||
{
|
||||
this.category = cat;
|
||||
this.isVisible = !this.name().equals( "Core" );
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* override to set visibility
|
||||
*
|
||||
* @return default true
|
||||
*/
|
||||
public boolean isVisible()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private enum Constants
|
||||
{
|
||||
;
|
||||
|
||||
private static final String CATEGORY_MISC = "Misc";
|
||||
private static final String CATEGORY_CRAFTING = "Crafting";
|
||||
private static final String CATEGORY_WORLD = "World";
|
||||
private static final String CATEGORY_TOOLS = "Tools";
|
||||
private static final String CATEGORY_TOOLS_CLASSIFICATIONS = "ToolsClassifications";
|
||||
private static final String CATEGORY_NETWORK_BUSES = "NetworkBuses";
|
||||
private static final String CATEGORY_P2P_TUNNELS = "P2PTunnels";
|
||||
private static final String CATEGORY_BLOCK_FEATURES = "BlockFeatures";
|
||||
private static final String CATEGORY_CRAFTING_FEATURES = "CraftingFeatures";
|
||||
private static final String CATEGORY_STORAGE = "Storage";
|
||||
private static final String CATEGORY_HIGHER_CAPACITY = "HigherCapacity";
|
||||
private static final String CATEGORY_NETWORK_FEATURES = "NetworkFeatures";
|
||||
private static final String CATEGORY_COMMANDS = "Commands";
|
||||
private static final String CATEGORY_RENDERING = "Rendering";
|
||||
private static final String CATEGORY_FACADES = "Facades";
|
||||
private static final String CATEGORY_NETWORK_TOOL = "NetworkTool";
|
||||
private static final String CATEGORY_PORTABLE_CELL = "PortableCell";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public final class EntityChargedQuartz extends AEBaseEntityItem
|
|||
{
|
||||
super.onUpdate();
|
||||
|
||||
if( !AEConfig.instance.isFeatureEnabled( AEFeature.inWorldFluix ) )
|
||||
if( !AEConfig.instance.isFeatureEnabled( AEFeature.InWorldFluix ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public final class EntityGrowingCrystal extends EntityItem
|
|||
{
|
||||
super.onUpdate();
|
||||
|
||||
if( !AEConfig.instance.isFeatureEnabled( AEFeature.inWorldPurification ) )
|
||||
if( !AEConfig.instance.isFeatureEnabled( AEFeature.InWorldPurification ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ public final class EntitySingularity extends AEBaseEntityItem
|
|||
return;
|
||||
}
|
||||
|
||||
if( !AEConfig.instance.isFeatureEnabled( AEFeature.inWorldSingularity ) )
|
||||
if( !AEConfig.instance.isFeatureEnabled( AEFeature.InWorldSingularity ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ public class NEI implements INEI, IContainerTooltipHandler, IIntegrationModule
|
|||
this.registerRecipeHandler( new NEIWorldCraftingHandler() );
|
||||
this.registerRecipeHandler( new NEIGrinderRecipeHandler() );
|
||||
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.Facades ) && AEConfig.instance.isFeatureEnabled( AEFeature.enableFacadeCrafting ) )
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.Facades ) && AEConfig.instance.isFeatureEnabled( AEFeature.EnableFacadeCrafting ) )
|
||||
{
|
||||
this.registerRecipeHandler( new NEIFacadeRecipeHandler() );
|
||||
}
|
||||
|
|
|
@ -221,17 +221,17 @@ public class NEIWorldCraftingHandler implements ICraftingHandler, IUsageHandler
|
|||
this.addRecipe( materials.engProcessorPress(), GuiText.inWorldCraftingPresses.getLocal() );
|
||||
}
|
||||
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.inWorldFluix ) )
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.InWorldFluix ) )
|
||||
{
|
||||
this.addRecipe( materials.fluixCrystal(), GuiText.inWorldFluix.getLocal() );
|
||||
}
|
||||
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.inWorldSingularity ) )
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.InWorldSingularity ) )
|
||||
{
|
||||
this.addRecipe( materials.qESingularity(), GuiText.inWorldSingularity.getLocal() );
|
||||
}
|
||||
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.inWorldPurification ) )
|
||||
if( AEConfig.instance.isFeatureEnabled( AEFeature.InWorldPurification ) )
|
||||
{
|
||||
this.addRecipe( materials.purifiedCertusQuartzCrystal(), GuiText.inWorldPurificationCertus.getLocal() );
|
||||
this.addRecipe( materials.purifiedNetherQuartzCrystal(), GuiText.inWorldPurificationNether.getLocal() );
|
||||
|
|
|
@ -42,47 +42,80 @@ public enum MaterialType
|
|||
{
|
||||
InvalidType( -1, AEFeature.Core ),
|
||||
|
||||
CertusQuartzCrystal( 0, AEFeature.Core, "crystalCertusQuartz" ), CertusQuartzCrystalCharged( 1, AEFeature.Core, EntityChargedQuartz.class ),
|
||||
CertusQuartzCrystal( 0, AEFeature.Core, "crystalCertusQuartz" ),
|
||||
CertusQuartzCrystalCharged( 1, AEFeature.Core, EntityChargedQuartz.class ),
|
||||
|
||||
CertusQuartzDust( 2, AEFeature.Core, "dustCertusQuartz" ), NetherQuartzDust( 3, AEFeature.Core, "dustNetherQuartz" ), Flour( 4, AEFeature.Flour, "dustWheat" ), GoldDust( 51, AEFeature.Core, "dustGold" ), IronDust( 49, AEFeature.Core, "dustIron" ), IronNugget( 50, AEFeature.Core, "nuggetIron" ),
|
||||
CertusQuartzDust( 2, AEFeature.Core, "dustCertusQuartz" ),
|
||||
NetherQuartzDust( 3, AEFeature.Core, "dustNetherQuartz" ),
|
||||
Flour( 4, AEFeature.Flour, "dustWheat" ),
|
||||
GoldDust( 51, AEFeature.Core, "dustGold" ),
|
||||
IronDust( 49, AEFeature.Core, "dustIron" ),
|
||||
IronNugget( 50, AEFeature.Core, "nuggetIron" ),
|
||||
|
||||
Silicon( 5, AEFeature.Core, "itemSilicon" ), MatterBall( 6 ),
|
||||
Silicon( 5, AEFeature.Core, "itemSilicon" ),
|
||||
MatterBall( 6 ),
|
||||
|
||||
FluixCrystal( 7, AEFeature.Core, "crystalFluix" ), FluixDust( 8, AEFeature.Core, "dustFluix" ), FluixPearl( 9, AEFeature.Core, "pearlFluix" ),
|
||||
FluixCrystal( 7, AEFeature.Core, "crystalFluix" ),
|
||||
FluixDust( 8, AEFeature.Core, "dustFluix" ),
|
||||
FluixPearl( 9, AEFeature.Core, "pearlFluix" ),
|
||||
|
||||
PurifiedCertusQuartzCrystal( 10 ), PurifiedNetherQuartzCrystal( 11 ), PurifiedFluixCrystal( 12 ),
|
||||
PurifiedCertusQuartzCrystal( 10 ),
|
||||
PurifiedNetherQuartzCrystal( 11 ),
|
||||
PurifiedFluixCrystal( 12 ),
|
||||
|
||||
CalcProcessorPress( 13 ), EngProcessorPress( 14 ), LogicProcessorPress( 15 ),
|
||||
CalcProcessorPress( 13 ),
|
||||
EngProcessorPress( 14 ),
|
||||
LogicProcessorPress( 15 ),
|
||||
|
||||
CalcProcessorPrint( 16 ), EngProcessorPrint( 17 ), LogicProcessorPrint( 18 ),
|
||||
CalcProcessorPrint( 16 ),
|
||||
EngProcessorPrint( 17 ),
|
||||
LogicProcessorPrint( 18 ),
|
||||
|
||||
SiliconPress( 19 ), SiliconPrint( 20 ),
|
||||
SiliconPress( 19 ),
|
||||
SiliconPrint( 20 ),
|
||||
|
||||
NamePress( 21 ),
|
||||
|
||||
LogicProcessor( 22 ), CalcProcessor( 23 ), EngProcessor( 24 ),
|
||||
LogicProcessor( 22 ),
|
||||
CalcProcessor( 23 ),
|
||||
EngProcessor( 24 ),
|
||||
|
||||
// Basic Cards
|
||||
BasicCard( 25 ), CardRedstone( 26 ), CardCapacity( 27 ),
|
||||
BasicCard( 25 ),
|
||||
CardRedstone( 26 ),
|
||||
CardCapacity( 27 ),
|
||||
|
||||
// Adv Cards
|
||||
AdvCard( 28 ), CardFuzzy( 29 ), CardSpeed( 30 ), CardInverter( 31 ),
|
||||
AdvCard( 28 ),
|
||||
CardFuzzy( 29 ), CardSpeed( 30 ),
|
||||
CardInverter( 31 ),
|
||||
|
||||
Cell2SpatialPart( 32, AEFeature.SpatialIO ), Cell16SpatialPart( 33, AEFeature.SpatialIO ), Cell128SpatialPart( 34, AEFeature.SpatialIO ),
|
||||
Cell2SpatialPart( 32, AEFeature.SpatialIO ),
|
||||
Cell16SpatialPart( 33, AEFeature.SpatialIO ),
|
||||
Cell128SpatialPart( 34, AEFeature.SpatialIO ),
|
||||
|
||||
Cell1kPart( 35, AEFeature.StorageCells ), Cell4kPart( 36, AEFeature.StorageCells ), Cell16kPart( 37, AEFeature.StorageCells ), Cell64kPart( 38, AEFeature.StorageCells ), EmptyStorageCell( 39, AEFeature.StorageCells ),
|
||||
Cell1kPart( 35, AEFeature.StorageCells ),
|
||||
Cell4kPart( 36, AEFeature.StorageCells ),
|
||||
Cell16kPart( 37, AEFeature.StorageCells ),
|
||||
Cell64kPart( 38, AEFeature.StorageCells ),
|
||||
EmptyStorageCell( 39, AEFeature.StorageCells ),
|
||||
|
||||
WoodenGear( 40, AEFeature.GrindStone, "gearWood" ),
|
||||
|
||||
Wireless( 41, AEFeature.WirelessAccessTerminal ), WirelessBooster( 42, AEFeature.WirelessAccessTerminal ),
|
||||
Wireless( 41, AEFeature.WirelessAccessTerminal ),
|
||||
WirelessBooster( 42, AEFeature.WirelessAccessTerminal ),
|
||||
|
||||
FormationCore( 43 ), AnnihilationCore( 44 ),
|
||||
FormationCore( 43 ),
|
||||
AnnihilationCore( 44 ),
|
||||
|
||||
SkyDust( 45, AEFeature.Core ),
|
||||
|
||||
EnderDust( 46, AEFeature.QuantumNetworkBridge, "dustEnder,dustEnderPearl", EntitySingularity.class ), Singularity( 47, AEFeature.QuantumNetworkBridge, EntitySingularity.class ), QESingularity( 48, AEFeature.QuantumNetworkBridge, EntitySingularity.class ),
|
||||
EnderDust( 46, AEFeature.QuantumNetworkBridge, "dustEnder,dustEnderPearl", EntitySingularity.class ),
|
||||
Singularity( 47, AEFeature.QuantumNetworkBridge, EntitySingularity.class ),
|
||||
QESingularity( 48, AEFeature.QuantumNetworkBridge, EntitySingularity.class ),
|
||||
|
||||
BlankPattern( 52 ), CardCrafting( 53 );
|
||||
BlankPattern( 52 ),
|
||||
CardCrafting( 53 );
|
||||
|
||||
private final EnumSet<AEFeature> features;
|
||||
// IIcon for the material.
|
||||
|
|
|
@ -308,6 +308,6 @@ public final class ItemBasicStorageCell extends AEBaseItem implements IStorageCe
|
|||
@Override
|
||||
public boolean hasContainerItem( final ItemStack stack )
|
||||
{
|
||||
return AEConfig.instance.isFeatureEnabled( AEFeature.enableDisassemblyCrafting );
|
||||
return AEConfig.instance.isFeatureEnabled( AEFeature.EnableDisassemblyCrafting );
|
||||
}
|
||||
}
|
||||
|
|
30
src/main/java/appeng/recipes/CustomRecipeConfig.java
Normal file
30
src/main/java/appeng/recipes/CustomRecipeConfig.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.recipes;
|
||||
|
||||
|
||||
/**
|
||||
* @author thatsIch
|
||||
* @version rv3 - 22.08.2015
|
||||
* @since rv3 22.08.2015
|
||||
*/
|
||||
public interface CustomRecipeConfig
|
||||
{
|
||||
boolean isEnabled();
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.recipes;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
|
||||
|
||||
/**
|
||||
* @author thatsIch
|
||||
* @version rv3 - 23.08.2015
|
||||
* @since rv3 23.08.2015
|
||||
*/
|
||||
public class CustomRecipeForgeConfiguration implements CustomRecipeConfig
|
||||
{
|
||||
private final boolean isEnabled;
|
||||
|
||||
public CustomRecipeForgeConfiguration( @Nonnull final Configuration config )
|
||||
{
|
||||
Preconditions.checkNotNull( config );
|
||||
|
||||
this.isEnabled = config.getBoolean( "enabled", "general", true, "If true, the custom recipes are enabled. Acts as a master switch." );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isEnabled()
|
||||
{
|
||||
return this.isEnabled;
|
||||
}
|
||||
}
|
|
@ -23,7 +23,6 @@ import java.io.BufferedReader;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
@ -31,6 +30,9 @@ import com.google.common.base.Preconditions;
|
|||
import appeng.api.recipes.IRecipeLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Loads the recipes from the config folder
|
||||
*/
|
||||
public final class ConfigLoader implements IRecipeLoader
|
||||
{
|
||||
private final File generatedRecipesDir;
|
||||
|
|
|
@ -22,6 +22,7 @@ package appeng.recipes.loader;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
|
@ -30,8 +31,8 @@ import java.util.Enumeration;
|
|||
import java.util.HashSet;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
@ -40,9 +41,7 @@ import org.apache.commons.io.FileUtils;
|
|||
|
||||
|
||||
/**
|
||||
* copies recipes in jars onto file system
|
||||
* includes the readme,
|
||||
* needs to be modified if other files needs to be handled
|
||||
* copies recipes in jars onto file system includes the readme, needs to be modified if other files needs to be handled
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 11.05.2015
|
||||
|
@ -55,6 +54,10 @@ public class RecipeResourceCopier
|
|||
*/
|
||||
private static final int INITIAL_RESOURCE_CAPACITY = 20;
|
||||
private static final Pattern DOT_COMPILE_PATTERN = Pattern.compile( ".", Pattern.LITERAL );
|
||||
private static final String FILE_PROTOCOL = "file";
|
||||
private static final String CLASS_EXTENSION = ".class";
|
||||
private static final String JAR_PROTOCOL = "jar";
|
||||
private static final String UTF_8_ENCODING = "UTF-8";
|
||||
|
||||
/**
|
||||
* copy source in the jar
|
||||
|
@ -76,47 +79,52 @@ public class RecipeResourceCopier
|
|||
/**
|
||||
* copies recipes found in the root to destination.
|
||||
*
|
||||
* @param identifier only copy files which end with the identifier
|
||||
* @param destination destination folder to which the recipes are copied to
|
||||
*
|
||||
* @throws URISyntaxException {@see #getResourceListing}
|
||||
* @throws IOException {@see #getResourceListing} and if copying the detected resource to file is not possible
|
||||
* @throws NullPointerException if either parameter is <tt>null</tt>
|
||||
* @throws URISyntaxException {@see #getResourceListing}
|
||||
* @throws IOException {@see #getResourceListing} and if copying the detected resource to file is not possible
|
||||
* @throws NullPointerException if either parameter is <tt>null</tt>
|
||||
* @throws IllegalArgumentException if destination is not a directory
|
||||
*/
|
||||
public void copyTo( @Nonnull final File destination ) throws URISyntaxException, IOException
|
||||
public void copyTo( @Nonnull final String identifier, @Nonnull final File destination ) throws URISyntaxException, IOException
|
||||
{
|
||||
Preconditions.checkNotNull( destination );
|
||||
Preconditions.checkArgument( destination.isDirectory() );
|
||||
|
||||
this.copyTo( destination, this.root );
|
||||
this.copyTo( identifier, destination, this.root );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {RecipeResourceCopier#copyTo(File)}
|
||||
*
|
||||
* @param destination destination folder to which the recipes are copied to
|
||||
* @param directory the folder to copy.
|
||||
*
|
||||
* @throws URISyntaxException {@see #getResourceListing}
|
||||
* @throws IOException {@see #getResourceListing} and if copying the detected resource to file is not possible
|
||||
* @throws IOException {@see #getResourceListing} and if copying the detected resource to file is not possible
|
||||
* @see {RecipeResourceCopier#copyTo(File)}
|
||||
*/
|
||||
private void copyTo( final File destination, final String directory ) throws URISyntaxException, IOException
|
||||
private void copyTo( @Nonnull final String identifier, @Nonnull final File destination, @Nonnull final String directory ) throws URISyntaxException, IOException
|
||||
{
|
||||
assert identifier != null;
|
||||
assert destination != null;
|
||||
assert directory != null;
|
||||
|
||||
final String[] listing = this.getResourceListing( this.getClass(), directory );
|
||||
final Class<? extends RecipeResourceCopier> copierClass = this.getClass();
|
||||
final String[] listing = this.getResourceListing( copierClass, directory );
|
||||
for( final String list : listing )
|
||||
{
|
||||
if( list.endsWith( ".recipe" ) || list.endsWith( ".html" ) )
|
||||
if( list.endsWith( identifier ) )
|
||||
{
|
||||
// generate folder before the file is copied so no empty folders will be generated
|
||||
FileUtils.forceMkdir( destination );
|
||||
|
||||
this.copyFile( destination, directory, list );
|
||||
}
|
||||
else if( !list.contains( "." ) )
|
||||
{
|
||||
final File subDirectory = new File( destination, list );
|
||||
FileUtils.forceMkdir( subDirectory );
|
||||
this.copyTo( subDirectory, directory + list + "/" );
|
||||
|
||||
this.copyTo( identifier, subDirectory, directory + list + "/" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,16 +134,18 @@ public class RecipeResourceCopier
|
|||
*
|
||||
* @param destination folder to which the file is copied to
|
||||
* @param directory the directory containing the file
|
||||
* @param fileName the fily to copy
|
||||
* @param fileName the file to copy
|
||||
*
|
||||
* @throws IOException if copying the file is not possible
|
||||
*/
|
||||
private void copyFile( final File destination, final String directory, final String fileName ) throws IOException
|
||||
private void copyFile( @Nonnull final File destination, @Nonnull final String directory, @Nonnull final String fileName ) throws IOException
|
||||
{
|
||||
assert destination != null;
|
||||
assert directory != null;
|
||||
assert fileName != null;
|
||||
|
||||
final InputStream inStream = this.getClass().getResourceAsStream( '/' + directory + fileName );
|
||||
final Class<? extends RecipeResourceCopier> copierClass = this.getClass();
|
||||
final InputStream inStream = copierClass.getResourceAsStream( '/' + directory + fileName );
|
||||
final File outFile = new File( destination, fileName );
|
||||
|
||||
if( !outFile.exists() && inStream != null )
|
||||
|
@ -146,30 +156,50 @@ public class RecipeResourceCopier
|
|||
}
|
||||
|
||||
/**
|
||||
* List directory contents for a resource folder. Not recursive.
|
||||
* This is basically a brute-force implementation.
|
||||
* Works for regular files and also JARs.
|
||||
* List directory contents for a resource folder. Not recursive. This is basically a brute-force implementation. Works for regular files and also JARs.
|
||||
*
|
||||
* @param clazz Any java class that lives in the same place as the resources you want.
|
||||
* @param path Should end with "/", but not start with one.
|
||||
*
|
||||
* @return Just the name of each member item, not the full paths.
|
||||
*
|
||||
* @throws URISyntaxException if it is a file path and the URL can not be converted to URI
|
||||
* @throws IOException if jar path can not be decoded
|
||||
* @throws URISyntaxException if it is a file path and the URL can not be converted to URI
|
||||
* @throws IOException if jar path can not be decoded
|
||||
* @throws UnsupportedOperationException if it is neither in jar nor in file path
|
||||
*/
|
||||
@Nonnull
|
||||
private String[] getResourceListing( final Class<?> clazz, final String path ) throws URISyntaxException, IOException
|
||||
private String[] getResourceListing( @Nonnull final Class<?> clazz, @Nonnull final String path ) throws URISyntaxException, IOException
|
||||
{
|
||||
assert clazz != null;
|
||||
assert path != null;
|
||||
|
||||
URL dirURL = clazz.getClassLoader().getResource( path );
|
||||
if( dirURL != null && dirURL.getProtocol().equals( "file" ) )
|
||||
final ClassLoader classLoader = clazz.getClassLoader();
|
||||
if( classLoader == null )
|
||||
{
|
||||
// A file path: easy enough
|
||||
return new File( dirURL.toURI() ).list();
|
||||
throw new IllegalStateException( "ClassLoader was not found. It was probably loaded at a inappropriate time" );
|
||||
}
|
||||
|
||||
URL dirURL = classLoader.getResource( path );
|
||||
if( dirURL != null )
|
||||
{
|
||||
final String protocol = dirURL.getProtocol();
|
||||
if( protocol.equals( FILE_PROTOCOL ) )
|
||||
{
|
||||
// A file path: easy enough
|
||||
|
||||
final URI uriOfURL = dirURL.toURI();
|
||||
final File fileOfURI = new File( uriOfURL );
|
||||
final String[] filesAndDirectoriesOfURI = fileOfURI.list();
|
||||
|
||||
if( filesAndDirectoriesOfURI == null )
|
||||
{
|
||||
throw new IllegalStateException( "Files and Directories were illegal. Either an abstract pathname does not denote a directory, or an I/O error occured." );
|
||||
}
|
||||
else
|
||||
{
|
||||
return filesAndDirectoriesOfURI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( dirURL == null )
|
||||
|
@ -178,43 +208,52 @@ public class RecipeResourceCopier
|
|||
* In case of a jar file, we can't actually find a directory.
|
||||
* Have to assume the same jar as clazz.
|
||||
*/
|
||||
final String me = DOT_COMPILE_PATTERN.matcher( clazz.getName() ).replaceAll( "/" ) + ".class";
|
||||
dirURL = clazz.getClassLoader().getResource( me );
|
||||
final String className = clazz.getName();
|
||||
final Matcher matcher = DOT_COMPILE_PATTERN.matcher( className );
|
||||
final String me = matcher.replaceAll( "/" ) + CLASS_EXTENSION;
|
||||
dirURL = classLoader.getResource( me );
|
||||
}
|
||||
|
||||
if( dirURL != null && dirURL.getProtocol().equals( "jar" ) )
|
||||
if( dirURL != null )
|
||||
{
|
||||
/* A JAR path */
|
||||
final String jarPath = dirURL.getPath().substring( 5, dirURL.getPath().indexOf( '!' ) ); // strip out only
|
||||
// the JAR file
|
||||
final JarFile jar = new JarFile( URLDecoder.decode( jarPath, "UTF-8" ) );
|
||||
try
|
||||
final String protocol = dirURL.getProtocol();
|
||||
if( protocol.equals( JAR_PROTOCOL ) )
|
||||
{
|
||||
final Enumeration<JarEntry> entries = jar.entries(); // gives ALL entries in jar
|
||||
final Collection<String> result = new HashSet<String>( INITIAL_RESOURCE_CAPACITY ); // avoid duplicates
|
||||
// in case it is a
|
||||
// subdirectory
|
||||
while( entries.hasMoreElements() )
|
||||
/* A JAR path */
|
||||
final String dirPath = dirURL.getPath();
|
||||
final String jarPath = dirPath.substring( 5, dirPath.indexOf( '!' ) ); // strip out only
|
||||
// the JAR file
|
||||
final JarFile jar = new JarFile( URLDecoder.decode( jarPath, UTF_8_ENCODING ) );
|
||||
try
|
||||
{
|
||||
final String name = entries.nextElement().getName();
|
||||
if( name.startsWith( path ) )
|
||||
{ // filter according to the path
|
||||
String entry = name.substring( path.length() );
|
||||
final int checkSubDir = entry.indexOf( '/' );
|
||||
if( checkSubDir >= 0 )
|
||||
{
|
||||
// if it is a subdirectory, we just return the directory name
|
||||
entry = entry.substring( 0, checkSubDir );
|
||||
}
|
||||
result.add( entry );
|
||||
}
|
||||
}
|
||||
final Enumeration<JarEntry> entries = jar.entries(); // gives ALL entries in jar
|
||||
final Collection<String> result = new HashSet<String>( INITIAL_RESOURCE_CAPACITY ); // avoid duplicates
|
||||
|
||||
return result.toArray( new String[result.size()] );
|
||||
}
|
||||
finally
|
||||
{
|
||||
jar.close();
|
||||
// in case it is a
|
||||
// subdirectory
|
||||
while( entries.hasMoreElements() )
|
||||
{
|
||||
final JarEntry entry = entries.nextElement();
|
||||
final String entryFullName = entry.getName();
|
||||
if( entryFullName.startsWith( path ) )
|
||||
{ // filter according to the path
|
||||
String entryName = entryFullName.substring( path.length() );
|
||||
final int checkSubDir = entryName.indexOf( '/' );
|
||||
if( checkSubDir >= 0 )
|
||||
{
|
||||
// if it is a subdirectory, we just return the directory name
|
||||
entryName = entryName.substring( 0, checkSubDir );
|
||||
}
|
||||
result.add( entryName );
|
||||
}
|
||||
}
|
||||
|
||||
return result.toArray( new String[result.size()] );
|
||||
}
|
||||
finally
|
||||
{
|
||||
jar.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ import appeng.server.subcommands.Supporters;
|
|||
|
||||
public enum Commands
|
||||
{
|
||||
Chunklogger( 4, new ChunkLogger() ), supporters( 0, new Supporters() );
|
||||
Chunklogger( 4, new ChunkLogger() ),
|
||||
Supporters( 0, new Supporters() );
|
||||
|
||||
public final int level;
|
||||
public final ISubCommand command;
|
||||
|
|
|
@ -76,7 +76,13 @@ public final class VersionChecker implements Runnable
|
|||
{
|
||||
Thread.yield();
|
||||
|
||||
// persist the config
|
||||
this.config.save();
|
||||
|
||||
// retrieve data
|
||||
final String rawLastCheck = this.config.lastCheck();
|
||||
|
||||
// process data
|
||||
final long lastCheck = Long.parseLong( rawLastCheck );
|
||||
final Date now = new Date();
|
||||
final long nowInMs = now.getTime();
|
||||
|
|
41
src/main/java/appeng/services/export/CheckType.java
Normal file
41
src/main/java/appeng/services/export/CheckType.java
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
/**
|
||||
* Defines a concrete result type when using the {@link Checker#isEqual(Object)} from the {@link Checker} class.
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 25.09.2015
|
||||
* @see Checker
|
||||
* @since rv3 - 25.09.2015
|
||||
*/
|
||||
enum CheckType
|
||||
{
|
||||
/**
|
||||
* If checking resulted in both objects being <b>equal</b>
|
||||
*/
|
||||
EQUAL,
|
||||
|
||||
/**
|
||||
* If checking resulted in both objects being <b>unequal</b>
|
||||
*/
|
||||
UNEQUAL
|
||||
}
|
45
src/main/java/appeng/services/export/Checker.java
Normal file
45
src/main/java/appeng/services/export/Checker.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
||||
/**
|
||||
* Checks against a specific type with its own check type for clear outcome.
|
||||
*
|
||||
* The constructor will generally have a value which the checker will check against
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 01.09.2015
|
||||
* @since rv3 - 01.09.2015
|
||||
*/
|
||||
interface Checker<T>
|
||||
{
|
||||
/**
|
||||
* @param checkedAgainst the object it is checked against
|
||||
*
|
||||
* @return non null being either equal or unequal
|
||||
*
|
||||
* @since rv3 - 01.09.2015
|
||||
*/
|
||||
@Nonnull
|
||||
CheckType isEqual( @Nonnull final T checkedAgainst );
|
||||
}
|
82
src/main/java/appeng/services/export/ExportConfig.java
Normal file
82
src/main/java/appeng/services/export/ExportConfig.java
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
||||
/**
|
||||
* @author thatsIch
|
||||
* @version rv3 - 14.08.2015
|
||||
* @since rv3 14.08.2015
|
||||
*/
|
||||
public interface ExportConfig
|
||||
{
|
||||
/**
|
||||
* config switch to disable the exporting.
|
||||
* if the recipes system is not used
|
||||
* there is no reason to export them.
|
||||
* Still can be useful for debugging purpose,
|
||||
* thus not tying it to the recipe system directly.
|
||||
*
|
||||
* @return true if exporting is enabled
|
||||
*/
|
||||
boolean isExportingItemNamesEnabled();
|
||||
|
||||
/**
|
||||
* config switch for using the digest cache.
|
||||
*
|
||||
* @return true if cache is enabled
|
||||
*/
|
||||
boolean isCacheEnabled();
|
||||
|
||||
/**
|
||||
* config switch to always refresh the CSV. Might be useful to activate on debugging.
|
||||
*
|
||||
* @return true if force refresh is enabled
|
||||
*/
|
||||
boolean isForceRefreshEnabled();
|
||||
|
||||
/**
|
||||
* config switch to export more information mostly used for debugging
|
||||
*
|
||||
* @return true if additional information are enabled
|
||||
*/
|
||||
boolean isAdditionalInformationEnabled();
|
||||
|
||||
/**
|
||||
* Will get the cache from last session. Can be used to reduce I/O operations though containing itself calculation.
|
||||
*
|
||||
* @return a digest from the last calculation
|
||||
*/
|
||||
String getCache();
|
||||
|
||||
/**
|
||||
* sets the cache for the next session to reduce calculation overhead
|
||||
*
|
||||
* @param digest new digest for the cache
|
||||
*/
|
||||
void setCache( @Nonnull String digest );
|
||||
|
||||
/**
|
||||
* Will delegate the saving
|
||||
*/
|
||||
void save();
|
||||
}
|
42
src/main/java/appeng/services/export/ExportMode.java
Normal file
42
src/main/java/appeng/services/export/ExportMode.java
Normal file
|
@ -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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
/**
|
||||
* Defines the different modes which need to be distinguished upon exporting.
|
||||
*
|
||||
* using a different mode will result in a different export outcome.
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 23.09.2015
|
||||
* @since rv3 - 23.09.2015
|
||||
*/
|
||||
enum ExportMode
|
||||
{
|
||||
/**
|
||||
* Will provide general users with information required for recipe making
|
||||
*/
|
||||
MINIMAL,
|
||||
|
||||
/**
|
||||
* Will provide advanced users with information with debugging functionality
|
||||
*/
|
||||
VERBOSE
|
||||
}
|
130
src/main/java/appeng/services/export/ExportProcess.java
Normal file
130
src/main/java/appeng/services/export/ExportProcess.java
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Stopwatch;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry;
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
|
||||
import appeng.core.AELog;
|
||||
|
||||
|
||||
/**
|
||||
* Main entry point for exporting the CSV file
|
||||
*
|
||||
* makes everything threadable
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 14.08.2015
|
||||
* @since rv3 14.08.2015
|
||||
*/
|
||||
public class ExportProcess implements Runnable
|
||||
{
|
||||
private static final String FORCE_REFRESH_MESSAGE = "Force Refresh enabled. Will ignore cache and export CSV content.";
|
||||
private static final String CACHE_ENABLED_MESSAGE = "Cache is enabled. Checking for new mod configurations.";
|
||||
private static final String EQUAL_CONTENT_MESSAGE = "Same mod configuration was found. Not updating CSV content.";
|
||||
private static final String UNEQUAL_CONTENT_MESSAGE = "New mod configuration was found. Commencing exporting.";
|
||||
private static final String CACHE_DISABLED_MESSAGE = "Cache is disabled. Commencing exporting.";
|
||||
private static final String EXPORT_START_MESSAGE = "Item Exporting ( started )";
|
||||
private static final String EXPORT_END_MESSAGE = "Item Exporting ( ended after %s ms)";
|
||||
|
||||
@Nonnull
|
||||
private final File exportDirectory;
|
||||
@Nonnull
|
||||
private final Checker<List<ModContainer>> modChecker;
|
||||
@Nonnull
|
||||
private final ExportConfig config;
|
||||
|
||||
/**
|
||||
* @param exportDirectory directory where the final CSV file will be exported to
|
||||
* @param config configuration to manipulate the export process
|
||||
*/
|
||||
public ExportProcess( @Nonnull final File exportDirectory, @Nonnull final ExportConfig config )
|
||||
{
|
||||
this.exportDirectory = Preconditions.checkNotNull( exportDirectory );
|
||||
this.config = Preconditions.checkNotNull( config );
|
||||
|
||||
this.modChecker = new ModListChecker( config );
|
||||
}
|
||||
|
||||
/**
|
||||
* Will check and export if various config settings will lead to exporting the CSV file.
|
||||
*/
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
// no priority to this thread
|
||||
Thread.yield();
|
||||
|
||||
// logic when to cancel the export process
|
||||
if( this.config.isForceRefreshEnabled() )
|
||||
{
|
||||
AELog.info( FORCE_REFRESH_MESSAGE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( this.config.isCacheEnabled() )
|
||||
{
|
||||
AELog.info( CACHE_ENABLED_MESSAGE );
|
||||
|
||||
final Loader loader = Loader.instance();
|
||||
final List<ModContainer> mods = loader.getActiveModList();
|
||||
|
||||
if( this.modChecker.isEqual( mods ) == CheckType.EQUAL )
|
||||
{
|
||||
AELog.info( EQUAL_CONTENT_MESSAGE );
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.info( UNEQUAL_CONTENT_MESSAGE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.info( CACHE_DISABLED_MESSAGE );
|
||||
}
|
||||
}
|
||||
|
||||
AELog.info( EXPORT_START_MESSAGE );
|
||||
final Stopwatch watch = Stopwatch.createStarted();
|
||||
|
||||
final FMLControlledNamespacedRegistry<Item> itemRegistry = GameData.getItemRegistry();
|
||||
|
||||
final ExportMode mode = this.config.isAdditionalInformationEnabled() ? ExportMode.VERBOSE : ExportMode.MINIMAL;
|
||||
final Exporter exporter = new MinecraftItemCSVExporter( this.exportDirectory, itemRegistry, mode );
|
||||
|
||||
exporter.export();
|
||||
|
||||
AELog.info( EXPORT_END_MESSAGE, watch.elapsed( TimeUnit.MILLISECONDS ) );
|
||||
}
|
||||
}
|
35
src/main/java/appeng/services/export/Exporter.java
Normal file
35
src/main/java/appeng/services/export/Exporter.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
/**
|
||||
* General purpose interface to define an export operation with side effects
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 19.08.2015
|
||||
* @since rv3 19.08.2015
|
||||
*/
|
||||
interface Exporter
|
||||
{
|
||||
/**
|
||||
* Will export something defined by the Exporter with side effects
|
||||
*/
|
||||
void export();
|
||||
}
|
129
src/main/java/appeng/services/export/ForgeExportConfig.java
Normal file
129
src/main/java/appeng/services/export/ForgeExportConfig.java
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.minecraftforge.common.config.Property;
|
||||
|
||||
|
||||
/**
|
||||
* Offers configuration switches for the user to change the export process
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 14.08.2015
|
||||
* @since rv3 14.08.2015
|
||||
*/
|
||||
public final class ForgeExportConfig implements ExportConfig
|
||||
{
|
||||
private static final String GENERAL_CATEGORY = "general";
|
||||
private static final String CACHE_CATEGORY = "cache";
|
||||
|
||||
private static final String EXPORT_ITEM_NAMES_KEY = "exportItemNames";
|
||||
private static final boolean EXPORT_ITEM_NAMES_DEFAULT = true;
|
||||
private static final String EXPORT_ITEM_NAMES_DESCRIPTION = "If true, all registered items will be exported containing the internal minecraft name and the localized name to actually find the item you are using. This also contains the item representation of the blocks, but are missing items, which are too much to display e.g. FMP.";
|
||||
|
||||
private static final String ENABLE_FORCE_REFRESH_KEY = "enableForceRefresh";
|
||||
private static final boolean ENABLE_FORCE_REFRESH_DEFAULT = false;
|
||||
private static final String ENABLE_FORCE_REFRESH_DESCRIPTION = "If true, the CSV exporting will always happen. This will not use the cache to reduce the computation.";
|
||||
|
||||
private static final String ENABLE_CACHE_KEY = "enableCache";
|
||||
private static final boolean ENABLE_CACHE_DEFAULT = true;
|
||||
private static final String ENABLE_CACHE_DESCRIPTION = "Caching can save processing time, if there are a lot of items.";
|
||||
|
||||
private static final String ENABLE_ADDITIONAL_INFO_KEY = "enableAdditionalInfo";
|
||||
private static final boolean ENABLE_ADDITIONAL_INFO_DEFAULT = false;
|
||||
private static final String ENABLE_ADDITIONAL_INFO_DESCRIPTION = "Will output more detailed information into the CSV like corresponding items";
|
||||
|
||||
private static final String DIGEST_KEY = "digest";
|
||||
private static final String DIGEST_DEFAULT = "";
|
||||
private static final String DIGEST_DESCRIPTION = "Digest of all the mods and versions to check if a re-export of the item names is required.";
|
||||
|
||||
private final boolean exportItemNamesEnabled;
|
||||
private final boolean cacheEnabled;
|
||||
private final boolean forceRefreshEnabled;
|
||||
private final boolean additionalInformationEnabled;
|
||||
private final String cache;
|
||||
private final Configuration config;
|
||||
|
||||
/**
|
||||
* Constructor using the configuration. Apparently there are some race conditions if constructing configurations on multiple file accesses
|
||||
*
|
||||
* @param config to be wrapped configuration.
|
||||
*/
|
||||
public ForgeExportConfig( @Nonnull final Configuration config )
|
||||
{
|
||||
this.config = Preconditions.checkNotNull( config );
|
||||
|
||||
this.exportItemNamesEnabled = this.config.getBoolean( EXPORT_ITEM_NAMES_KEY, GENERAL_CATEGORY, EXPORT_ITEM_NAMES_DEFAULT, EXPORT_ITEM_NAMES_DESCRIPTION );
|
||||
this.cacheEnabled = this.config.getBoolean( ENABLE_CACHE_KEY, CACHE_CATEGORY, ENABLE_CACHE_DEFAULT, ENABLE_CACHE_DESCRIPTION );
|
||||
this.additionalInformationEnabled = this.config.getBoolean( ENABLE_ADDITIONAL_INFO_KEY, GENERAL_CATEGORY, ENABLE_ADDITIONAL_INFO_DEFAULT, ENABLE_ADDITIONAL_INFO_DESCRIPTION );
|
||||
this.cache = this.config.getString( DIGEST_KEY, CACHE_CATEGORY, DIGEST_DEFAULT, DIGEST_DESCRIPTION );
|
||||
this.forceRefreshEnabled = this.config.getBoolean( ENABLE_FORCE_REFRESH_KEY, GENERAL_CATEGORY, ENABLE_FORCE_REFRESH_DEFAULT, ENABLE_FORCE_REFRESH_DESCRIPTION );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExportingItemNamesEnabled()
|
||||
{
|
||||
return this.exportItemNamesEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCacheEnabled()
|
||||
{
|
||||
return this.cacheEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForceRefreshEnabled()
|
||||
{
|
||||
return this.forceRefreshEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdditionalInformationEnabled()
|
||||
{
|
||||
return this.additionalInformationEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCache()
|
||||
{
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCache( @Nonnull final String digest )
|
||||
{
|
||||
final Property digestProperty = this.config.get( CACHE_CATEGORY, DIGEST_KEY, DIGEST_DEFAULT );
|
||||
digestProperty.set( digest );
|
||||
|
||||
this.config.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
this.config.save();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.StatCollector;
|
||||
|
||||
import cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry;
|
||||
|
||||
import appeng.core.AELog;
|
||||
|
||||
|
||||
/**
|
||||
* handles the exporting including processing, transformation and persisting the information
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 14.08.2015
|
||||
* @since rv3 14.08.2015
|
||||
*/
|
||||
final class MinecraftItemCSVExporter implements Exporter
|
||||
{
|
||||
private static final String ITEM_CSV_FILE_NAME = "items.csv";
|
||||
private static final String MINIMAL_HEADER = "Mod:Item:MetaData, Localized Name";
|
||||
private static final String VERBOSE_HEADER = MINIMAL_HEADER + ", Unlocalized Name, Is Air?, Class Name";
|
||||
private static final String EXPORT_SUCCESSFUL_MESSAGE = "Exported successfully %d items into %s";
|
||||
private static final String EXPORT_UNSUCCESSFUL_MESSAGE = "Exporting was unsuccessful.";
|
||||
|
||||
@Nonnull
|
||||
private final File exportDirectory;
|
||||
@Nonnull
|
||||
private final FMLControlledNamespacedRegistry<Item> itemRegistry;
|
||||
@Nonnull
|
||||
private final ExportMode mode;
|
||||
|
||||
/**
|
||||
* @param exportDirectory directory of the resulting export file. Non-null required.
|
||||
* @param itemRegistry the registry with minecraft items. Needs to be populated at that time, thus the exporting can only happen in init (pre-init is the
|
||||
* phase when all items are determined)
|
||||
* @param mode mode in which the export should be operated. Resulting CSV will change depending on this.
|
||||
*/
|
||||
MinecraftItemCSVExporter( @Nonnull final File exportDirectory, @Nonnull final FMLControlledNamespacedRegistry<Item> itemRegistry, @Nonnull final ExportMode mode )
|
||||
{
|
||||
this.exportDirectory = Preconditions.checkNotNull( exportDirectory );
|
||||
Preconditions.checkArgument( !exportDirectory.isFile() );
|
||||
this.itemRegistry = Preconditions.checkNotNull( itemRegistry );
|
||||
this.mode = Preconditions.checkNotNull( mode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export()
|
||||
{
|
||||
final Iterable<Item> items = this.itemRegistry.typeSafeIterable();
|
||||
final List<Item> itemList = Lists.newArrayList( items );
|
||||
|
||||
final List<String> lines = Lists.transform( itemList, new ItemRowExtractFunction( this.itemRegistry, this.mode ) );
|
||||
|
||||
final Joiner newLineJoiner = Joiner.on( '\n' );
|
||||
final Joiner newLineJoinerIgnoringNull = newLineJoiner.skipNulls();
|
||||
final String joined = newLineJoinerIgnoringNull.join( lines );
|
||||
|
||||
final File file = new File( this.exportDirectory, ITEM_CSV_FILE_NAME );
|
||||
|
||||
try
|
||||
{
|
||||
FileUtils.forceMkdir( this.exportDirectory );
|
||||
|
||||
final Writer writer = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( file ), Charset.forName("UTF-8") ) );
|
||||
|
||||
final String header = this.mode == ExportMode.MINIMAL ? MINIMAL_HEADER : VERBOSE_HEADER;
|
||||
writer.write( header );
|
||||
writer.write( "\n" );
|
||||
writer.write( joined );
|
||||
writer.flush();
|
||||
writer.close();
|
||||
|
||||
AELog.info( EXPORT_SUCCESSFUL_MESSAGE, lines.size(), ITEM_CSV_FILE_NAME );
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.warning( EXPORT_UNSUCCESSFUL_MESSAGE );
|
||||
AELog.error( e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts item name with meta and the display name
|
||||
*/
|
||||
private static final class TypeExtractFunction implements Function<ItemStack, String>
|
||||
{
|
||||
private static final String EXTRACTING_NULL_MESSAGE = "extracting type null";
|
||||
private static final String EXTRACTING_ITEM_MESSAGE = "extracting type %s:%d";
|
||||
|
||||
@Nonnull
|
||||
private final String itemName;
|
||||
@Nonnull
|
||||
private final ExportMode mode;
|
||||
|
||||
private TypeExtractFunction( @Nonnull final String itemName, @Nonnull final ExportMode mode )
|
||||
{
|
||||
this.itemName = Preconditions.checkNotNull( itemName );
|
||||
Preconditions.checkArgument( !itemName.isEmpty() );
|
||||
|
||||
this.mode = Preconditions.checkNotNull( mode );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply( @Nullable final ItemStack input )
|
||||
{
|
||||
if( input == null )
|
||||
{
|
||||
AELog.debug( EXTRACTING_NULL_MESSAGE );
|
||||
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.debug( EXTRACTING_ITEM_MESSAGE, input.getDisplayName(), input.getItemDamage() );
|
||||
}
|
||||
|
||||
final List<String> joinedBlockAttributes = Lists.newArrayListWithCapacity( 5 );
|
||||
final int meta = input.getItemDamage();
|
||||
final String metaName = this.itemName + ':' + meta;
|
||||
final String localization = input.getDisplayName();
|
||||
|
||||
joinedBlockAttributes.add( metaName );
|
||||
joinedBlockAttributes.add( localization );
|
||||
|
||||
if( this.mode == ExportMode.VERBOSE )
|
||||
{
|
||||
final Item item = input.getItem();
|
||||
final String unlocalizedItem = input.getUnlocalizedName();
|
||||
final Block block = Block.getBlockFromItem( item );
|
||||
final boolean isBlock = !block.equals( Blocks.air );
|
||||
final Class<? extends ItemStack> stackClass = input.getClass();
|
||||
final String stackClassName = stackClass.getName();
|
||||
|
||||
joinedBlockAttributes.add( unlocalizedItem );
|
||||
joinedBlockAttributes.add( Boolean.toString( isBlock ) );
|
||||
joinedBlockAttributes.add( stackClassName );
|
||||
}
|
||||
|
||||
final Joiner csvJoiner = Joiner.on( ", " );
|
||||
final Joiner csvJoinerIgnoringNulls = csvJoiner.skipNulls();
|
||||
|
||||
return csvJoinerIgnoringNulls.join( joinedBlockAttributes );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* transforms an item into a row representation of the CSV file
|
||||
*/
|
||||
private static final class ItemRowExtractFunction implements Function<Item, String>
|
||||
{
|
||||
/**
|
||||
* this extension is required to apply the {@link StatCollector}
|
||||
*/
|
||||
private static final String LOCALIZATION_NAME_EXTENSION = ".name";
|
||||
private static final String EXPORTING_NOTHING_MESSAGE = "Exporting nothing";
|
||||
private static final String EXPORTING_SUBTYPES_MESSAGE = "Exporting input %s with subtypes: %b";
|
||||
|
||||
@Nonnull
|
||||
private final FMLControlledNamespacedRegistry<Item> itemRegistry;
|
||||
@Nonnull
|
||||
private final ExportMode mode;
|
||||
|
||||
/**
|
||||
* @param itemRegistry used to retrieve the name of the item
|
||||
* @param mode extracts more or less information from item depending on mode
|
||||
*/
|
||||
ItemRowExtractFunction( @Nonnull final FMLControlledNamespacedRegistry<Item> itemRegistry, @Nonnull final ExportMode mode )
|
||||
{
|
||||
this.itemRegistry = Preconditions.checkNotNull( itemRegistry );
|
||||
this.mode = Preconditions.checkNotNull( mode );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply( @Nullable final Item input )
|
||||
{
|
||||
if( input == null )
|
||||
{
|
||||
AELog.debug( EXPORTING_NOTHING_MESSAGE );
|
||||
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.debug( EXPORTING_SUBTYPES_MESSAGE, input.getUnlocalizedName(), input.getHasSubtypes() );
|
||||
}
|
||||
|
||||
final String itemName = this.itemRegistry.getNameForObject( input );
|
||||
final boolean hasSubtypes = input.getHasSubtypes();
|
||||
if( hasSubtypes )
|
||||
{
|
||||
final CreativeTabs creativeTab = input.getCreativeTab();
|
||||
final List<ItemStack> stacks = Lists.newArrayList();
|
||||
|
||||
// modifies the stacks list and adds the different sub types to it
|
||||
try
|
||||
{
|
||||
input.getSubItems( input, creativeTab, stacks );
|
||||
}
|
||||
catch( final Exception ignored )
|
||||
{
|
||||
AELog.error( ignored );
|
||||
|
||||
// ignore if mods do bullshit in their code
|
||||
return null;
|
||||
}
|
||||
|
||||
// list can be empty, no clue why
|
||||
if( stacks.isEmpty() )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Joiner newLineJoiner = Joiner.on( '\n' );
|
||||
final Joiner typeJoiner = newLineJoiner.skipNulls();
|
||||
final List<String> transformedTypes = Lists.transform( stacks, new TypeExtractFunction( itemName, this.mode ) );
|
||||
|
||||
return typeJoiner.join( transformedTypes );
|
||||
}
|
||||
|
||||
final List<String> joinedBlockAttributes = Lists.newArrayListWithCapacity( 5 );
|
||||
final String unlocalizedItem = input.getUnlocalizedName();
|
||||
final String localization = StatCollector.translateToLocal( unlocalizedItem + LOCALIZATION_NAME_EXTENSION );
|
||||
|
||||
joinedBlockAttributes.add( itemName );
|
||||
joinedBlockAttributes.add( localization );
|
||||
|
||||
if( this.mode == ExportMode.VERBOSE )
|
||||
{
|
||||
final Block block = Block.getBlockFromItem( input );
|
||||
final boolean isBlock = !block.equals( Blocks.air );
|
||||
final Class<? extends Item> itemClass = input.getClass();
|
||||
final String itemClassName = itemClass.getName();
|
||||
|
||||
joinedBlockAttributes.add( unlocalizedItem );
|
||||
joinedBlockAttributes.add( Boolean.toString( isBlock ) );
|
||||
joinedBlockAttributes.add( itemClassName );
|
||||
}
|
||||
|
||||
final Joiner csvJoiner = Joiner.on( ", " );
|
||||
final Joiner csvJoinerIgnoringNulls = csvJoiner.skipNulls();
|
||||
|
||||
return csvJoinerIgnoringNulls.join( joinedBlockAttributes );
|
||||
}
|
||||
}
|
||||
}
|
92
src/main/java/appeng/services/export/ModListChecker.java
Normal file
92
src/main/java/appeng/services/export/ModListChecker.java
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
|
||||
/**
|
||||
* Checks the cached digest against the current mods including their versions.
|
||||
* Use the config to manipulate the process
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 01.09.2015
|
||||
* @since rv3 - 01.09.2015
|
||||
*/
|
||||
final class ModListChecker implements Checker<List<ModContainer>>
|
||||
{
|
||||
private final String configHashValue;
|
||||
|
||||
@Nonnull
|
||||
private final ExportConfig config;
|
||||
|
||||
/**
|
||||
* @param config uses the config to retrieve the old hash of the mod list
|
||||
*/
|
||||
ModListChecker( @Nonnull final ExportConfig config )
|
||||
{
|
||||
this.config = Preconditions.checkNotNull( config );
|
||||
this.configHashValue = Preconditions.checkNotNull( config.getCache() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles a list of all mods and their versions to a digest which is updated, if it differs from the config. This is used to elevate the need to export
|
||||
* the csv once again, if no change was detected.
|
||||
*
|
||||
* @param modContainers all mods and their versions to check if a difference exists between the current instance and the previous instance
|
||||
*
|
||||
* @return CheckType.EQUAL if no change was detected
|
||||
*/
|
||||
@Nonnull
|
||||
@Override
|
||||
public CheckType isEqual( @Nonnull final List<ModContainer> modContainers )
|
||||
{
|
||||
Preconditions.checkNotNull( modContainers );
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
for( final ModContainer container : modContainers )
|
||||
{
|
||||
builder.append( container.getModId() );
|
||||
builder.append( container.getVersion() );
|
||||
}
|
||||
|
||||
final String allModsAndVersions = builder.toString();
|
||||
final String hex = DigestUtils.md5Hex( allModsAndVersions );
|
||||
|
||||
if( hex.equals( this.configHashValue ) )
|
||||
{
|
||||
return CheckType.EQUAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.config.setCache( hex );
|
||||
|
||||
return CheckType.UNEQUAL;
|
||||
}
|
||||
}
|
||||
}
|
33
src/main/java/appeng/services/export/package-info.java
Normal file
33
src/main/java/appeng/services/export/package-info.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* the export package is to export all the required information for recipes into a convenient CSV file
|
||||
* often names are difficult to acquire without access to the internal names.
|
||||
*
|
||||
* To save from rescanning every start-up it can save a list of mods and their version
|
||||
* and if only something changed, it requires to update the CSV.
|
||||
*
|
||||
* There is no explicit check if it was manually tempered
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 14.08.2015
|
||||
* @since rv3 14.08.2015
|
||||
*/
|
||||
|
||||
package appeng.services.export;
|
|
@ -65,7 +65,7 @@ public final class VersionCheckerConfig
|
|||
this.shouldPostChangelog = this.config.getBoolean( "changelog", "client", true, "If true, the player is getting a notification including changelog. Only happens if notification are enabled." );
|
||||
}
|
||||
|
||||
public boolean isEnabled()
|
||||
public boolean isVersionCheckingEnabled()
|
||||
{
|
||||
return this.isEnabled;
|
||||
}
|
||||
|
@ -76,8 +76,7 @@ public final class VersionCheckerConfig
|
|||
}
|
||||
|
||||
/**
|
||||
* Stores the current date in milli seconds into the "lastCheck" field of the config
|
||||
* and makes it persistent.
|
||||
* Stores the current date in milli seconds into the "lastCheck" field of the config and makes it persistent.
|
||||
*/
|
||||
public void updateLastCheck()
|
||||
{
|
||||
|
@ -109,4 +108,12 @@ public final class VersionCheckerConfig
|
|||
{
|
||||
return this.shouldPostChangelog;
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
if( this.config.hasChanged() )
|
||||
{
|
||||
this.config.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
* 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
|
||||
|
@ -23,6 +23,7 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.WorldProvider;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.world.biome.WorldChunkManagerHell;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
|
@ -32,6 +33,7 @@ import cpw.mods.fml.relauncher.Side;
|
|||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
import appeng.client.render.SpatialSkyRender;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.core.Registration;
|
||||
|
||||
|
||||
|
@ -46,7 +48,11 @@ public class StorageWorldProvider extends WorldProvider
|
|||
@Override
|
||||
protected void registerWorldChunkManager()
|
||||
{
|
||||
super.worldChunkMgr = new WorldChunkManagerHell( Registration.INSTANCE.storageBiome, 0.0F );
|
||||
final AppEng ae2internal = AppEng.instance();
|
||||
final Registration ae2registration = ae2internal.getRegistration();
|
||||
final BiomeGenBase storageBiome = ae2registration.getStorageBiome();
|
||||
|
||||
super.worldChunkMgr = new WorldChunkManagerHell( storageBiome, 0.0F );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import=processing/factorization.recipe
|
||||
import=processing/grind.recipe
|
||||
import=processing/hydralicraft.recipe
|
||||
import=processing/hydraulicraft.recipe
|
||||
import=processing/ic2.recipe
|
||||
import=processing/mekanism.recipe
|
||||
import=processing/rotarycraft.recipe
|
||||
|
|
Loading…
Reference in a new issue