Added a new facade config. (#3706)
The whitelist is now based on manually add explicit entries instead of automatically adding every existing block. This alone should save a few MB of RAM depending on the modpack size. Additionally the FacadeConfig is no longer extending the normal Configuration provided by Forge. It will only parse the file once per start and store the settings in an optimised collection to further reduce memory consumption. Any full block without a TileEntity and having a model is whitelisted automatically and does not need an explicit entry anymore. By default vanilla and AE2 glass is added as they are no fullblocks technically. The whitelist technically allows many more blocks now. E.g. stairs, slabs or even items like saplings. But with various rendering quality. Further there is an option to allow facades based on TileEntities, this is completely unsupported and can work or corrupt the whole save.
This commit is contained in:
@@ -20,32 +20,124 @@ package appeng.core;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.config.ConfigCategory;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.minecraftforge.common.config.Property;
|
||||
import net.minecraftforge.common.config.Property.Type;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
|
||||
|
||||
public class FacadeConfig extends Configuration
|
||||
public class FacadeConfig
|
||||
{
|
||||
|
||||
private static final String CONFIG_VERSION = "1";
|
||||
private static final String CONFIG_COMMON_KEY = "common";
|
||||
private static final String CONFIG_COMMON_COMMENT = "Settings applied to all facades.\n\n" //
|
||||
+ "By default full blocks with no tile entity and a model do not need whitelisting.\n"//
|
||||
+ "This will only be read once during client startup.";
|
||||
private static final String CONFIG_COMMON_ALLOW_TILEENTITIES_KEY = "allowTileEntityFacades";
|
||||
private static final String CONFIG_COMMON_ALLOW_TILEENTITIES_COMMENT = "Unsupported: Allows whitelisting TileEntity as facades. Could work, have render issues, or corrupt your world. USE AT YOUR OWN RISK.";
|
||||
private static final String CONFIG_FACADES_KEY = "facades";
|
||||
private static final String CONFIG_FACADES_COMMENT = "A way to explicitly handle certain blocks as facades.\n\n" //
|
||||
+ "Blocks can be added by their resource location under the following rules.\n" //
|
||||
+ " - One category per domain like minecraft or appliedenergistics2\n" //
|
||||
+ " - One key per id. E.g. glass in case of minecraft:glass\n" //
|
||||
+ " - An integer value ranging from 0 to 16 representing the metadata 0-15 and 16 as wildcard for all" //
|
||||
+ " - Multiple entries for the same id but different metadata are possible when needed";
|
||||
|
||||
private static FacadeConfig instance;
|
||||
|
||||
private final Pattern replacementPattern;
|
||||
private final boolean allowTileEntityFacades;
|
||||
private final Object2IntMap<ResourceLocation> whiteList;
|
||||
|
||||
public FacadeConfig( final File facadeFile )
|
||||
private FacadeConfig( boolean allowTileEntityFacades, Object2IntMap<ResourceLocation> whiteList )
|
||||
{
|
||||
super( facadeFile );
|
||||
this.replacementPattern = Pattern.compile( "[^a-zA-Z0-9]" );
|
||||
this.allowTileEntityFacades = allowTileEntityFacades;
|
||||
this.whiteList = whiteList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a custom confuration based on a {@link Configuration}, but ultimately throws it away after reading it
|
||||
* once to save a couple MB of memory.
|
||||
*
|
||||
* @param configFile
|
||||
*/
|
||||
public static void init( final File configFile )
|
||||
{
|
||||
instance = new FacadeConfig( configFile );
|
||||
final Configuration configurartion = migrate( new Configuration( configFile, CONFIG_VERSION ) );
|
||||
|
||||
final boolean allowTileEntityFacades = configurartion
|
||||
.get( CONFIG_COMMON_KEY, CONFIG_COMMON_ALLOW_TILEENTITIES_KEY, false, CONFIG_COMMON_ALLOW_TILEENTITIES_COMMENT )
|
||||
.setRequiresMcRestart( true )
|
||||
.setShowInGui( false )
|
||||
.getBoolean();
|
||||
|
||||
final Object2IntMap<ResourceLocation> configWhiteList = new Object2IntArrayMap<>();
|
||||
|
||||
final Set<ConfigCategory> whitelist = configurartion.getCategory( CONFIG_FACADES_KEY ).getChildren();
|
||||
for( ConfigCategory configCategory : whitelist )
|
||||
{
|
||||
final String domain = configCategory.getName();
|
||||
final Map<String, Property> values = configCategory.getValues();
|
||||
|
||||
for( Entry<String, Property> entry : values.entrySet() )
|
||||
{
|
||||
configWhiteList.put( new ResourceLocation( domain, entry.getKey() ), entry.getValue().getInt() );
|
||||
}
|
||||
}
|
||||
|
||||
if( configurartion.hasChanged() )
|
||||
{
|
||||
configurartion.save();
|
||||
}
|
||||
|
||||
instance = new FacadeConfig( allowTileEntityFacades, configWhiteList );
|
||||
}
|
||||
|
||||
private static Configuration migrate( Configuration configurartion )
|
||||
{
|
||||
// Clear pre rv6 configs.
|
||||
if( configurartion.getLoadedConfigVersion() == null )
|
||||
{
|
||||
for( String category : configurartion.getCategoryNames() )
|
||||
{
|
||||
final ConfigCategory c = configurartion.getCategory( category );
|
||||
configurartion.removeCategory( c );
|
||||
}
|
||||
}
|
||||
|
||||
// Create general category, if missing
|
||||
if( !configurartion.hasCategory( CONFIG_COMMON_KEY ) )
|
||||
{
|
||||
configurartion.getCategory( CONFIG_COMMON_KEY ).setComment( CONFIG_COMMON_COMMENT );
|
||||
}
|
||||
|
||||
// Create whitelist, if missing
|
||||
if( !configurartion.hasCategory( CONFIG_FACADES_KEY ) )
|
||||
{
|
||||
final ConfigCategory category = configurartion.getCategory( CONFIG_FACADES_KEY );
|
||||
category.setComment( CONFIG_FACADES_COMMENT );
|
||||
|
||||
// Whitelist some vanilla blocks like glass
|
||||
final ConfigCategory minecraft = new ConfigCategory( "minecraft", category );
|
||||
minecraft.put( "glass", new Property( "glass", "16", Type.INTEGER ) );
|
||||
minecraft.put( "stained_glass", new Property( "stained_glass", "16", Type.INTEGER ) );
|
||||
|
||||
// Whitelist some AE2 blocks like quartz glass
|
||||
final ConfigCategory appliedenergistics = new ConfigCategory( "appliedenergistics2", category );
|
||||
appliedenergistics.put( "quartz_glass", new Property( "quartz_glass", "16", Type.INTEGER ) );
|
||||
appliedenergistics.put( "quartz_vibrant_glass", new Property( "quartz_vibrant_glass", "16", Type.INTEGER ) );
|
||||
}
|
||||
|
||||
return configurartion;
|
||||
}
|
||||
|
||||
public static FacadeConfig instance()
|
||||
@@ -53,36 +145,18 @@ public class FacadeConfig extends Configuration
|
||||
return instance;
|
||||
}
|
||||
|
||||
public boolean checkEnabled( final Block id, final int metadata, final boolean automatic )
|
||||
public boolean allowTileEntityFacades()
|
||||
{
|
||||
if( id == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.allowTileEntityFacades;
|
||||
}
|
||||
|
||||
final ResourceLocation blk = Item.REGISTRY.getNameForObject( Item.getItemFromBlock( id ) );
|
||||
if( blk == null )
|
||||
public boolean isWhiteListed( final Block block, final int metadata )
|
||||
{
|
||||
final Integer entry = this.whiteList.get( block.getRegistryName() );
|
||||
|
||||
if( entry != null )
|
||||
{
|
||||
for( final Field f : Block.class.getFields() )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( f.get( Block.class ) == id )
|
||||
{
|
||||
return this.get( "minecraft", f.getName() + ( metadata == 0 ? "" : "/" + metadata ), automatic ).getBoolean( automatic );
|
||||
}
|
||||
}
|
||||
catch( final Throwable e )
|
||||
{
|
||||
// :P
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final Matcher mod = this.replacementPattern.matcher( blk.getResourceDomain() );
|
||||
final Matcher name = this.replacementPattern.matcher( blk.getResourcePath() );
|
||||
return this.get( mod.replaceAll( "" ), name.replaceAll( "" ) + ( metadata == 0 ? "" : "." + metadata ), automatic ).getBoolean( automatic );
|
||||
return entry == metadata || entry == 16;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user