mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2026-08-14 14:28:54 +00:00
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
This commit is contained in:
@@ -12,496 +12,333 @@ import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.turtle.event.TurtleAction;
|
||||
import dan200.computercraft.core.apis.AddressPredicate;
|
||||
import dan200.computercraft.core.apis.http.websocket.Websocket;
|
||||
import net.minecraftforge.common.config.ConfigCategory;
|
||||
import net.minecraftforge.common.config.ConfigElement;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.minecraftforge.common.config.Property;
|
||||
import net.minecraftforge.fml.client.config.IConfigElement;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static dan200.computercraft.ComputerCraft.DEFAULT_HTTP_BLACKLIST;
|
||||
import static dan200.computercraft.ComputerCraft.DEFAULT_HTTP_WHITELIST;
|
||||
import static net.minecraftforge.common.ForgeConfigSpec.Builder;
|
||||
import static net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
|
||||
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD )
|
||||
public final class Config
|
||||
{
|
||||
private static final int MODEM_MAX_RANGE = 100000;
|
||||
|
||||
private static final String CATEGORY_GENERAL = "general";
|
||||
private static final String CATEGORY_EXECUTION = "execution";
|
||||
private static final String CATEGORY_HTTP = "http";
|
||||
private static final String CATEGORY_PERIPHERAL = "peripheral";
|
||||
private static final String CATEGORY_TURTLE = "turtle";
|
||||
private static final String TRANSLATION_PREFIX = "gui.computercraft.config.";
|
||||
|
||||
private static Configuration config;
|
||||
private static ConfigValue<Integer> computerSpaceLimit;
|
||||
private static ConfigValue<Integer> floppySpaceLimit;
|
||||
private static ConfigValue<Integer> maximumFilesOpen;
|
||||
private static ConfigValue<Boolean> disableLua51Features;
|
||||
private static ConfigValue<String> defaultComputerSettings;
|
||||
private static ConfigValue<Boolean> debugEnabled;
|
||||
private static ConfigValue<Boolean> logComputerErrors;
|
||||
|
||||
private static Property computerSpaceLimit;
|
||||
private static Property floppySpaceLimit;
|
||||
private static Property maximumFilesOpen;
|
||||
private static Property disableLua51Features;
|
||||
private static Property defaultComputerSettings;
|
||||
private static Property debugEnabled;
|
||||
private static Property logComputerErrors;
|
||||
private static ConfigValue<Integer> computerThreads;
|
||||
private static ConfigValue<Long> maxMainGlobalTime;
|
||||
private static ConfigValue<Long> maxMainComputerTime;
|
||||
|
||||
private static Property computerThreads;
|
||||
private static Property maxMainGlobalTime;
|
||||
private static Property maxMainComputerTime;
|
||||
private static ConfigValue<Boolean> httpEnabled;
|
||||
private static ConfigValue<Boolean> httpWebsocketEnabled;
|
||||
private static ConfigValue<List<? extends String>> httpWhitelist;
|
||||
private static ConfigValue<List<? extends String>> httpBlacklist;
|
||||
|
||||
private static Property httpEnable;
|
||||
private static Property httpWebsocketEnable;
|
||||
private static Property httpWhitelist;
|
||||
private static Property httpBlacklist;
|
||||
private static ConfigValue<Integer> httpTimeout;
|
||||
private static ConfigValue<Integer> httpMaxRequests;
|
||||
private static ConfigValue<Long> httpMaxDownload;
|
||||
private static ConfigValue<Long> httpMaxUpload;
|
||||
private static ConfigValue<Integer> httpMaxWebsockets;
|
||||
private static ConfigValue<Integer> httpMaxWebsocketMessage;
|
||||
|
||||
private static Property httpTimeout;
|
||||
private static Property httpMaxRequests;
|
||||
private static Property httpMaxDownload;
|
||||
private static Property httpMaxUpload;
|
||||
private static Property httpMaxWebsockets;
|
||||
private static Property httpMaxWebsocketMessage;
|
||||
private static ConfigValue<Boolean> commandBlockEnabled;
|
||||
private static ConfigValue<Integer> modemRange;
|
||||
private static ConfigValue<Integer> modemHighAltitudeRange;
|
||||
private static ConfigValue<Integer> modemRangeDuringStorm;
|
||||
private static ConfigValue<Integer> modemHighAltitudeRangeDuringStorm;
|
||||
private static ConfigValue<Integer> maxNotesPerTick;
|
||||
|
||||
private static Property commandBlockEnabled;
|
||||
private static Property modemRange;
|
||||
private static Property modemHighAltitudeRange;
|
||||
private static Property modemRangeDuringStorm;
|
||||
private static Property modemHighAltitudeRangeDuringStorm;
|
||||
private static Property maxNotesPerTick;
|
||||
private static ConfigValue<Boolean> turtlesNeedFuel;
|
||||
private static ConfigValue<Integer> turtleFuelLimit;
|
||||
private static ConfigValue<Integer> advancedTurtleFuelLimit;
|
||||
private static ConfigValue<Boolean> turtlesObeyBlockProtection;
|
||||
private static ConfigValue<Boolean> turtlesCanPush;
|
||||
private static ConfigValue<List<? extends String>> turtleDisabledActions;
|
||||
|
||||
private static Property turtlesNeedFuel;
|
||||
private static Property turtleFuelLimit;
|
||||
private static Property advancedTurtleFuelLimit;
|
||||
private static Property turtlesObeyBlockProtection;
|
||||
private static Property turtlesCanPush;
|
||||
private static Property turtleDisabledActions;
|
||||
private static final ForgeConfigSpec spec;
|
||||
|
||||
private Config() {}
|
||||
|
||||
public static void load( File configFile )
|
||||
static
|
||||
{
|
||||
config = new Configuration( configFile, ComputerCraft.getVersion() );
|
||||
|
||||
config.load();
|
||||
Builder builder = new Builder();
|
||||
|
||||
{ // General computers
|
||||
renameProperty( CATEGORY_GENERAL, "computerSpaceLimit", CATEGORY_GENERAL, "computer_space_limit" );
|
||||
renameProperty( CATEGORY_GENERAL, "floppySpaceLimit", CATEGORY_GENERAL, "floppy_space_limit" );
|
||||
renameProperty( CATEGORY_GENERAL, "maximumFilesOpen", CATEGORY_GENERAL, "maximum_open_files" );
|
||||
renameProperty( CATEGORY_GENERAL, "debug_enable", CATEGORY_GENERAL, "debug_enabled" );
|
||||
renameProperty( CATEGORY_GENERAL, "logPeripheralErrors", CATEGORY_GENERAL, "log_computer_errors" );
|
||||
computerSpaceLimit = builder
|
||||
.comment( "The disk space limit for computers and turtles, in bytes" )
|
||||
.translation( TRANSLATION_PREFIX + "computer_space_limit" )
|
||||
.define( "computer_space_limit", ComputerCraft.computerSpaceLimit );
|
||||
|
||||
computerSpaceLimit = config.get( CATEGORY_GENERAL, "computer_space_limit", ComputerCraft.computerSpaceLimit );
|
||||
computerSpaceLimit.setComment( "The disk space limit for computers and turtles, in bytes" );
|
||||
floppySpaceLimit = builder
|
||||
.comment( "The disk space limit for floppy disks, in bytes" )
|
||||
.translation( TRANSLATION_PREFIX + "floppy_space_limit" )
|
||||
.define( "floppy_space_limit", ComputerCraft.floppySpaceLimit );
|
||||
|
||||
floppySpaceLimit = config.get( CATEGORY_GENERAL, "floppy_space_limit", ComputerCraft.floppySpaceLimit );
|
||||
floppySpaceLimit.setComment( "The disk space limit for floppy disks, in bytes" );
|
||||
maximumFilesOpen = builder
|
||||
.comment( "Set how many files a computer can have open at the same time. Set to 0 for unlimited." )
|
||||
.translation( TRANSLATION_PREFIX + "maximum_open_files" )
|
||||
.defineInRange( "maximum_open_files", ComputerCraft.maximumFilesOpen, 0, Integer.MAX_VALUE );
|
||||
|
||||
maximumFilesOpen = config.get( CATEGORY_GENERAL, "maximum_open_files", ComputerCraft.maximumFilesOpen );
|
||||
maximumFilesOpen.setComment( "Set how many files a computer can have open at the same time. Set to 0 for unlimited." );
|
||||
maximumFilesOpen.setMinValue( 0 );
|
||||
disableLua51Features = builder
|
||||
.comment( "Set this to true to disable Lua 5.1 functions that will be removed in a future update. " +
|
||||
"Useful for ensuring forward compatibility of your programs now." )
|
||||
.define( "disable_lua51_features", ComputerCraft.disable_lua51_features );
|
||||
|
||||
disableLua51Features = config.get( CATEGORY_GENERAL, "disable_lua51_features", ComputerCraft.disable_lua51_features );
|
||||
disableLua51Features.setComment( "Set this to true to disable Lua 5.1 functions that will be removed in a future " +
|
||||
"update. Useful for ensuring forward compatibility of your programs now." );
|
||||
defaultComputerSettings = builder
|
||||
.comment( "A comma separated list of default system settings to set on new computers. Example: " +
|
||||
"\"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\" will disable all " +
|
||||
"autocompletion" )
|
||||
.define( "default_computer_settings", ComputerCraft.default_computer_settings );
|
||||
|
||||
defaultComputerSettings = config.get( CATEGORY_GENERAL, "default_computer_settings", ComputerCraft.default_computer_settings );
|
||||
defaultComputerSettings.setComment( "A comma separated list of default system settings to set on new computers. Example: " +
|
||||
"\"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\" will disable all autocompletion" );
|
||||
debugEnabled = builder
|
||||
.comment( "Enable Lua's debug library. This is sandboxed to each computer, so is generally safe to be used by players." )
|
||||
.define( "debug_enabled", ComputerCraft.debug_enable );
|
||||
|
||||
debugEnabled = config.get( CATEGORY_GENERAL, "debug_enabled", ComputerCraft.debug_enable );
|
||||
debugEnabled.setComment( "Enable Lua's debug library. This is sandboxed to each computer, so is generally safe to be used by players." );
|
||||
|
||||
logComputerErrors = config.get( CATEGORY_GENERAL, "log_computer_errors", ComputerCraft.logPeripheralErrors );
|
||||
logComputerErrors.setComment( "Log exceptions thrown by peripherals and other Lua objects.\n" +
|
||||
"This makes it easier for mod authors to debug problems, but may result in log spam should people use buggy methods." );
|
||||
|
||||
setOrder(
|
||||
CATEGORY_GENERAL,
|
||||
computerSpaceLimit, floppySpaceLimit, maximumFilesOpen,
|
||||
disableLua51Features, defaultComputerSettings, debugEnabled, logComputerErrors
|
||||
);
|
||||
logComputerErrors = builder
|
||||
.comment( "Log exceptions thrown by peripherals and other Lua objects.\n" +
|
||||
"This makes it easier for mod authors to debug problems, but may result in log spam should people use buggy methods." )
|
||||
.define( "log_computer_errors", ComputerCraft.logPeripheralErrors );
|
||||
}
|
||||
|
||||
{ // Execution
|
||||
renameProperty( CATEGORY_GENERAL, "computer_threads", CATEGORY_EXECUTION, "computer_threads" );
|
||||
{
|
||||
builder.comment( "Controls execution behaviour of computers. This is largely intended for fine-tuning " +
|
||||
"servers, and generally shouldn't need to be touched" );
|
||||
builder.push( "execution" );
|
||||
|
||||
config.getCategory( CATEGORY_EXECUTION )
|
||||
.setComment( "Controls execution behaviour of computers. This is largely intended for fine-tuning " +
|
||||
"servers, and generally shouldn't need to be touched" );
|
||||
computerThreads = builder
|
||||
.comment( "Set the number of threads computers can run on. A higher number means more computers can run " +
|
||||
"at once, but may induce lag.\n" +
|
||||
"Please note that some mods may not work with a thread count higher than 1. Use with caution." )
|
||||
.worldRestart()
|
||||
.defineInRange( "computer_threads", ComputerCraft.computer_threads, 1, Integer.MAX_VALUE );
|
||||
|
||||
computerThreads = config.get( CATEGORY_EXECUTION, "computer_threads", ComputerCraft.computer_threads );
|
||||
computerThreads
|
||||
.setMinValue( 1 )
|
||||
.setRequiresMcRestart( true )
|
||||
.setComment( "Set the number of threads computers can run on. A higher number means more computers can " +
|
||||
"run at once, but may induce lag.\n" +
|
||||
"Please note that some mods may not work with a thread count higher than 1. Use with caution." );
|
||||
maxMainGlobalTime = builder
|
||||
.comment( "The maximum time that can be spent executing tasks in a single tick, in milliseconds.\n" +
|
||||
"Note, we will quite possibly go over this limit, as there's no way to tell how long a will take " +
|
||||
"- this aims to be the upper bound of the average time." )
|
||||
.defineInRange( "max_main_global_time", TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainGlobalTime ), 1, Long.MAX_VALUE );
|
||||
|
||||
maxMainGlobalTime = config.get( CATEGORY_EXECUTION, "max_main_global_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainGlobalTime ) );
|
||||
maxMainGlobalTime
|
||||
.setMinValue( 1 )
|
||||
.setComment( "The maximum time that can be spent executing tasks in a single tick, in milliseconds.\n" +
|
||||
"Note, we will quite possibly go over this limit, as there's no way to tell how long a will take - this aims " +
|
||||
"to be the upper bound of the average time." );
|
||||
maxMainComputerTime = builder
|
||||
.comment( "The ideal maximum time a computer can execute for in a tick, in milliseconds.\n" +
|
||||
"Note, we will quite possibly go over this limit, as there's no way to tell how long a will take " +
|
||||
"- this aims to be the upper bound of the average time." )
|
||||
.defineInRange( "max_main_computer_time", TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainComputerTime ), 1, Long.MAX_VALUE );
|
||||
|
||||
maxMainComputerTime = config.get( CATEGORY_EXECUTION, "max_main_computer_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainComputerTime ) );
|
||||
maxMainComputerTime
|
||||
.setMinValue( 1 )
|
||||
.setComment( "The ideal maximum time a computer can execute for in a tick, in milliseconds.\n" +
|
||||
"Note, we will quite possibly go over this limit, as there's no way to tell how long a will take - this aims " +
|
||||
"to be the upper bound of the average time." );
|
||||
|
||||
setOrder(
|
||||
CATEGORY_EXECUTION,
|
||||
computerThreads, maxMainGlobalTime, maxMainComputerTime
|
||||
);
|
||||
builder.pop();
|
||||
}
|
||||
|
||||
{ // HTTP
|
||||
renameProperty( CATEGORY_GENERAL, "http_enable", CATEGORY_HTTP, "enabled" );
|
||||
renameProperty( CATEGORY_GENERAL, "http_websocket_enable", CATEGORY_HTTP, "websocket_enabled" );
|
||||
renameProperty( CATEGORY_GENERAL, "http_whitelist", CATEGORY_HTTP, "whitelist" );
|
||||
renameProperty( CATEGORY_GENERAL, "http_blacklist", CATEGORY_HTTP, "blacklist" );
|
||||
builder.comment( "Controls the HTTP API" );
|
||||
builder.push( "http" );
|
||||
|
||||
config.getCategory( CATEGORY_HTTP )
|
||||
.setComment( "Controls the HTTP API" );
|
||||
httpEnabled = builder
|
||||
.comment( "Enable the \"http\" API on Computers (see \"http_whitelist\" and \"http_blacklist\" for more " +
|
||||
"fine grained control than this)" )
|
||||
.define( "enabled", ComputerCraft.http_enable );
|
||||
|
||||
httpEnable = config.get( CATEGORY_HTTP, "enabled", ComputerCraft.http_enable );
|
||||
httpEnable.setComment( "Enable the \"http\" API on Computers (see \"http_whitelist\" and \"http_blacklist\" for " +
|
||||
"more fine grained control than this)" );
|
||||
httpWebsocketEnabled = builder
|
||||
.comment( "Enable use of http websockets. This requires the \"http_enable\" option to also be true." )
|
||||
.define( "websocket_enabled", ComputerCraft.http_websocket_enable );
|
||||
|
||||
httpWebsocketEnable = config.get( CATEGORY_HTTP, "websocket_enabled", ComputerCraft.http_websocket_enable );
|
||||
httpWebsocketEnable.setComment( "Enable use of http websockets. This requires the \"http_enable\" option to also be true." );
|
||||
httpWhitelist = builder
|
||||
.comment( "A list of wildcards for domains or IP ranges that can be accessed through the \"http\" API on Computers.\n" +
|
||||
"Set this to \"*\" to access to the entire internet. Example: \"*.pastebin.com\" will restrict access to just subdomains of pastebin.com.\n" +
|
||||
"You can use domain names (\"pastebin.com\"), wilcards (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\")." )
|
||||
.defineList( "whitelist", Arrays.asList( DEFAULT_HTTP_WHITELIST ), x -> true );
|
||||
|
||||
httpWhitelist = config.get( CATEGORY_HTTP, "whitelist", DEFAULT_HTTP_WHITELIST );
|
||||
httpWhitelist.setComment( "A list of wildcards for domains or IP ranges that can be accessed through the " +
|
||||
"\"http\" API on Computers.\n" +
|
||||
"Set this to \"*\" to access to the entire internet. Example: \"*.pastebin.com\" will restrict access to " +
|
||||
"just subdomains of pastebin.com.\n" +
|
||||
"You can use domain names (\"pastebin.com\"), wilcards (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\")." );
|
||||
httpBlacklist = builder
|
||||
.comment( "A list of wildcards for domains or IP ranges that cannot be accessed through the \"http\" API on Computers.\n" +
|
||||
"If this is empty then all whitelisted domains will be accessible. Example: \"*.github.com\" will block access to all subdomains of github.com.\n" +
|
||||
"You can use domain names (\"pastebin.com\"), wilcards (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\")." )
|
||||
.defineList( "blacklist", Arrays.asList( DEFAULT_HTTP_BLACKLIST ), x -> true );
|
||||
|
||||
httpBlacklist = config.get( CATEGORY_HTTP, "blacklist", DEFAULT_HTTP_BLACKLIST );
|
||||
httpBlacklist.setComment( "A list of wildcards for domains or IP ranges that cannot be accessed through the " +
|
||||
"\"http\" API on Computers.\n" +
|
||||
"If this is empty then all whitelisted domains will be accessible. Example: \"*.github.com\" will block " +
|
||||
"access to all subdomains of github.com.\n" +
|
||||
"You can use domain names (\"pastebin.com\"), wilcards (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\")." );
|
||||
httpTimeout = builder
|
||||
.comment( "The period of time (in milliseconds) to wait before a HTTP request times out. Set to 0 for unlimited." )
|
||||
.defineInRange( "timeout", ComputerCraft.httpTimeout, 0, Integer.MAX_VALUE );
|
||||
|
||||
httpTimeout = config.get( CATEGORY_HTTP, "timeout", ComputerCraft.httpTimeout );
|
||||
httpTimeout.setComment( "The period of time (in milliseconds) to wait before a HTTP request times out. Set to 0 for unlimited." );
|
||||
httpTimeout.setMinValue( 0 );
|
||||
httpMaxRequests = builder
|
||||
.comment( "The number of http requests a computer can make at one time. Additional requests will be queued, and sent when the running requests have finished. Set to 0 for unlimited." )
|
||||
.defineInRange( "max_requests", ComputerCraft.httpMaxRequests, 0, Integer.MAX_VALUE );
|
||||
|
||||
httpMaxRequests = config.get( CATEGORY_HTTP, "max_requests", ComputerCraft.httpMaxRequests );
|
||||
httpMaxRequests.setComment( "The number of http requests a computer can make at one time. Additional requests " +
|
||||
"will be queued, and sent when the running requests have finished. Set to 0 for unlimited." );
|
||||
httpMaxRequests.setMinValue( 0 );
|
||||
httpMaxDownload = builder
|
||||
.comment( "The maximum size (in bytes) that a computer can download in a single request. Note that responses may receive more data than allowed, but this data will not be returned to the client." )
|
||||
.defineInRange( "max_download", ComputerCraft.httpMaxDownload, 0, Long.MAX_VALUE );
|
||||
|
||||
httpMaxDownload = config.get( CATEGORY_HTTP, "max_download", (int) ComputerCraft.httpMaxDownload );
|
||||
httpMaxDownload.setComment( "The maximum size (in bytes) that a computer can download in a single request. " +
|
||||
"Note that responses may receive more data than allowed, but this data will not be returned to the client." );
|
||||
httpMaxDownload.setMinValue( 0 );
|
||||
httpMaxUpload = builder
|
||||
.comment( "The maximum size (in bytes) that a computer can upload in a single request. This includes headers and POST text." )
|
||||
.defineInRange( "max_upload", ComputerCraft.httpMaxUpload, 0, Long.MAX_VALUE );
|
||||
|
||||
httpMaxUpload = config.get( CATEGORY_HTTP, "max_upload", (int) ComputerCraft.httpMaxUpload );
|
||||
httpMaxUpload.setComment( "The maximum size (in bytes) that a computer can upload in a single request. This " +
|
||||
"includes headers and POST text." );
|
||||
httpMaxUpload.setMinValue( 0 );
|
||||
httpMaxWebsockets = builder
|
||||
.comment( "The number of websockets a computer can have open at one time. Set to 0 for unlimited." )
|
||||
.defineInRange( "max_websockets", ComputerCraft.httpMaxWebsockets, 1, Integer.MAX_VALUE );
|
||||
|
||||
httpMaxWebsockets = config.get( CATEGORY_HTTP, "max_websockets", ComputerCraft.httpMaxWebsockets );
|
||||
httpMaxWebsockets.setComment( "The number of websockets a computer can have open at one time. Set to 0 for unlimited." );
|
||||
httpMaxWebsockets.setMinValue( 1 );
|
||||
httpMaxWebsocketMessage = builder
|
||||
.comment( "The maximum size (in bytes) that a computer can send or receive in one websocket packet." )
|
||||
.defineInRange( "max_websocket_message", ComputerCraft.httpMaxWebsocketMessage, 0, Websocket.MAX_MESSAGE_SIZE );
|
||||
|
||||
httpMaxWebsocketMessage = config.get( CATEGORY_HTTP, "max_websocket_message", ComputerCraft.httpMaxWebsocketMessage );
|
||||
httpMaxWebsocketMessage.setComment( "The maximum size (in bytes) that a computer can send or receive in one websocket packet." );
|
||||
httpMaxWebsocketMessage.setMinValue( 0 );
|
||||
httpMaxWebsocketMessage.setMaxValue( Websocket.MAX_MESSAGE_SIZE );
|
||||
|
||||
setOrder(
|
||||
CATEGORY_HTTP,
|
||||
httpEnable, httpWebsocketEnable, httpWhitelist, httpBlacklist,
|
||||
httpTimeout, httpMaxRequests, httpMaxDownload, httpMaxUpload, httpMaxWebsockets, httpMaxWebsocketMessage
|
||||
);
|
||||
builder.pop();
|
||||
}
|
||||
|
||||
{ // Peripherals
|
||||
renameProperty( CATEGORY_GENERAL, "enableCommandBlock", CATEGORY_PERIPHERAL, "command_block_enabled" );
|
||||
renameProperty( CATEGORY_GENERAL, "modem_range", CATEGORY_PERIPHERAL, "modem_range" );
|
||||
renameProperty( CATEGORY_GENERAL, "modem_highAltitudeRange", CATEGORY_PERIPHERAL, "modem_high_altitude_range" );
|
||||
renameProperty( CATEGORY_GENERAL, "modem_rangeDuringStorm", CATEGORY_PERIPHERAL, "modem_range_during_storm" );
|
||||
renameProperty( CATEGORY_GENERAL, "modem_highAltitudeRangeDuringStorm", CATEGORY_PERIPHERAL, "modem_high_altitude_range_during_storm" );
|
||||
renameProperty( CATEGORY_GENERAL, "maxNotesPerTick", CATEGORY_PERIPHERAL, "max_notes_per_tick" );
|
||||
builder.comment( "Various options relating to peripherals." );
|
||||
builder.push( "peripheral" );
|
||||
|
||||
config.getCategory( CATEGORY_PERIPHERAL )
|
||||
.setComment( "Various options relating to peripherals." );
|
||||
commandBlockEnabled = builder
|
||||
.comment( "Enable Command Block peripheral support" )
|
||||
.define( "command_block_enabled", ComputerCraft.enableCommandBlock );
|
||||
|
||||
commandBlockEnabled = config.get( CATEGORY_PERIPHERAL, "command_block_enabled", ComputerCraft.enableCommandBlock );
|
||||
commandBlockEnabled.setComment( "Enable Command Block peripheral support" );
|
||||
modemRange = builder
|
||||
.comment( "The range of Wireless Modems at low altitude in clear weather, in meters" )
|
||||
.defineInRange( "modem_range", ComputerCraft.modem_range, 0, MODEM_MAX_RANGE );
|
||||
|
||||
modemRange = config.get( CATEGORY_PERIPHERAL, "modem_range", ComputerCraft.modem_range );
|
||||
modemRange.setComment( "The range of Wireless Modems at low altitude in clear weather, in meters" );
|
||||
modemRange.setMinValue( 0 );
|
||||
modemRange.setMaxValue( MODEM_MAX_RANGE );
|
||||
modemHighAltitudeRange = builder
|
||||
.comment( "The range of Wireless Modems at maximum altitude in clear weather, in meters" )
|
||||
.defineInRange( "modem_high_altitude_range", ComputerCraft.modem_highAltitudeRange, 0, MODEM_MAX_RANGE );
|
||||
|
||||
modemHighAltitudeRange = config.get( CATEGORY_PERIPHERAL, "modem_high_altitude_range", ComputerCraft.modem_highAltitudeRange );
|
||||
modemHighAltitudeRange.setComment( "The range of Wireless Modems at maximum altitude in clear weather, in meters" );
|
||||
modemHighAltitudeRange.setMinValue( 0 );
|
||||
modemHighAltitudeRange.setMaxValue( MODEM_MAX_RANGE );
|
||||
modemRangeDuringStorm = builder
|
||||
.comment( "The range of Wireless Modems at low altitude in stormy weather, in meters" )
|
||||
.defineInRange( "modem_range_during_storm", ComputerCraft.modem_rangeDuringStorm, 0, MODEM_MAX_RANGE );
|
||||
|
||||
modemRangeDuringStorm = config.get( CATEGORY_PERIPHERAL, "modem_range_during_storm", ComputerCraft.modem_rangeDuringStorm );
|
||||
modemRangeDuringStorm.setComment( "The range of Wireless Modems at low altitude in stormy weather, in meters" );
|
||||
modemRangeDuringStorm.setMinValue( 0 );
|
||||
modemRangeDuringStorm.setMaxValue( MODEM_MAX_RANGE );
|
||||
modemHighAltitudeRangeDuringStorm = builder
|
||||
.comment( "The range of Wireless Modems at maximum altitude in stormy weather, in meters" )
|
||||
.defineInRange( "modem_high_altitude_range_during_storm", ComputerCraft.modem_highAltitudeRangeDuringStorm, 0, MODEM_MAX_RANGE );
|
||||
|
||||
modemHighAltitudeRangeDuringStorm = config.get( CATEGORY_PERIPHERAL, "modem_high_altitude_range_during_storm", ComputerCraft.modem_highAltitudeRangeDuringStorm );
|
||||
modemHighAltitudeRangeDuringStorm.setComment( "The range of Wireless Modems at maximum altitude in stormy weather, in meters" );
|
||||
modemHighAltitudeRangeDuringStorm.setMinValue( 0 );
|
||||
modemHighAltitudeRangeDuringStorm.setMaxValue( MODEM_MAX_RANGE );
|
||||
maxNotesPerTick = builder
|
||||
.comment( "Maximum amount of notes a speaker can play at once" )
|
||||
.defineInRange( "max_notes_per_tick", ComputerCraft.maxNotesPerTick, 1, Integer.MAX_VALUE );
|
||||
|
||||
maxNotesPerTick = config.get( CATEGORY_PERIPHERAL, "max_notes_per_tick", ComputerCraft.maxNotesPerTick );
|
||||
maxNotesPerTick.setComment( "Maximum amount of notes a speaker can play at once" );
|
||||
maxNotesPerTick.setMinValue( 1 );
|
||||
|
||||
setOrder(
|
||||
CATEGORY_PERIPHERAL,
|
||||
commandBlockEnabled, modemRange, modemHighAltitudeRange, modemRangeDuringStorm, modemHighAltitudeRangeDuringStorm, maxNotesPerTick
|
||||
);
|
||||
builder.pop();
|
||||
}
|
||||
|
||||
{ // Turtles
|
||||
renameProperty( CATEGORY_GENERAL, "turtlesNeedFuel", CATEGORY_TURTLE, "need_fuel" );
|
||||
renameProperty( CATEGORY_GENERAL, "turtleFuelLimit", CATEGORY_TURTLE, "normal_fuel_limit" );
|
||||
renameProperty( CATEGORY_GENERAL, "advancedTurtleFuelLimit", CATEGORY_TURTLE, "advanced_fuel_limit" );
|
||||
renameProperty( CATEGORY_GENERAL, "turtlesObeyBlockProtection", CATEGORY_TURTLE, "obey_block_protection" );
|
||||
renameProperty( CATEGORY_GENERAL, "turtlesCanPush", CATEGORY_TURTLE, "can_push" );
|
||||
renameProperty( CATEGORY_GENERAL, "turtle_disabled_actions", CATEGORY_TURTLE, "disabled_actions" );
|
||||
builder.comment( "Various options relating to turtles." );
|
||||
builder.push( "turtle" );
|
||||
|
||||
config.getCategory( CATEGORY_HTTP )
|
||||
.setComment( "Various options relating to turtles." );
|
||||
turtlesNeedFuel = builder
|
||||
.comment( "Set whether Turtles require fuel to move" )
|
||||
.define( "need_fuel", ComputerCraft.turtlesNeedFuel );
|
||||
|
||||
turtlesNeedFuel = config.get( CATEGORY_TURTLE, "need_fuel", ComputerCraft.turtlesNeedFuel );
|
||||
turtlesNeedFuel.setComment( "Set whether Turtles require fuel to move" );
|
||||
turtleFuelLimit = builder
|
||||
.comment( "The fuel limit for Turtles" )
|
||||
.defineInRange( "normal_fuel_limit", ComputerCraft.turtleFuelLimit, 0, Integer.MAX_VALUE );
|
||||
|
||||
turtleFuelLimit = config.get( CATEGORY_TURTLE, "normal_fuel_limit", ComputerCraft.turtleFuelLimit );
|
||||
turtleFuelLimit.setComment( "The fuel limit for Turtles" );
|
||||
turtleFuelLimit.setMinValue( 0 );
|
||||
advancedTurtleFuelLimit = builder
|
||||
.comment( "The fuel limit for Advanced Turtles" )
|
||||
.defineInRange( "advanced_fuel_limit", ComputerCraft.advancedTurtleFuelLimit, 0, Integer.MAX_VALUE );
|
||||
|
||||
advancedTurtleFuelLimit = config.get( CATEGORY_TURTLE, "advanced_fuel_limit", ComputerCraft.advancedTurtleFuelLimit );
|
||||
advancedTurtleFuelLimit.setComment( "The fuel limit for Advanced Turtles" );
|
||||
advancedTurtleFuelLimit.setMinValue( 0 );
|
||||
turtlesObeyBlockProtection = builder
|
||||
.comment( "If set to true, Turtles will be unable to build, dig, or enter protected areas (such as near the server spawn point)" )
|
||||
.define( "obey_block_protection", ComputerCraft.turtlesObeyBlockProtection );
|
||||
|
||||
turtlesObeyBlockProtection = config.get( CATEGORY_TURTLE, "obey_block_protection", ComputerCraft.turtlesObeyBlockProtection );
|
||||
turtlesObeyBlockProtection.setComment( "If set to true, Turtles will be unable to build, dig, or enter protected " +
|
||||
"areas (such as near the server spawn point)" );
|
||||
turtlesCanPush = builder
|
||||
.comment( "If set to true, Turtles will push entities out of the way instead of stopping if there is space to do so" )
|
||||
.define( "can_push", ComputerCraft.turtlesCanPush );
|
||||
|
||||
turtlesCanPush = config.get( CATEGORY_TURTLE, "can_push", ComputerCraft.turtlesCanPush );
|
||||
turtlesCanPush.setComment( "If set to true, Turtles will push entities out of the way instead of stopping if " +
|
||||
"there is space to do so" );
|
||||
turtleDisabledActions = builder
|
||||
.comment( "A list of turtle actions which are disabled." )
|
||||
.defineList( "disabled_actions", Collections.emptyList(), x -> x instanceof String && getAction( (String) x ) != null );
|
||||
|
||||
turtleDisabledActions = config.get( CATEGORY_TURTLE, "disabled_actions", new String[0] );
|
||||
turtleDisabledActions.setComment( "A list of turtle actions which are disabled." );
|
||||
|
||||
setOrder(
|
||||
CATEGORY_TURTLE,
|
||||
turtlesNeedFuel, turtleFuelLimit, advancedTurtleFuelLimit, turtlesObeyBlockProtection, turtlesCanPush, turtleDisabledActions
|
||||
);
|
||||
builder.pop();
|
||||
}
|
||||
|
||||
for( String child : config.getCategoryNames() )
|
||||
{
|
||||
setupLanguage(
|
||||
config.getCategory( child ),
|
||||
child.equals( CATEGORY_GENERAL ) ? "gui.computercraft:config" : "gui.computercraft:config." + child
|
||||
);
|
||||
}
|
||||
|
||||
sync();
|
||||
spec = builder.build();
|
||||
}
|
||||
|
||||
private static void setOrder( String category, Property... properties )
|
||||
public static void load()
|
||||
{
|
||||
List<String> names = new ArrayList<>( properties.length );
|
||||
for( Property property : properties ) names.add( property.getName() );
|
||||
config.getCategory( category ).setPropertyOrder( names );
|
||||
}
|
||||
|
||||
private static void renameProperty( String oldCat, String oldProp, String newCat, String newProp )
|
||||
{
|
||||
if( !config.hasCategory( oldCat ) ) return;
|
||||
|
||||
ConfigCategory cat = config.getCategory( oldCat );
|
||||
if( !cat.containsKey( oldProp ) ) return;
|
||||
|
||||
Property prop = cat.remove( oldProp );
|
||||
prop.setName( newProp );
|
||||
config.getCategory( newCat ).put( newProp, prop );
|
||||
|
||||
// Clean up old categories
|
||||
if( cat.isEmpty() ) config.removeCategory( cat );
|
||||
}
|
||||
|
||||
private static void setupLanguage( ConfigCategory category, String key )
|
||||
{
|
||||
category.setLanguageKey( key );
|
||||
for( Property property : category.getOrderedValues() )
|
||||
{
|
||||
property.setLanguageKey( key + "." + property.getName() );
|
||||
}
|
||||
|
||||
for( ConfigCategory child : category.getChildren() )
|
||||
{
|
||||
setupLanguage( child, key + "." + child.getName() );
|
||||
}
|
||||
}
|
||||
|
||||
public static void reload()
|
||||
{
|
||||
Configuration newConfig = new Configuration( config.getConfigFile(), ComputerCraft.getVersion() );
|
||||
Set<String> oldCategories = config.getCategoryNames(), newCategories = newConfig.getCategoryNames();
|
||||
|
||||
// Sync any categories on the original config
|
||||
for( String category : oldCategories )
|
||||
{
|
||||
if( newCategories.contains( category ) )
|
||||
{
|
||||
reloadCategory( config.getCategory( category ), newConfig.getCategory( category ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( Property property : config.getCategory( category ).getValues().values() ) property.setToDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// And drop any unexpected ones.
|
||||
for( String category : newCategories )
|
||||
{
|
||||
if( !oldCategories.contains( category ) )
|
||||
{
|
||||
ComputerCraft.log.warn( "Cannot sync unknown config category {}", category );
|
||||
}
|
||||
}
|
||||
|
||||
sync();
|
||||
}
|
||||
|
||||
private static void reloadCategory( ConfigCategory oldCat, ConfigCategory newCat )
|
||||
{
|
||||
// Copy the config values across to the original config.
|
||||
for( Map.Entry<String, Property> child : newCat.getValues().entrySet() )
|
||||
{
|
||||
Property oldProperty = oldCat.get( child.getKey() ), newProperty = child.getValue();
|
||||
if( oldProperty.getType() != newProperty.getType() || oldProperty.isList() != newProperty.isList() )
|
||||
{
|
||||
ComputerCraft.log.warn(
|
||||
"Cannot sync config property {} (type changed from {} to {})",
|
||||
child.getKey(), getType( oldProperty ), getType( newProperty )
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if( oldProperty.isList() )
|
||||
{
|
||||
oldProperty.setValues( oldProperty.getStringList() );
|
||||
}
|
||||
else
|
||||
{
|
||||
oldProperty.setValue( newProperty.getString() );
|
||||
}
|
||||
}
|
||||
|
||||
// Reset any missing properties.
|
||||
for( Map.Entry<String, Property> child : oldCat.getValues().entrySet() )
|
||||
{
|
||||
if( !newCat.containsKey( child.getKey() ) ) child.getValue().setToDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private static String getType( Property property )
|
||||
{
|
||||
return property.getType() + (property.isList() ? " list" : "");
|
||||
ModLoadingContext.get().registerConfig( ModConfig.Type.COMMON, spec );
|
||||
}
|
||||
|
||||
public static void sync()
|
||||
{
|
||||
// General
|
||||
ComputerCraft.computerSpaceLimit = computerSpaceLimit.getInt();
|
||||
ComputerCraft.floppySpaceLimit = floppySpaceLimit.getInt();
|
||||
ComputerCraft.maximumFilesOpen = Math.max( 0, maximumFilesOpen.getInt() );
|
||||
ComputerCraft.disable_lua51_features = disableLua51Features.getBoolean();
|
||||
ComputerCraft.default_computer_settings = defaultComputerSettings.getString();
|
||||
ComputerCraft.debug_enable = debugEnabled.getBoolean();
|
||||
ComputerCraft.logPeripheralErrors = logComputerErrors.getBoolean();
|
||||
ComputerCraft.computerSpaceLimit = computerSpaceLimit.get();
|
||||
ComputerCraft.floppySpaceLimit = floppySpaceLimit.get();
|
||||
ComputerCraft.maximumFilesOpen = maximumFilesOpen.get();
|
||||
ComputerCraft.disable_lua51_features = disableLua51Features.get();
|
||||
ComputerCraft.default_computer_settings = defaultComputerSettings.get();
|
||||
ComputerCraft.debug_enable = debugEnabled.get();
|
||||
ComputerCraft.computer_threads = computerThreads.get();
|
||||
ComputerCraft.logPeripheralErrors = logComputerErrors.get();
|
||||
|
||||
// Execution
|
||||
ComputerCraft.computer_threads = computerThreads.getInt();
|
||||
ComputerCraft.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos( Math.max( 1, maxMainGlobalTime.getLong() ) );
|
||||
ComputerCraft.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos( Math.max( 1, maxMainComputerTime.getLong() ) );
|
||||
ComputerCraft.computer_threads = computerThreads.get();
|
||||
ComputerCraft.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos( maxMainGlobalTime.get() );
|
||||
ComputerCraft.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos( maxMainComputerTime.get() );
|
||||
|
||||
// HTTP
|
||||
ComputerCraft.http_enable = httpEnable.getBoolean();
|
||||
ComputerCraft.http_websocket_enable = httpWebsocketEnable.getBoolean();
|
||||
ComputerCraft.http_whitelist = new AddressPredicate( httpWhitelist.getStringList() );
|
||||
ComputerCraft.http_blacklist = new AddressPredicate( httpBlacklist.getStringList() );
|
||||
ComputerCraft.http_enable = httpEnabled.get();
|
||||
ComputerCraft.http_websocket_enable = httpWebsocketEnabled.get();
|
||||
ComputerCraft.http_whitelist = new AddressPredicate( httpWhitelist.get() );
|
||||
ComputerCraft.http_blacklist = new AddressPredicate( httpBlacklist.get() );
|
||||
|
||||
ComputerCraft.httpTimeout = Math.max( 0, httpTimeout.getInt() );
|
||||
ComputerCraft.httpMaxRequests = Math.max( 1, httpMaxRequests.getInt() );
|
||||
ComputerCraft.httpMaxDownload = Math.max( 0, httpMaxDownload.getLong() );
|
||||
ComputerCraft.httpMaxUpload = Math.max( 0, httpMaxUpload.getLong() );
|
||||
ComputerCraft.httpMaxWebsockets = Math.max( 1, httpMaxWebsockets.getInt() );
|
||||
ComputerCraft.httpMaxWebsocketMessage = Math.max( 0, httpMaxWebsocketMessage.getInt() );
|
||||
ComputerCraft.httpTimeout = httpTimeout.get();
|
||||
ComputerCraft.httpMaxRequests = httpMaxRequests.get();
|
||||
ComputerCraft.httpMaxDownload = httpMaxDownload.get();
|
||||
ComputerCraft.httpMaxUpload = httpMaxUpload.get();
|
||||
ComputerCraft.httpMaxWebsockets = httpMaxWebsockets.get();
|
||||
ComputerCraft.httpMaxWebsocketMessage = httpMaxWebsocketMessage.get();
|
||||
|
||||
// Peripheral
|
||||
ComputerCraft.enableCommandBlock = commandBlockEnabled.getBoolean();
|
||||
ComputerCraft.maxNotesPerTick = Math.max( 1, maxNotesPerTick.getInt() );
|
||||
ComputerCraft.modem_range = Math.min( modemRange.getInt(), MODEM_MAX_RANGE );
|
||||
ComputerCraft.modem_highAltitudeRange = Math.min( modemHighAltitudeRange.getInt(), MODEM_MAX_RANGE );
|
||||
ComputerCraft.modem_rangeDuringStorm = Math.min( modemRangeDuringStorm.getInt(), MODEM_MAX_RANGE );
|
||||
ComputerCraft.modem_highAltitudeRangeDuringStorm = Math.min( modemHighAltitudeRangeDuringStorm.getInt(), MODEM_MAX_RANGE );
|
||||
ComputerCraft.enableCommandBlock = commandBlockEnabled.get();
|
||||
ComputerCraft.maxNotesPerTick = maxNotesPerTick.get();
|
||||
ComputerCraft.modem_range = modemRange.get();
|
||||
ComputerCraft.modem_highAltitudeRange = modemHighAltitudeRange.get();
|
||||
ComputerCraft.modem_rangeDuringStorm = modemRangeDuringStorm.get();
|
||||
ComputerCraft.modem_highAltitudeRangeDuringStorm = modemHighAltitudeRangeDuringStorm.get();
|
||||
|
||||
// Turtles
|
||||
ComputerCraft.turtlesNeedFuel = turtlesNeedFuel.getBoolean();
|
||||
ComputerCraft.turtleFuelLimit = turtleFuelLimit.getInt();
|
||||
ComputerCraft.advancedTurtleFuelLimit = advancedTurtleFuelLimit.getInt();
|
||||
ComputerCraft.turtlesObeyBlockProtection = turtlesObeyBlockProtection.getBoolean();
|
||||
ComputerCraft.turtlesCanPush = turtlesCanPush.getBoolean();
|
||||
ComputerCraft.turtlesNeedFuel = turtlesNeedFuel.get();
|
||||
ComputerCraft.turtleFuelLimit = turtleFuelLimit.get();
|
||||
ComputerCraft.advancedTurtleFuelLimit = advancedTurtleFuelLimit.get();
|
||||
ComputerCraft.turtlesObeyBlockProtection = turtlesObeyBlockProtection.get();
|
||||
ComputerCraft.turtlesCanPush = turtlesCanPush.get();
|
||||
|
||||
ComputerCraft.turtleDisabledActions.clear();
|
||||
Converter<String, String> converter = CaseFormat.LOWER_CAMEL.converterTo( CaseFormat.UPPER_UNDERSCORE );
|
||||
for( String value : turtleDisabledActions.getStringList() )
|
||||
{
|
||||
try
|
||||
{
|
||||
ComputerCraft.turtleDisabledActions.add( TurtleAction.valueOf( converter.convert( value ) ) );
|
||||
}
|
||||
catch( IllegalArgumentException e )
|
||||
{
|
||||
ComputerCraft.log.error( "Unknown turtle action " + value );
|
||||
}
|
||||
}
|
||||
|
||||
config.save();
|
||||
for( String value : turtleDisabledActions.get() ) ComputerCraft.turtleDisabledActions.add( getAction( value ) );
|
||||
}
|
||||
|
||||
public static List<IConfigElement> getConfigElements()
|
||||
@SubscribeEvent
|
||||
public static void sync( ModConfig.Loading event )
|
||||
{
|
||||
ArrayList<IConfigElement> elements = new ArrayList<>();
|
||||
|
||||
// Add all child categories
|
||||
for( String categoryName : config.getCategoryNames() )
|
||||
{
|
||||
if( categoryName.equals( CATEGORY_GENERAL ) ) continue;
|
||||
ConfigCategory category = config.getCategory( categoryName );
|
||||
elements.add( new ConfigElement( category ) );
|
||||
}
|
||||
|
||||
// Add the general category
|
||||
for( Property property : config.getCategory( CATEGORY_GENERAL ).getOrderedValues() )
|
||||
{
|
||||
elements.add( new ConfigElement( property ) );
|
||||
}
|
||||
|
||||
return elements;
|
||||
sync();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void sync( ModConfig.ConfigReloading event )
|
||||
{
|
||||
sync();
|
||||
}
|
||||
|
||||
private static final Converter<String, String> converter = CaseFormat.LOWER_CAMEL.converterTo( CaseFormat.UPPER_UNDERSCORE );
|
||||
|
||||
private static TurtleAction getAction( String value )
|
||||
{
|
||||
try
|
||||
{
|
||||
return TurtleAction.valueOf( converter.convert( value ) );
|
||||
}
|
||||
catch( IllegalArgumentException e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user