mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 05:33:00 +00:00 
			
		
		
		
	Fix: Mimic CC:T config file structure
Replaces the jankson implementation with night-config. Night config is what the forge api uses so it's easy to produce .toml files in the same structure as CC:Tweaked. All config options and comments from CC:Tweaked are implemented. Some of these options are ignored in various bits of implementation but that is another problem :) Also splits the config into a client and server file. The server file is saved per-world. Names and locations are consistent with CC:T.
This commit is contained in:
		
							
								
								
									
										37
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								build.gradle
									
									
									
									
									
								
							| @@ -13,7 +13,8 @@ archivesBaseName = "cc-restiched" | |||||||
|  |  | ||||||
| repositories { | repositories { | ||||||
|     mavenCentral() |     mavenCentral() | ||||||
|     jcenter() |     maven { url 'https://jitpack.io' } | ||||||
|  |     maven { url "https://maven.shedaniel.me/" } | ||||||
|     maven { |     maven { | ||||||
|         name "SquidDev" |         name "SquidDev" | ||||||
|         url "https://squiddev.cc/maven" |         url "https://squiddev.cc/maven" | ||||||
| @@ -30,40 +31,26 @@ dependencies { | |||||||
|     modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}" |     modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}" | ||||||
|     modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_api_version}" |     modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_api_version}" | ||||||
|  |  | ||||||
|     compile 'com.electronwill.night-config:json:3.6.0' |     modApi("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}") { | ||||||
|  |         exclude(group: "net.fabricmc.fabric-api") | ||||||
|     modImplementation "me.shedaniel.cloth:config-2:${cloth_config_version}" |     } | ||||||
|     modImplementation "io.github.prospector:modmenu:${modmenu_version}" |     modImplementation "io.github.prospector:modmenu:${modmenu_version}" | ||||||
|  |     modImplementation "me.shedaniel.cloth.api:cloth-utils-v1:${cloth_api_version}" | ||||||
|  |  | ||||||
|     modApi "me.shedaniel.cloth.api:cloth-utils-v1:${project.cloth_api_version}" |     compile 'com.electronwill.night-config:toml:3.6.3' | ||||||
|     include "me.shedaniel.cloth.api:cloth-utils-v1:${project.cloth_api_version}" |  | ||||||
|  |  | ||||||
|     implementation "blue.endless:jankson:${jankson_version}" |  | ||||||
|     implementation 'com.google.code.findbugs:jsr305:3.0.2' |     implementation 'com.google.code.findbugs:jsr305:3.0.2' | ||||||
|  |  | ||||||
|     compileOnly 'com.google.auto.service:auto-service:1.0-rc7' |  | ||||||
|     annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7' |  | ||||||
|  |  | ||||||
|     include "me.shedaniel.cloth:config-2:${cloth_config_version}" |  | ||||||
|     include "blue.endless:jankson:${jankson_version}" |  | ||||||
|     include 'javax.vecmath:vecmath:1.5.2' |  | ||||||
|  |  | ||||||
|     compile 'javax.vecmath:vecmath:1.5.2' |  | ||||||
|  |  | ||||||
|     shade 'org.squiddev:Cobalt:0.5.2-SNAPSHOT' |     shade 'org.squiddev:Cobalt:0.5.2-SNAPSHOT' | ||||||
|  |  | ||||||
|  |     include "me.shedaniel.cloth.api:cloth-utils-v1:${cloth_api_version}" | ||||||
|  |     include 'com.electronwill.night-config:core:3.6.3' | ||||||
|  |     include 'com.electronwill.night-config:toml:3.6.3' | ||||||
|  |     include "me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}" | ||||||
|  |  | ||||||
|     modRuntime "me.shedaniel:RoughlyEnoughItems-api:5.8.9" |     modRuntime "me.shedaniel:RoughlyEnoughItems-api:5.8.9" | ||||||
|     modRuntime "me.shedaniel:RoughlyEnoughItems:5.8.9" |     modRuntime "me.shedaniel:RoughlyEnoughItems:5.8.9" | ||||||
| } | } | ||||||
|  |  | ||||||
| sourceSets { |  | ||||||
|     main { |  | ||||||
|         java { |  | ||||||
|             exclude 'dan200/computercraft/shared/integration' |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| processResources { | processResources { | ||||||
|     inputs.property "version", project.version |     inputs.property "version", project.version | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,9 +9,9 @@ mc_version=1.16.5 | |||||||
| mappings_version=9 | mappings_version=9 | ||||||
|  |  | ||||||
| # Dependencies | # Dependencies | ||||||
| cloth_config_version=4.8.1 | cloth_config_version=4.11.26 | ||||||
| fabric_loader_version=0.11.3 | fabric_loader_version=0.11.3 | ||||||
| fabric_api_version=0.32.0+1.16 | fabric_api_version=0.32.0+1.16 | ||||||
| jankson_version=1.2.0 | jankson_version=1.2.0 | ||||||
| modmenu_version=1.14.6+ | modmenu_version=1.16.9 | ||||||
| cloth_api_version=1.4.5 | cloth_api_version=1.4.5 | ||||||
|   | |||||||
| @@ -9,18 +9,15 @@ package dan200.computercraft; | |||||||
| import static dan200.computercraft.shared.ComputerCraftRegistry.ModBlocks; | import static dan200.computercraft.shared.ComputerCraftRegistry.ModBlocks; | ||||||
| import static dan200.computercraft.shared.ComputerCraftRegistry.init; | import static dan200.computercraft.shared.ComputerCraftRegistry.init; | ||||||
|  |  | ||||||
| import java.nio.file.Paths; |  | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.EnumSet; | import java.util.EnumSet; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
|  |  | ||||||
|  |  | ||||||
| import dan200.computercraft.api.turtle.event.TurtleAction; | import dan200.computercraft.api.turtle.event.TurtleAction; | ||||||
| import dan200.computercraft.core.apis.http.options.Action; | import dan200.computercraft.core.apis.http.options.Action; | ||||||
| import dan200.computercraft.core.apis.http.options.AddressRule; | import dan200.computercraft.core.apis.http.options.AddressRule; | ||||||
| import dan200.computercraft.core.apis.http.websocket.Websocket; |  | ||||||
| import dan200.computercraft.shared.common.ColourableRecipe; | import dan200.computercraft.shared.common.ColourableRecipe; | ||||||
| import dan200.computercraft.shared.computer.core.ClientComputerRegistry; | import dan200.computercraft.shared.computer.core.ClientComputerRegistry; | ||||||
| import dan200.computercraft.shared.computer.core.ServerComputerRegistry; | import dan200.computercraft.shared.computer.core.ServerComputerRegistry; | ||||||
| @@ -35,9 +32,7 @@ import dan200.computercraft.shared.pocket.recipes.PocketComputerUpgradeRecipe; | |||||||
| import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon; | import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon; | ||||||
| import dan200.computercraft.shared.turtle.recipes.TurtleRecipe; | import dan200.computercraft.shared.turtle.recipes.TurtleRecipe; | ||||||
| import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe; | import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe; | ||||||
| import dan200.computercraft.shared.util.Config; | import dan200.computercraft.shared.util.*; | ||||||
| import dan200.computercraft.shared.util.ImpostorRecipe; |  | ||||||
| import dan200.computercraft.shared.util.ImpostorShapelessRecipe; |  | ||||||
| import org.apache.logging.log4j.LogManager; | import org.apache.logging.log4j.LogManager; | ||||||
| import org.apache.logging.log4j.Logger; | import org.apache.logging.log4j.Logger; | ||||||
|  |  | ||||||
| @@ -54,72 +49,76 @@ import net.fabricmc.loader.api.FabricLoader; | |||||||
|  |  | ||||||
| public final class ComputerCraft implements ModInitializer { | public final class ComputerCraft implements ModInitializer { | ||||||
|     public static final String MOD_ID = "computercraft"; |     public static final String MOD_ID = "computercraft"; | ||||||
|     // Configuration options |  | ||||||
|     public static final int terminalWidth_computer = 51; |     // Configuration fields | ||||||
|     public static final int terminalHeight_computer = 19; |  | ||||||
|     public static final int terminalWidth_turtle = 39; |  | ||||||
|     public static final int terminalHeight_turtle = 13; |  | ||||||
|     public static final int terminalWidth_pocketComputer = 26; |  | ||||||
|     public static final int terminalHeight_pocketComputer = 20; |  | ||||||
|     // Registries |  | ||||||
|     public static final ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry(); |  | ||||||
|     public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry(); |  | ||||||
|     // Logging |  | ||||||
|     public static final Logger log = LogManager.getLogger(MOD_ID); |  | ||||||
|     public static ItemGroup MAIN_GROUP = FabricItemGroupBuilder.build(new Identifier(MOD_ID, "main"), () -> new ItemStack(ModBlocks.COMPUTER_NORMAL)); |  | ||||||
|     public static boolean commandRequireCreative = false; |  | ||||||
|     public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST; |  | ||||||
|     public static int computerSpaceLimit = 1000 * 1000; |     public static int computerSpaceLimit = 1000 * 1000; | ||||||
|     public static int floppySpaceLimit = 125 * 1000; |     public static int floppySpaceLimit = 125 * 1000; | ||||||
|     public static int maximumFilesOpen = 128; |     public static int maximumFilesOpen = 128; | ||||||
|     public static boolean disable_lua51_features = false; |     public static boolean disableLua51Features = false; | ||||||
|     public static String default_computer_settings = ""; |     public static String defaultComputerSettings = ""; | ||||||
|     public static boolean debug_enable = true; |     public static boolean debugEnable = true; | ||||||
|     public static boolean logPeripheralErrors = false; |     public static boolean logComputerErrors = true; | ||||||
|     public static int computer_threads = 1; |     public static boolean commandRequireCreative = true; | ||||||
|  |  | ||||||
|  |     public static int computerThreads = 1; | ||||||
|     public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(10); |     public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(10); | ||||||
|     public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(5); |     public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(5); | ||||||
|     public static boolean http_enable = true; |  | ||||||
|     public static boolean http_websocket_enable = true; |     public static boolean httpEnabled = true; | ||||||
|     public static int httpTimeout = 30000; |     public static boolean httpWebsocketEnabled = true; | ||||||
|  |     public static List<AddressRule> httpRules = Collections.unmodifiableList( Arrays.asList( | ||||||
|  |             AddressRule.parse( "$private", null, Action.DENY.toPartial() ), | ||||||
|  |             AddressRule.parse( "*", null, Action.ALLOW.toPartial() ) | ||||||
|  |     )); | ||||||
|  |  | ||||||
|     public static int httpMaxRequests = 16; |     public static int httpMaxRequests = 16; | ||||||
|     public static long httpMaxDownload = 16 * 1024 * 1024; |  | ||||||
|     public static long httpMaxUpload = 4 * 1024 * 1024; |  | ||||||
|     public static int httpMaxWebsockets = 4; |     public static int httpMaxWebsockets = 4; | ||||||
|     public static int httpMaxWebsocketMessage = Websocket.MAX_MESSAGE_SIZE; |  | ||||||
|     public static boolean enableCommandBlock = false; |     public static boolean enableCommandBlock = false; | ||||||
|     public static int modem_range = 64; |     public static int modemRange = 64; | ||||||
|     public static int modem_highAltitudeRange = 384; |     public static int modemHighAltitudeRange = 384; | ||||||
|     public static int modem_rangeDuringStorm = 64; |     public static int modemRangeDuringStorm = 64; | ||||||
|     public static int modem_highAltitudeRangeDuringStorm = 384; |     public static int modemHighAltitudeRangeDuringStorm = 384; | ||||||
|     public static int maxNotesPerTick = 8; |     public static int maxNotesPerTick = 8; | ||||||
|  |     public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST; | ||||||
|  |     public static double monitorDistanceSq = 4096; | ||||||
|  |     public static long monitorBandwidth = 1_000_000; | ||||||
|  |  | ||||||
|     public static boolean turtlesNeedFuel = true; |     public static boolean turtlesNeedFuel = true; | ||||||
|     public static int turtleFuelLimit = 20000; |     public static int turtleFuelLimit = 20000; | ||||||
|     public static int advancedTurtleFuelLimit = 100000; |     public static int advancedTurtleFuelLimit = 100000; | ||||||
|     public static boolean turtlesObeyBlockProtection = true; |     public static boolean turtlesObeyBlockProtection = true; | ||||||
|     public static boolean turtlesCanPush = true; |     public static boolean turtlesCanPush = true; | ||||||
|     public static EnumSet<TurtleAction> turtleDisabledActions = EnumSet.noneOf(TurtleAction.class); |     public static EnumSet<TurtleAction> turtleDisabledActions = EnumSet.noneOf(TurtleAction.class); | ||||||
|  |  | ||||||
|  |     public static int computerTermWidth = 51; | ||||||
|  |     public static int computerTermHeight = 19; | ||||||
|  |  | ||||||
|  |     public static final int turtleTermWidth = 39; | ||||||
|  |     public static final int turtleTermHeight = 13; | ||||||
|  |  | ||||||
|  |     public static int pocketTermWidth = 26; | ||||||
|  |     public static int pocketTermHeight = 20; | ||||||
|  |  | ||||||
|     public static int monitorWidth = 8; |     public static int monitorWidth = 8; | ||||||
|     public static int monitorHeight = 6; |     public static int monitorHeight = 6; | ||||||
|     public static double monitorDistanceSq = 4096; |  | ||||||
|  |  | ||||||
|     public static List<AddressRule> httpRules = Collections.unmodifiableList( Arrays.asList( |     // Registries | ||||||
|         AddressRule.parse( "$private", null, Action.DENY.toPartial() ), |     public static final ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry(); | ||||||
|         AddressRule.parse( "*", null, Action.ALLOW.toPartial() ) |     public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry(); | ||||||
|     ) ); |  | ||||||
|  |     // Logging | ||||||
|  |     public static final Logger log = LogManager.getLogger(MOD_ID); | ||||||
|  |  | ||||||
|  |     public static ItemGroup MAIN_GROUP = FabricItemGroupBuilder.build(new Identifier(MOD_ID, "main"), () -> new ItemStack(ModBlocks.COMPUTER_NORMAL)); | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void onInitialize() { |     public void onInitialize() { | ||||||
|         Config.load(Paths.get(FabricLoader.getInstance() |  | ||||||
|                                           .getConfigDir() |  | ||||||
|                                           .toFile() |  | ||||||
|                                           .getPath(), MOD_ID + ".json5")); |  | ||||||
|         ComputerCraftProxyCommon.init(); |         ComputerCraftProxyCommon.init(); | ||||||
|  |  | ||||||
|         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "colour"), ColourableRecipe.SERIALIZER); |         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "colour"), ColourableRecipe.SERIALIZER); | ||||||
|         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "computer_upgrade"), ComputerUpgradeRecipe.SERIALIZER); |         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "computer_upgrade"), ComputerUpgradeRecipe.SERIALIZER); | ||||||
|         Registry.register(Registry.RECIPE_SERIALIZER, |         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "pocket_computer_upgrade"), PocketComputerUpgradeRecipe.SERIALIZER); | ||||||
|                           new Identifier(ComputerCraft.MOD_ID, "pocket_computer_upgrade"), |  | ||||||
|                           PocketComputerUpgradeRecipe.SERIALIZER); |  | ||||||
|         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "disk"), DiskRecipe.SERIALIZER); |         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "disk"), DiskRecipe.SERIALIZER); | ||||||
|         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "printout"), PrintoutRecipe.SERIALIZER); |         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "printout"), PrintoutRecipe.SERIALIZER); | ||||||
|         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "turtle"), TurtleRecipe.SERIALIZER); |         Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "turtle"), TurtleRecipe.SERIALIZER); | ||||||
| @@ -135,5 +134,4 @@ public final class ComputerCraft implements ModInitializer { | |||||||
|             ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MOD_ID, "overhaul"), modContainer, ResourcePackActivationType.NORMAL); |             ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MOD_ID, "overhaul"), modContainer, ResourcePackActivationType.NORMAL); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -48,11 +48,11 @@ public final class GuiComputer<T extends ContainerComputerBase> extends HandledS | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static GuiComputer<ContainerComputer> create(ContainerComputer container, PlayerInventory inventory, Text component) { |     public static GuiComputer<ContainerComputer> create(ContainerComputer container, PlayerInventory inventory, Text component) { | ||||||
|         return new GuiComputer<>(container, inventory, component, ComputerCraft.terminalWidth_computer, ComputerCraft.terminalHeight_computer); |         return new GuiComputer<>(container, inventory, component, ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static GuiComputer<ContainerPocketComputer> createPocket(ContainerPocketComputer container, PlayerInventory inventory, Text component) { |     public static GuiComputer<ContainerPocketComputer> createPocket(ContainerPocketComputer container, PlayerInventory inventory, Text component) { | ||||||
|         return new GuiComputer<>(container, inventory, component, ComputerCraft.terminalWidth_pocketComputer, ComputerCraft.terminalHeight_pocketComputer); |         return new GuiComputer<>(container, inventory, component, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static GuiComputer<ContainerViewComputer> createView(ContainerViewComputer container, PlayerInventory inventory, Text component) { |     public static GuiComputer<ContainerViewComputer> createView(ContainerViewComputer container, PlayerInventory inventory, Text component) { | ||||||
|   | |||||||
| @@ -48,10 +48,10 @@ public class GuiTurtle extends HandledScreen<ContainerTurtle> { | |||||||
|         super.init(); |         super.init(); | ||||||
|         this.client.keyboard.setRepeatEvents(true); |         this.client.keyboard.setRepeatEvents(true); | ||||||
|  |  | ||||||
|         int termPxWidth = ComputerCraft.terminalWidth_turtle * FixedWidthFontRenderer.FONT_WIDTH; |         int termPxWidth = ComputerCraft.turtleTermWidth * FixedWidthFontRenderer.FONT_WIDTH; | ||||||
|         int termPxHeight = ComputerCraft.terminalHeight_turtle * FixedWidthFontRenderer.FONT_HEIGHT; |         int termPxHeight = ComputerCraft.turtleTermHeight * FixedWidthFontRenderer.FONT_HEIGHT; | ||||||
|  |  | ||||||
|         this.terminal = new WidgetTerminal(this.client, () -> this.m_computer, ComputerCraft.terminalWidth_turtle, ComputerCraft.terminalHeight_turtle, 2, 2, 2, 2); |         this.terminal = new WidgetTerminal(this.client, () -> this.m_computer, ComputerCraft.turtleTermWidth, ComputerCraft.turtleTermHeight, 2, 2, 2, 2); | ||||||
|         this.terminalWrapper = new WidgetWrapper(this.terminal, 2 + 8 + this.x, 2 + 8 + this.y, termPxWidth, termPxHeight); |         this.terminalWrapper = new WidgetWrapper(this.terminal, 2 + 8 + this.x, 2 + 8 + this.y, termPxWidth, termPxHeight); | ||||||
|  |  | ||||||
|         this.children.add(this.terminalWrapper); |         this.children.add(this.terminalWrapper); | ||||||
|   | |||||||
| @@ -34,7 +34,9 @@ import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer; | |||||||
| import dan200.computercraft.shared.pocket.items.ItemPocketComputer; | import dan200.computercraft.shared.pocket.items.ItemPocketComputer; | ||||||
| import dan200.computercraft.shared.turtle.inventory.ContainerTurtle; | import dan200.computercraft.shared.turtle.inventory.ContainerTurtle; | ||||||
|  |  | ||||||
|  | import dan200.computercraft.shared.util.Config; | ||||||
| import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents; | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents; | ||||||
|  | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; | ||||||
| import net.minecraft.client.item.ModelPredicateProvider; | import net.minecraft.client.item.ModelPredicateProvider; | ||||||
| import net.minecraft.client.render.RenderLayer; | import net.minecraft.client.render.RenderLayer; | ||||||
| import net.minecraft.item.Item; | import net.minecraft.item.Item; | ||||||
| @@ -63,6 +65,9 @@ public final class ComputerCraftProxyClient implements ClientModInitializer { | |||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         ClientUnloadWorldEvent.EVENT.register( () -> ClientMonitor.destroyAll() ); |         ClientUnloadWorldEvent.EVENT.register( () -> ClientMonitor.destroyAll() ); | ||||||
|  |  | ||||||
|  |         // Config | ||||||
|  |         ClientLifecycleEvents.CLIENT_STARTED.register(Config::clientStarted); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -50,8 +50,8 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer { | |||||||
|  |  | ||||||
|         int termWidth, termHeight; |         int termWidth, termHeight; | ||||||
|         if (terminal == null) { |         if (terminal == null) { | ||||||
|             termWidth = ComputerCraft.terminalWidth_pocketComputer; |             termWidth = ComputerCraft.pocketTermWidth; | ||||||
|             termHeight = ComputerCraft.terminalHeight_pocketComputer; |             termHeight = ComputerCraft.pocketTermHeight; | ||||||
|         } else { |         } else { | ||||||
|             termWidth = terminal.getWidth(); |             termWidth = terminal.getWidth(); | ||||||
|             termHeight = terminal.getHeight(); |             termHeight = terminal.getHeight(); | ||||||
|   | |||||||
| @@ -156,7 +156,7 @@ public class HTTPAPI implements ILuaAPI | |||||||
|     @LuaFunction |     @LuaFunction | ||||||
|     public final Object[] websocket( String address, Optional<Map<?, ?>> headerTbl ) throws LuaException |     public final Object[] websocket( String address, Optional<Map<?, ?>> headerTbl ) throws LuaException | ||||||
|     { |     { | ||||||
|         if( !ComputerCraft.http_websocket_enable ) |         if( !ComputerCraft.httpWebsocketEnabled) | ||||||
|         { |         { | ||||||
|             throw new LuaException( "Websocket connections are disabled" ); |             throw new LuaException( "Websocket connections are disabled" ); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -188,7 +188,7 @@ public class HttpRequest extends Resource<HttpRequest> { | |||||||
|             this.failure(e.getMessage()); |             this.failure(e.getMessage()); | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             this.failure("Could not connect"); |             this.failure("Could not connect"); | ||||||
|             if (ComputerCraft.logPeripheralErrors) { |             if (ComputerCraft.logComputerErrors) { | ||||||
|                 ComputerCraft.log.error("Error in HTTP request", e); |                 ComputerCraft.log.error("Error in HTTP request", e); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -182,7 +182,7 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpOb | |||||||
|     @Override |     @Override | ||||||
|     public void exceptionCaught( ChannelHandlerContext ctx, Throwable cause ) |     public void exceptionCaught( ChannelHandlerContext ctx, Throwable cause ) | ||||||
|     { |     { | ||||||
|         if( ComputerCraft.logPeripheralErrors ) ComputerCraft.log.error( "Error handling HTTP response", cause ); |         if( ComputerCraft.logComputerErrors ) ComputerCraft.log.error( "Error handling HTTP response", cause ); | ||||||
|         request.failure( cause ); |         request.failure( cause ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -164,7 +164,7 @@ public class Websocket extends Resource<Websocket> { | |||||||
|             this.failure(e.getMessage()); |             this.failure(e.getMessage()); | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             this.failure("Could not connect"); |             this.failure("Could not connect"); | ||||||
|             if (ComputerCraft.logPeripheralErrors) { |             if (ComputerCraft.logComputerErrors) { | ||||||
|                 ComputerCraft.log.error("Error in websocket", e); |                 ComputerCraft.log.error("Error in websocket", e); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -157,7 +157,7 @@ final class ComputerExecutor { | |||||||
|         this.apis.add(new FSAPI(environment)); |         this.apis.add(new FSAPI(environment)); | ||||||
|         this.apis.add(new PeripheralAPI(environment)); |         this.apis.add(new PeripheralAPI(environment)); | ||||||
|         this.apis.add(new OSAPI(environment)); |         this.apis.add(new OSAPI(environment)); | ||||||
|         if (ComputerCraft.http_enable) { |         if (ComputerCraft.httpEnabled) { | ||||||
|             this.apis.add(new HTTPAPI(environment)); |             this.apis.add(new HTTPAPI(environment)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -124,7 +124,7 @@ public final class ComputerThread { | |||||||
|  |  | ||||||
|             if (runners == null) { |             if (runners == null) { | ||||||
|                 // TODO: Change the runners length on config reloads |                 // TODO: Change the runners length on config reloads | ||||||
|                 runners = new TaskRunner[ComputerCraft.computer_threads]; |                 runners = new TaskRunner[ComputerCraft.computerThreads]; | ||||||
|  |  | ||||||
|                 // latency and minPeriod are scaled by 1 + floor(log2(threads)). We can afford to execute tasks for |                 // latency and minPeriod are scaled by 1 + floor(log2(threads)). We can afford to execute tasks for | ||||||
|                 // longer when executing on more than one thread. |                 // longer when executing on more than one thread. | ||||||
| @@ -326,7 +326,7 @@ public final class ComputerThread { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static void timeoutTask(ComputerExecutor executor, Thread thread, long time) { |     private static void timeoutTask(ComputerExecutor executor, Thread thread, long time) { | ||||||
|         if (!ComputerCraft.logPeripheralErrors) { |         if (!ComputerCraft.logComputerErrors) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ class BasicFunction extends VarArgFunction { | |||||||
|         } catch (LuaException e) { |         } catch (LuaException e) { | ||||||
|             throw wrap(e); |             throw wrap(e); | ||||||
|         } catch (Throwable t) { |         } catch (Throwable t) { | ||||||
|             if (ComputerCraft.logPeripheralErrors) { |             if (ComputerCraft.logComputerErrors) { | ||||||
|                 ComputerCraft.log.error("Error calling " + this.name + " on " + this.instance, t); |                 ComputerCraft.log.error("Error calling " + this.name + " on " + this.instance, t); | ||||||
|             } |             } | ||||||
|             throw new LuaError("Java Exception Thrown: " + t, 0); |             throw new LuaError("Java Exception Thrown: " + t, 0); | ||||||
|   | |||||||
| @@ -119,7 +119,7 @@ public class CobaltLuaMachine implements ILuaMachine { | |||||||
|         this.m_globals.load(state, new CoroutineLib()); |         this.m_globals.load(state, new CoroutineLib()); | ||||||
|         this.m_globals.load(state, new Bit32Lib()); |         this.m_globals.load(state, new Bit32Lib()); | ||||||
|         this.m_globals.load(state, new Utf8Lib()); |         this.m_globals.load(state, new Utf8Lib()); | ||||||
|         if (ComputerCraft.debug_enable) { |         if (ComputerCraft.debugEnable) { | ||||||
|             this.m_globals.load(state, new DebugLib()); |             this.m_globals.load(state, new DebugLib()); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -135,8 +135,8 @@ public class CobaltLuaMachine implements ILuaMachine { | |||||||
|                               valueOf(computer.getAPIEnvironment() |                               valueOf(computer.getAPIEnvironment() | ||||||
|                                          .getComputerEnvironment() |                                          .getComputerEnvironment() | ||||||
|                                          .getHostString())); |                                          .getHostString())); | ||||||
|         this.m_globals.rawset("_CC_DEFAULT_SETTINGS", valueOf(ComputerCraft.default_computer_settings)); |         this.m_globals.rawset("_CC_DEFAULT_SETTINGS", valueOf(ComputerCraft.defaultComputerSettings)); | ||||||
|         if (ComputerCraft.disable_lua51_features) { |         if (ComputerCraft.disableLua51Features) { | ||||||
|             this.m_globals.rawset("_CC_DISABLE_LUA51_FEATURES", Constants.TRUE); |             this.m_globals.rawset("_CC_DISABLE_LUA51_FEATURES", Constants.TRUE); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -436,7 +436,7 @@ public class CobaltLuaMachine implements ILuaMachine { | |||||||
|             return wrapped; |             return wrapped; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (ComputerCraft.logPeripheralErrors) { |         if (ComputerCraft.logComputerErrors) { | ||||||
|             ComputerCraft.log.warn("Received unknown type '{}', returning nil.", |             ComputerCraft.log.warn("Received unknown type '{}', returning nil.", | ||||||
|                                    object.getClass() |                                    object.getClass() | ||||||
|                                          .getName()); |                                          .getName()); | ||||||
| @@ -581,7 +581,7 @@ public class CobaltLuaMachine implements ILuaMachine { | |||||||
|                                               e.getMessage() |                                               e.getMessage() | ||||||
|                                           }); |                                           }); | ||||||
|                 } catch (Throwable t) { |                 } catch (Throwable t) { | ||||||
|                     if (ComputerCraft.logPeripheralErrors) { |                     if (ComputerCraft.logComputerErrors) { | ||||||
|                         ComputerCraft.log.error("Error running task", t); |                         ComputerCraft.log.error("Error running task", t); | ||||||
|                     } |                     } | ||||||
|                     CobaltLuaMachine.this.m_computer.queueEvent("task_complete", new Object[] { |                     CobaltLuaMachine.this.m_computer.queueEvent("task_complete", new Object[] { | ||||||
|   | |||||||
| @@ -49,7 +49,7 @@ class ResultInterpreterFunction extends ResumableVarArgFunction<ResultInterprete | |||||||
|         } catch (LuaException e) { |         } catch (LuaException e) { | ||||||
|             throw wrap(e, 0); |             throw wrap(e, 0); | ||||||
|         } catch (Throwable t) { |         } catch (Throwable t) { | ||||||
|             if (ComputerCraft.logPeripheralErrors) { |             if (ComputerCraft.logComputerErrors) { | ||||||
|                 ComputerCraft.log.error("Error calling " + this.name + " on " + this.instance, t); |                 ComputerCraft.log.error("Error calling " + this.name + " on " + this.instance, t); | ||||||
|             } |             } | ||||||
|             throw new LuaError("Java Exception Thrown: " + t, 0); |             throw new LuaError("Java Exception Thrown: " + t, 0); | ||||||
| @@ -75,7 +75,7 @@ class ResultInterpreterFunction extends ResumableVarArgFunction<ResultInterprete | |||||||
|         } catch (LuaException e) { |         } catch (LuaException e) { | ||||||
|             throw wrap(e, container.errorAdjust); |             throw wrap(e, container.errorAdjust); | ||||||
|         } catch (Throwable t) { |         } catch (Throwable t) { | ||||||
|             if (ComputerCraft.logPeripheralErrors) { |             if (ComputerCraft.logComputerErrors) { | ||||||
|                 ComputerCraft.log.error("Error calling " + this.name + " on " + container.callback, t); |                 ComputerCraft.log.error("Error calling " + this.name + " on " + container.callback, t); | ||||||
|             } |             } | ||||||
|             throw new LuaError("Java Exception Thrown: " + t, 0); |             throw new LuaError("Java Exception Thrown: " + t, 0); | ||||||
|   | |||||||
| @@ -90,7 +90,7 @@ public class CommandAPI implements ILuaAPI { | |||||||
|                 result |                 result | ||||||
|             }; |             }; | ||||||
|         } catch (Throwable t) { |         } catch (Throwable t) { | ||||||
|             if (ComputerCraft.logPeripheralErrors) { |             if (ComputerCraft.logComputerErrors) { | ||||||
|                 ComputerCraft.log.error("Error running command.", t); |                 ComputerCraft.log.error("Error running command.", t); | ||||||
|             } |             } | ||||||
|             return new Object[] { |             return new Object[] { | ||||||
|   | |||||||
| @@ -67,8 +67,8 @@ public class TileComputer extends TileComputerBase { | |||||||
|                                                      id, this.label, |                                                      id, this.label, | ||||||
|                                                      instanceID, |                                                      instanceID, | ||||||
|                                                      family, |                                                      family, | ||||||
|                                                      ComputerCraft.terminalWidth_computer, |                                                      ComputerCraft.computerTermWidth, | ||||||
|                                                      ComputerCraft.terminalHeight_computer); |                                                      ComputerCraft.computerTermHeight); | ||||||
|         computer.setPosition(this.getPos()); |         computer.setPosition(this.getPos()); | ||||||
|         return computer; |         return computer; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -0,0 +1,21 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of ComputerCraft - http://www.computercraft.info | ||||||
|  |  * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission. | ||||||
|  |  * Send enquiries to dratcliffe@gmail.com | ||||||
|  |  */ | ||||||
|  | package dan200.computercraft.shared.integration; | ||||||
|  |  | ||||||
|  | import com.terraformersmc.modmenu.api.ConfigScreenFactory; | ||||||
|  | import com.terraformersmc.modmenu.api.ModMenuApi; | ||||||
|  | import net.fabricmc.api.EnvType; | ||||||
|  | import net.fabricmc.api.Environment; | ||||||
|  |  | ||||||
|  | // A stub modmenu entrypoint for when we get there | ||||||
|  |  | ||||||
|  | @Environment(EnvType.CLIENT) | ||||||
|  | public class ModMenuIntegration implements ModMenuApi { | ||||||
|  |     @Override | ||||||
|  |     public ConfigScreenFactory<?> getModConfigScreenFactory() { | ||||||
|  |         return parent -> null; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -14,9 +14,6 @@ import net.fabricmc.fabric.api.network.PacketContext; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * The base interface for any message which will be sent to the client or server. |  * The base interface for any message which will be sent to the client or server. | ||||||
|  * |  | ||||||
|  * @see dan200.computercraft.shared.network.client |  | ||||||
|  * @see dan200.computercraft.shared.network.server |  | ||||||
|  */ |  */ | ||||||
| public interface NetworkMessage { | public interface NetworkMessage { | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -30,11 +30,11 @@ public abstract class WirelessModemPeripheral extends ModemPeripheral { | |||||||
|             World world = this.getWorld(); |             World world = this.getWorld(); | ||||||
|             if (world != null) { |             if (world != null) { | ||||||
|                 Vec3d position = this.getPosition(); |                 Vec3d position = this.getPosition(); | ||||||
|                 double minRange = ComputerCraft.modem_range; |                 double minRange = ComputerCraft.modemRange; | ||||||
|                 double maxRange = ComputerCraft.modem_highAltitudeRange; |                 double maxRange = ComputerCraft.modemHighAltitudeRange; | ||||||
|                 if (world.isRaining() && world.isThundering()) { |                 if (world.isRaining() && world.isThundering()) { | ||||||
|                     minRange = ComputerCraft.modem_rangeDuringStorm; |                     minRange = ComputerCraft.modemRangeDuringStorm; | ||||||
|                     maxRange = ComputerCraft.modem_highAltitudeRangeDuringStorm; |                     maxRange = ComputerCraft.modemHighAltitudeRangeDuringStorm; | ||||||
|                 } |                 } | ||||||
|                 if (position.y > 96.0 && maxRange > minRange) { |                 if (position.y > 96.0 && maxRange > minRange) { | ||||||
|                     return minRange + (position.y - 96.0) * ((maxRange - minRange) / ((world.getHeight() - 1) - 96.0)); |                     return minRange + (position.y - 96.0) * ((maxRange - minRange) / ((world.getHeight() - 1) - 96.0)); | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces | |||||||
|     private ItemStack m_stack; |     private ItemStack m_stack; | ||||||
|  |  | ||||||
|     public PocketServerComputer(World world, int computerID, String label, int instanceID, ComputerFamily family) { |     public PocketServerComputer(World world, int computerID, String label, int instanceID, ComputerFamily family) { | ||||||
|         super(world, computerID, label, instanceID, family, ComputerCraft.terminalWidth_pocketComputer, ComputerCraft.terminalHeight_pocketComputer); |         super(world, computerID, label, instanceID, family, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Nullable |     @Nullable | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods; | |||||||
| import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork; | import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork; | ||||||
| import dan200.computercraft.shared.turtle.FurnaceRefuelHandler; | import dan200.computercraft.shared.turtle.FurnaceRefuelHandler; | ||||||
| import dan200.computercraft.shared.turtle.SignInspectHandler; | import dan200.computercraft.shared.turtle.SignInspectHandler; | ||||||
|  | import dan200.computercraft.shared.util.Config; | ||||||
| import dan200.computercraft.shared.util.TickScheduler; | import dan200.computercraft.shared.util.TickScheduler; | ||||||
|  |  | ||||||
| import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents; | import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents; | ||||||
| @@ -117,6 +118,10 @@ public final class ComputerCraftProxyCommon { | |||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|  |         // Config | ||||||
|  |         ServerLifecycleEvents.SERVER_STARTING.register(Config::serverStarting); | ||||||
|  |         ServerLifecycleEvents.SERVER_STOPPING.register(Config::serverStopping); | ||||||
|  |  | ||||||
|         TurtleEvent.EVENT_BUS.register(FurnaceRefuelHandler.INSTANCE); |         TurtleEvent.EVENT_BUS.register(FurnaceRefuelHandler.INSTANCE); | ||||||
|         TurtleEvent.EVENT_BUS.register(new TurtlePermissions()); |         TurtleEvent.EVENT_BUS.register(new TurtlePermissions()); | ||||||
|         TurtleEvent.EVENT_BUS.register(new SignInspectHandler()); |         TurtleEvent.EVENT_BUS.register(new SignInspectHandler()); | ||||||
|   | |||||||
| @@ -312,8 +312,8 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default | |||||||
|         ServerComputer computer = new ServerComputer(this.getWorld(), |         ServerComputer computer = new ServerComputer(this.getWorld(), | ||||||
|                                                      id, this.label, |                                                      id, this.label, | ||||||
|                                                      instanceID, this.getFamily(), |                                                      instanceID, this.getFamily(), | ||||||
|                                                      ComputerCraft.terminalWidth_turtle, |                                                      ComputerCraft.turtleTermWidth, | ||||||
|                                                      ComputerCraft.terminalHeight_turtle); |                                                      ComputerCraft.turtleTermHeight); | ||||||
|         computer.setPosition(this.getPos()); |         computer.setPosition(this.getPos()); | ||||||
|         computer.addAPI(new TurtleAPI(computer.getAPIEnvironment(), this.getAccess())); |         computer.addAPI(new TurtleAPI(computer.getAPIEnvironment(), this.getAccess())); | ||||||
|         this.m_brain.setupComputer(computer); |         this.m_brain.setupComputer(computer); | ||||||
|   | |||||||
| @@ -0,0 +1,44 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of ComputerCraft - http://www.computercraft.info | ||||||
|  |  * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission. | ||||||
|  |  * Send enquiries to dratcliffe@gmail.com | ||||||
|  |  */ | ||||||
|  | package dan200.computercraft.shared.util; | ||||||
|  |  | ||||||
|  | import com.electronwill.nightconfig.core.Config; | ||||||
|  | import com.electronwill.nightconfig.core.CommentedConfig; | ||||||
|  | import com.electronwill.nightconfig.core.ConfigSpec; | ||||||
|  |  | ||||||
|  | import java.util.*; | ||||||
|  |  | ||||||
|  | import static com.electronwill.nightconfig.core.utils.StringUtils.split; | ||||||
|  |  | ||||||
|  | public class CommentedConfigSpec extends ConfigSpec { | ||||||
|  |     private final Map<List<String>, String> comments = new HashMap<>(); | ||||||
|  |  | ||||||
|  |     public void comment(List<String> path, String comment) { | ||||||
|  |         comments.put(path, comment); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void comment(String path, String comment) { | ||||||
|  |         comment(split(path, '.'), comment); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int correct(Config config) { | ||||||
|  |         return correct(config, (action, path, incorrectValue, correctedValue) -> {}); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int correct(Config config, ConfigSpec.CorrectionListener listener) { | ||||||
|  |         int corrections = super.correct(config, listener); | ||||||
|  |         if(config instanceof CommentedConfig) { | ||||||
|  |             insertComments((CommentedConfig) config); | ||||||
|  |         } | ||||||
|  |         return corrections; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void insertComments(CommentedConfig config) { | ||||||
|  |         for(Map.Entry<List<String>, String> entry : comments.entrySet()) { | ||||||
|  |             config.setComment(entry.getKey(), entry.getValue()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,223 +1,365 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of ComputerCraft - http://www.computercraft.info | ||||||
|  |  * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission. | ||||||
|  |  * Send enquiries to dratcliffe@gmail.com | ||||||
|  |  */ | ||||||
| package dan200.computercraft.shared.util; | package dan200.computercraft.shared.util; | ||||||
|  |  | ||||||
| import java.io.IOException; | import com.electronwill.nightconfig.core.*; | ||||||
| import java.nio.file.Files; | import com.electronwill.nightconfig.core.file.CommentedFileConfig; | ||||||
| import java.nio.file.Path; | import com.electronwill.nightconfig.core.file.FileNotFoundAction; | ||||||
| import java.util.Objects; |  | ||||||
| import java.util.concurrent.TimeUnit; |  | ||||||
| import java.util.stream.Collectors; |  | ||||||
| import java.util.stream.Stream; |  | ||||||
|  |  | ||||||
| import blue.endless.jankson.Comment; |  | ||||||
| import blue.endless.jankson.Jankson; |  | ||||||
| import blue.endless.jankson.JsonObject; |  | ||||||
| import blue.endless.jankson.api.SyntaxError; |  | ||||||
| import com.google.common.base.CaseFormat; | import com.google.common.base.CaseFormat; | ||||||
| import com.google.common.base.Converter; | import com.google.common.base.Converter; | ||||||
| import dan200.computercraft.ComputerCraft; | import dan200.computercraft.ComputerCraft; | ||||||
| import dan200.computercraft.api.turtle.event.TurtleAction; | import dan200.computercraft.api.turtle.event.TurtleAction; | ||||||
| import dan200.computercraft.core.apis.http.options.Action; | import dan200.computercraft.core.apis.http.options.Action; | ||||||
| import dan200.computercraft.core.apis.http.options.AddressRule; | import dan200.computercraft.core.apis.http.options.AddressRuleConfig; | ||||||
| import dan200.computercraft.core.apis.http.websocket.Websocket; | import dan200.computercraft.fabric.mixin.WorldSavePathAccess; | ||||||
|  | import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer; | ||||||
|  | import net.fabricmc.loader.FabricLoader; | ||||||
|  | import net.minecraft.client.MinecraftClient; | ||||||
|  | import net.minecraft.server.MinecraftServer; | ||||||
|  | import net.minecraft.util.WorldSavePath; | ||||||
|  |  | ||||||
|  | import java.nio.file.Files; | ||||||
|  | import java.nio.file.Path; | ||||||
|  | import java.util.*; | ||||||
|  | import java.util.concurrent.TimeUnit; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  |  | ||||||
| public class Config { | public class Config { | ||||||
|     public static final transient int MODEM_MAX_RANGE = 100000; |     private static final int MODEM_MAX_RANGE = 100000; | ||||||
|     public static final transient Config defaultConfig = new Config(); |  | ||||||
|     private static transient Path configPath; |  | ||||||
|     private static transient Config config; |  | ||||||
|     public General general = new General(); |  | ||||||
|     @Comment ("\nControls execution behaviour of computers. This is largely intended for fine-tuning " + "servers, and generally shouldn't need to be " + "touched") public Execution execution = new Execution(); |  | ||||||
|     @Comment ("\nControls the HTTP API") public Http http = new Http(); |  | ||||||
|     @Comment ("\nVarious options relating to peripherals.") public Peripheral peripheral = new Peripheral(); |  | ||||||
|     @Comment ("\nVarious options relating to turtles.") public Turtle turtle = new Turtle(); |  | ||||||
|  |  | ||||||
|     public static Config get() { |     public static final String TRANSLATION_PREFIX = "gui.computercraft.config."; | ||||||
|         return config; |  | ||||||
|  |     public static final CommentedConfigSpec serverSpec; | ||||||
|  |     public static final CommentedConfigSpec clientSpec; | ||||||
|  |  | ||||||
|  |     public static CommentedConfig serverConfig; | ||||||
|  |     public static CommentedConfig clientConfig; | ||||||
|  |  | ||||||
|  |     private static final WorldSavePath serverDir = WorldSavePathAccess.createWorldSavePath("serverconfig"); | ||||||
|  |     private static final String serverFileName = "computercraft-server.toml"; | ||||||
|  |     private static final Path clientPath = FabricLoader.INSTANCE.getConfigDir().resolve("computercraft-client.toml"); | ||||||
|  |  | ||||||
|  |     private Config() { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void load(Path path) { |     static { | ||||||
|         configPath = path; |         System.setProperty("nightconfig.preserveInsertionOrder", "true"); | ||||||
|  |  | ||||||
|         if (Files.exists(configPath)) { |         serverSpec = new CommentedConfigSpec(); | ||||||
|             Jankson jankson = Jankson.builder() |         { // General computers | ||||||
|  |             serverSpec.comment("computer_space_limit", | ||||||
|  |                     "The disk space limit for computers and turtles, in bytes"); | ||||||
|  |             serverSpec.define("computer_space_limit", ComputerCraft.computerSpaceLimit); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("floppy_space_limit", | ||||||
|  |                     "The disk space limit for floppy disks, in bytes"); | ||||||
|  |             serverSpec.define("floppy_space_limit", ComputerCraft.floppySpaceLimit); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("maximum_open_files", | ||||||
|  |                     "Set how many files a computer can have open at the same time. Set to 0 for unlimited."); | ||||||
|  |             serverSpec.defineInRange("maximum_open_files", ComputerCraft.maximumFilesOpen, 0, Integer.MAX_VALUE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("disable_lua51_features", | ||||||
|  |                     "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."); | ||||||
|  |             serverSpec.define("disable_lua51_features", ComputerCraft.disableLua51Features); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("default_computer_settings", | ||||||
|  |                     "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"); | ||||||
|  |             serverSpec.define("default_computer_settings", ComputerCraft.defaultComputerSettings); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("debug_enabled", | ||||||
|  |                     "Enable Lua's debug library. This is sandboxed to each computer, so is generally safe to be used by players."); | ||||||
|  |             serverSpec.define("debug_enabled", ComputerCraft.debugEnable); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("log_computer_errors", | ||||||
|  |                     "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."); | ||||||
|  |             serverSpec.define("log_computer_errors", ComputerCraft.logComputerErrors); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("command_require_creative", | ||||||
|  |                     "Require players to be in creative mode and be opped in order to interact with command computers." + | ||||||
|  |                     "This is the default behaviour for vanilla's Command blocks."); | ||||||
|  |             serverSpec.define("command_require_creative", ComputerCraft.commandRequireCreative); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         { // Execution | ||||||
|  |             serverSpec.comment("execution", | ||||||
|  |                     "Controls execution behaviour of computers. This is largely intended for fine-tuning " + | ||||||
|  |                     "servers, and generally shouldn't need to be touched"); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("execution.computer_threads", | ||||||
|  |                     "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."); | ||||||
|  |             serverSpec.defineInRange("execution.computer_threads", ComputerCraft.computerThreads, 1, Integer.MAX_VALUE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("execution.max_main_global_time", | ||||||
|  |                     "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."); | ||||||
|  |             serverSpec.defineInRange("execution.max_main_global_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainGlobalTime ), 1, Integer.MAX_VALUE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("execution.max_main_computer_time", | ||||||
|  |                     "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."); | ||||||
|  |             serverSpec.defineInRange("execution.max_main_computer_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainComputerTime ), 1, Integer.MAX_VALUE); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         { // HTTP | ||||||
|  |             serverSpec.comment("http", "Controls the HTTP API"); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("http.enabled", | ||||||
|  |                     "Enable the \"http\" API on Computers (see \"rules\" for more fine grained control than this)."); | ||||||
|  |             serverSpec.define("http.enabled", ComputerCraft.httpEnabled); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("http.websocket_enabled", | ||||||
|  |                     "Enable use of http websockets. This requires the \"http_enable\" option to also be true."); | ||||||
|  |             serverSpec.define("http.websocket_enabled", ComputerCraft.httpWebsocketEnabled); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("http.rules", | ||||||
|  |                     "A list of rules which control behaviour of the \"http\" API for specific domains or IPs.\n" + | ||||||
|  |                     "Each rule is an item with a 'host' to match against, and a series of properties. " + | ||||||
|  |                     "The host may be a domain name (\"pastebin.com\"),\n" + | ||||||
|  |                     "wildcard (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\"). If no rules, the domain is blocked."); | ||||||
|  |             serverSpec.defineList("http.rules", Arrays.asList( | ||||||
|  |                             AddressRuleConfig.makeRule("$private", Action.DENY), | ||||||
|  |                             AddressRuleConfig.makeRule("*", Action.ALLOW) | ||||||
|  |                     ), x -> x instanceof UnmodifiableConfig && AddressRuleConfig.checkRule((UnmodifiableConfig) x)); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("http.max_requests", | ||||||
|  |                     "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."); | ||||||
|  |             serverSpec.defineInRange("http.max_requests", ComputerCraft.httpMaxRequests, 0, Integer.MAX_VALUE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("http.max_websockets", | ||||||
|  |                     "The number of websockets a computer can have open at one time. Set to 0 for unlimited."); | ||||||
|  |             serverSpec.defineInRange("http.max_websockets", ComputerCraft.httpMaxWebsockets, 1, Integer.MAX_VALUE); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         { // Peripherals | ||||||
|  |             serverSpec.comment("peripheral", "Various options relating to peripherals."); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("peripheral.command_block_enabled", | ||||||
|  |                     "Enable Command Block peripheral support"); | ||||||
|  |             serverSpec.define("peripheral.command_block_enabled", ComputerCraft.enableCommandBlock); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("peripheral.modem_range", | ||||||
|  |                     "The range of Wireless Modems at low altitude in clear weather, in meters"); | ||||||
|  |             serverSpec.defineInRange("peripheral.modem_range", ComputerCraft.modemRange, 0, MODEM_MAX_RANGE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("peripheral.modem_high_altitude_range", | ||||||
|  |                     "The range of Wireless Modems at maximum altitude in clear weather, in meters"); | ||||||
|  |             serverSpec.defineInRange("peripheral.modem_high_altitude_range", ComputerCraft.modemHighAltitudeRange, 0, MODEM_MAX_RANGE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("peripheral.modem_range_during_storm", | ||||||
|  |                     "The range of Wireless Modems at low altitude in stormy weather, in meters"); | ||||||
|  |             serverSpec.defineInRange("peripheral.modem_range_during_storm", ComputerCraft.modemRangeDuringStorm, 0, MODEM_MAX_RANGE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("peripheral.modem_high_altitude_range_during_storm", | ||||||
|  |                     "The range of Wireless Modems at maximum altitude in stormy weather, in meters"); | ||||||
|  |             serverSpec.defineInRange("peripheral.modem_high_altitude_range_during_storm", ComputerCraft.modemHighAltitudeRangeDuringStorm, 0, MODEM_MAX_RANGE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("peripheral.max_notes_per_tick", | ||||||
|  |                     "Maximum amount of notes a speaker can play at once"); | ||||||
|  |             serverSpec.defineInRange("peripheral.max_notes_per_tick", ComputerCraft.maxNotesPerTick, 1, Integer.MAX_VALUE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("peripheral.monitor_bandwidth", | ||||||
|  |                     "The limit to how much monitor data can be sent *per tick*. Note:\n" + | ||||||
|  |                     " - Bandwidth is measured before compression, so the data sent to the client is smaller.\n" + | ||||||
|  |                     " - This ignores the number of players a packet is sent to. Updating a monitor for one player consumes " + | ||||||
|  |                     "the same bandwidth limit as sending to 20.\n" + | ||||||
|  |                     " - A full sized monitor sends ~25kb of data. So the default (1MB) allows for ~40 monitors to be updated " + | ||||||
|  |                     "in a single tick. \n" + | ||||||
|  |                     "Set to 0 to disable."); | ||||||
|  |             serverSpec.defineInRange("peripheral.monitor_bandwidth", (int) ComputerCraft.monitorBandwidth, 0, Integer.MAX_VALUE); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         { // Turtles | ||||||
|  |             serverSpec.comment("turtle", "Various options relating to turtles."); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("turtle.need_fuel", | ||||||
|  |                     "Set whether Turtles require fuel to move"); | ||||||
|  |             serverSpec.define("turtle.need_fuel", ComputerCraft.turtlesNeedFuel); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("turtle.normal_fuel_limit", "The fuel limit for Turtles"); | ||||||
|  |             serverSpec.defineInRange("turtle.normal_fuel_limit", ComputerCraft.turtleFuelLimit, 0, Integer.MAX_VALUE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("turtle.advanced_fuel_limit", | ||||||
|  |                     "The fuel limit for Advanced Turtles"); | ||||||
|  |             serverSpec.defineInRange("turtle.advanced_fuel_limit", ComputerCraft.advancedTurtleFuelLimit, 0, Integer.MAX_VALUE); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("turtle.obey_block_protection", | ||||||
|  |                     "If set to true, Turtles will be unable to build, dig, or enter protected areas (such as near the server spawn point)"); | ||||||
|  |             serverSpec.define("turtle.obey_block_protection", ComputerCraft.turtlesObeyBlockProtection); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("turtle.can_push", | ||||||
|  |                     "If set to true, Turtles will push entities out of the way instead of stopping if there is space to do so"); | ||||||
|  |             serverSpec.define("turtle.can_push", ComputerCraft.turtlesCanPush); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("turtle.disabled_actions", | ||||||
|  |                     "A list of turtle actions which are disabled."); | ||||||
|  |             serverSpec.defineList("turtle.disabled_actions", Collections.emptyList(), x -> x instanceof String && getAction((String) x) != null); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         { | ||||||
|  |             serverSpec.comment("term_sizes", "Configure the size of various computer's terminals.\n" + | ||||||
|  |                     "Larger terminals require more bandwidth, so use with care."); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("term_sizes.computer", "Terminal size of computers"); | ||||||
|  |             serverSpec.defineInRange("term_sizes.computer.width", ComputerCraft.computerTermWidth, 1, 255); | ||||||
|  |             serverSpec.defineInRange("term_sizes.computer.height", ComputerCraft.computerTermHeight, 1, 255); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("term_sizes.pocket_computer", "Terminal size of pocket computers"); | ||||||
|  |             serverSpec.defineInRange("term_sizes.pocket_computer.width", ComputerCraft.pocketTermWidth, 1, 255); | ||||||
|  |             serverSpec.defineInRange("term_sizes.pocket_computer.height", ComputerCraft.pocketTermHeight, 1, 255); | ||||||
|  |  | ||||||
|  |             serverSpec.comment("term_sizes.monitor", "Maximum size of monitors (in blocks)"); | ||||||
|  |             serverSpec.defineInRange("term_sizes.monitor.width", ComputerCraft.monitorWidth, 1, 32); | ||||||
|  |             serverSpec.defineInRange("term_sizes.monitor.height", ComputerCraft.monitorHeight, 1, 32); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         clientSpec = new CommentedConfigSpec(); | ||||||
|  |  | ||||||
|  |         clientSpec.comment("monitor_renderer", | ||||||
|  |                 "The renderer to use for monitors. Generally this should be kept at \"best\" - if " + | ||||||
|  |                 "monitors have performance issues, you may wish to experiment with alternative renderers."); | ||||||
|  |         clientSpec.defineRestrictedEnum("monitor_renderer", MonitorRenderer.BEST, EnumSet.allOf(MonitorRenderer.class), EnumGetMethod.NAME_IGNORECASE); | ||||||
|  |  | ||||||
|  |         clientSpec.comment("monitor_distance", | ||||||
|  |                 "The maximum distance monitors will render at. This defaults to the standard tile entity limit, " + | ||||||
|  |                 "but may be extended if you wish to build larger monitors." ); | ||||||
|  |         clientSpec.defineInRange("monitor_distance", 64, 16, 1024); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static final FileNotFoundAction MAKE_DIRECTORIES = (file, configFormat) -> { | ||||||
|  |         Files.createDirectories(file.getParent()); | ||||||
|  |         Files.createFile(file); | ||||||
|  |         configFormat.initEmptyFile(file); | ||||||
|  |         return false; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private static CommentedFileConfig buildFileConfig(Path path) { | ||||||
|  |         return CommentedFileConfig.builder(path) | ||||||
|  |                 .onFileNotFound(MAKE_DIRECTORIES) | ||||||
|  |                 .preserveInsertionOrder() | ||||||
|                 .build(); |                 .build(); | ||||||
|             try { |  | ||||||
|                 JsonObject jsonObject = jankson.load(Files.newInputStream(configPath)); |  | ||||||
|                 config = jankson.fromJson(jsonObject, Config.class); |  | ||||||
|             } catch (IOException | SyntaxError e) { |  | ||||||
|                 config = new Config(); |  | ||||||
|                 ComputerCraft.log.error("Failed to load config! Use default config."); |  | ||||||
|                 e.printStackTrace(); |  | ||||||
|                 return; |  | ||||||
|     } |     } | ||||||
|         } else { |  | ||||||
|             config = new Config(); |     public static void serverStarting(MinecraftServer server) { | ||||||
|         } |         Path serverPath = server.getSavePath(serverDir).resolve(serverFileName); | ||||||
|         save(); |  | ||||||
|  |         try(CommentedFileConfig config = buildFileConfig(serverPath)) { | ||||||
|  |             config.load(); | ||||||
|  |             serverSpec.correct(config, Config::correctionListener); | ||||||
|  |             config.save(); | ||||||
|  |             serverConfig = config; | ||||||
|             sync(); |             sync(); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public static void save() { |     public static void serverStopping(MinecraftServer server) { | ||||||
|         Jankson jankson = Jankson.builder() |         serverConfig = null; | ||||||
|                                  .build(); |     } | ||||||
|         try { |  | ||||||
|             String configData = jankson.toJson(config) |     public static void clientStarted(MinecraftClient client) { | ||||||
|                                        .toJson(true, true); |         try (CommentedFileConfig config = buildFileConfig(clientPath)) { | ||||||
|             Files.write(configPath, configData.getBytes()); |             config.load(); | ||||||
|         } catch (IOException e) { |             clientSpec.correct(config, Config::correctionListener); | ||||||
|             ComputerCraft.log.error("Failed to save config!"); |             config.save(); | ||||||
|             e.printStackTrace(); |             clientConfig = config; | ||||||
|  |             sync(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void correctionListener(ConfigSpec.CorrectionAction action, List<String> path, Object incorrectValue, Object correctedValue) { | ||||||
|  |         String key = String.join(".", path); | ||||||
|  |         switch(action) { | ||||||
|  |             case ADD: | ||||||
|  |                 ComputerCraft.log.warn("Config key {} missing -> added default value.", key); break; | ||||||
|  |             case REMOVE: | ||||||
|  |                 ComputerCraft.log.warn("Config key {} not defined -> removed from config.", key); break; | ||||||
|  |             case REPLACE: | ||||||
|  |                 ComputerCraft.log.warn("Config key {} not valid -> replaced with default value.", key); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void sync() { |     public static void sync() { | ||||||
|  |         if(serverConfig != null) { | ||||||
|             // General |             // General | ||||||
|         ComputerCraft.computerSpaceLimit = config.general.computer_space_limit; |             ComputerCraft.computerSpaceLimit = serverConfig.<Integer>get("computer_space_limit"); | ||||||
|         ComputerCraft.floppySpaceLimit = config.general.floppy_space_limit; |             ComputerCraft.floppySpaceLimit = serverConfig.<Integer>get("floppy_space_limit"); | ||||||
|         ComputerCraft.maximumFilesOpen = Math.max(0, config.general.maximum_open_files); |             ComputerCraft.maximumFilesOpen = serverConfig.<Integer>get("maximum_open_files"); | ||||||
|         ComputerCraft.disable_lua51_features = config.general.disable_lua51_features; |             ComputerCraft.disableLua51Features = serverConfig.<Boolean>get("disable_lua51_features"); | ||||||
|         ComputerCraft.default_computer_settings = config.general.default_computer_settings; |             ComputerCraft.defaultComputerSettings = serverConfig.<String>get("default_computer_settings"); | ||||||
|         ComputerCraft.debug_enable = config.general.debug_enabled; |             ComputerCraft.debugEnable = serverConfig.<Boolean>get("debug_enabled"); | ||||||
|         ComputerCraft.logPeripheralErrors = config.general.log_computer_errors; |             ComputerCraft.logComputerErrors = serverConfig.<Boolean>get("log_computer_errors"); | ||||||
|  |             ComputerCraft.commandRequireCreative = serverConfig.<Boolean>get("command_require_creative"); | ||||||
|  |  | ||||||
|             // Execution |             // Execution | ||||||
|         ComputerCraft.computer_threads = Math.max(1, config.execution.computer_threads); |             ComputerCraft.computerThreads = serverConfig.<Integer>get("execution.computer_threads"); | ||||||
|         ComputerCraft.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(Math.max(1, config.execution.max_main_global_time)); |             ComputerCraft.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(serverConfig.<Integer>get("execution.max_main_global_time")); | ||||||
|         ComputerCraft.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(Math.max(1, config.execution.max_main_computer_time)); |             ComputerCraft.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(serverConfig.<Integer>get("execution.max_main_computer_time")); | ||||||
|  |  | ||||||
|             // HTTP |             // HTTP | ||||||
|         ComputerCraft.http_enable = config.http.enabled; |             ComputerCraft.httpEnabled = serverConfig.<Boolean>get("http.enabled"); | ||||||
|         ComputerCraft.http_websocket_enable = config.http.websocket_enabled; |             ComputerCraft.httpWebsocketEnabled = serverConfig.<Boolean>get("http.websocket_enabled"); | ||||||
|         ComputerCraft.httpRules = Stream.concat(Stream.of(config.http.blacklist) |             ComputerCraft.httpRules = serverConfig.<List<UnmodifiableConfig>>get("http.rules").stream().map(AddressRuleConfig::parseRule) | ||||||
|                 .map( x -> AddressRule.parse( x, null, Action.DENY.toPartial())) |                     .filter(Objects::nonNull).collect(Collectors.toList()); | ||||||
|                 .filter(Objects::nonNull), |             ComputerCraft.httpMaxRequests = serverConfig.<Integer>get("http.max_requests"); | ||||||
|         Stream.of(config.http.whitelist) |             ComputerCraft.httpMaxWebsockets = serverConfig.<Integer>get("http.max_websockets"); | ||||||
|                 .map( x -> AddressRule.parse( x, null, Action.ALLOW.toPartial())) |  | ||||||
|                 .filter(Objects::nonNull)) |  | ||||||
|         .collect(Collectors.toList()); |  | ||||||
|  |  | ||||||
|         ComputerCraft.httpTimeout = Math.max(0, config.http.timeout); |             // Peripherals | ||||||
|         ComputerCraft.httpMaxRequests = Math.max(1, config.http.max_requests); |             ComputerCraft.enableCommandBlock = serverConfig.<Boolean>get("peripheral.command_block_enabled"); | ||||||
|         ComputerCraft.httpMaxDownload = Math.max(0, config.http.max_download); |             ComputerCraft.modemRange = serverConfig.<Integer>get("peripheral.modem_range"); | ||||||
|         ComputerCraft.httpMaxUpload = Math.max(0, config.http.max_upload); |             ComputerCraft.modemHighAltitudeRange = serverConfig.<Integer>get("peripheral.modem_high_altitude_range"); | ||||||
|         ComputerCraft.httpMaxWebsockets = Math.max(1, config.http.max_websockets); |             ComputerCraft.modemRangeDuringStorm = serverConfig.<Integer>get("peripheral.modem_range_during_storm"); | ||||||
|         ComputerCraft.httpMaxWebsocketMessage = Math.min(Math.max(0, config.http.max_websocket_message), Websocket.MAX_MESSAGE_SIZE); |             ComputerCraft.modemHighAltitudeRangeDuringStorm = serverConfig.<Integer>get("peripheral.modem_high_altitude_range_during_storm"); | ||||||
|  |             ComputerCraft.maxNotesPerTick = serverConfig.<Integer>get("peripheral.max_notes_per_tick"); | ||||||
|         // Peripheral |             ComputerCraft.monitorBandwidth = serverConfig.<Integer>get("peripheral.monitor_bandwidth"); | ||||||
|         ComputerCraft.enableCommandBlock = config.peripheral.command_block_enabled; |  | ||||||
|         ComputerCraft.maxNotesPerTick = Math.max(1, config.peripheral.max_notes_per_tick); |  | ||||||
|         ComputerCraft.modem_range = Math.min(Math.max(0, config.peripheral.modem_range), MODEM_MAX_RANGE); |  | ||||||
|         ComputerCraft.modem_highAltitudeRange = Math.min(Math.max(0, config.peripheral.modem_high_altitude_range), MODEM_MAX_RANGE); |  | ||||||
|         ComputerCraft.modem_rangeDuringStorm = Math.min(Math.max(0, config.peripheral.modem_range_during_storm), MODEM_MAX_RANGE); |  | ||||||
|         ComputerCraft.modem_highAltitudeRangeDuringStorm = Math.min(Math.max(0, config.peripheral.modem_high_altitude_range_during_storm), MODEM_MAX_RANGE); |  | ||||||
|  |  | ||||||
|             // Turtles |             // Turtles | ||||||
|         ComputerCraft.turtlesNeedFuel = config.turtle.need_fuel; |             ComputerCraft.turtlesNeedFuel = serverConfig.<Boolean>get("turtle.need_fuel"); | ||||||
|         ComputerCraft.turtleFuelLimit = Math.max(0, config.turtle.normal_fuel_limit); |             ComputerCraft.turtleFuelLimit = serverConfig.<Integer>get("turtle.normal_fuel_limit"); | ||||||
|         ComputerCraft.advancedTurtleFuelLimit = Math.max(0, config.turtle.advanced_fuel_limit); |             ComputerCraft.advancedTurtleFuelLimit = serverConfig.<Integer>get("turtle.advanced_fuel_limit"); | ||||||
|         ComputerCraft.turtlesObeyBlockProtection = config.turtle.obey_block_protection; |             ComputerCraft.turtlesObeyBlockProtection = serverConfig.<Boolean>get("turtle.obey_block_protection"); | ||||||
|         ComputerCraft.turtlesCanPush = config.turtle.can_push; |             ComputerCraft.turtlesCanPush = serverConfig.<Boolean>get("turtle.can_push"); | ||||||
|  |  | ||||||
|             ComputerCraft.turtleDisabledActions.clear(); |             ComputerCraft.turtleDisabledActions.clear(); | ||||||
|         Converter<String, String> converter = CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.UPPER_UNDERSCORE); |             for(String value : serverConfig.<List<String>>get("turtle.disabled_actions")) { | ||||||
|         for (String value : config.turtle.disabled_actions) { |                 ComputerCraft.turtleDisabledActions.add(getAction(value)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // Terminal Size | ||||||
|  |             ComputerCraft.computerTermWidth = serverConfig.<Integer>get("term_sizes.computer.width"); | ||||||
|  |             ComputerCraft.computerTermHeight = serverConfig.<Integer>get("term_sizes.computer.height"); | ||||||
|  |             ComputerCraft.pocketTermWidth = serverConfig.<Integer>get("term_sizes.pocket_computer.width"); | ||||||
|  |             ComputerCraft.pocketTermHeight = serverConfig.<Integer>get("term_sizes.pocket_computer.height"); | ||||||
|  |             ComputerCraft.monitorWidth = serverConfig.<Integer>get("term_sizes.monitor.width"); | ||||||
|  |             ComputerCraft.monitorHeight = serverConfig.<Integer>get("term_sizes.monitor.height"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Client | ||||||
|  |         if(clientConfig != null) { | ||||||
|  |             ComputerCraft.monitorRenderer = clientConfig.getEnum("monitor_renderer", MonitorRenderer.class); | ||||||
|  |             int distance = clientConfig.get("monitor_distance"); | ||||||
|  |             ComputerCraft.monitorDistanceSq = distance * distance; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static final Converter<String, String> converter = CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.UPPER_UNDERSCORE); | ||||||
|  |  | ||||||
|  |     private static TurtleAction getAction(String value) { | ||||||
|         try { |         try { | ||||||
|                 ComputerCraft.turtleDisabledActions.add(TurtleAction.valueOf(converter.convert(value))); |             return TurtleAction.valueOf(converter.convert(value)); | ||||||
|             } catch (IllegalArgumentException e) { |         } | ||||||
|                 ComputerCraft.log.error("Unknown turtle action " + value); |         catch(IllegalArgumentException e) { | ||||||
|  |             return null; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|     public static class General { |  | ||||||
|         @Comment ("\nThe disk space limit for computers and turtles, in bytes") public int computer_space_limit = ComputerCraft.computerSpaceLimit; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe disk space limit for floppy disks, in bytes") public int floppy_space_limit = ComputerCraft.floppySpaceLimit; |  | ||||||
|  |  | ||||||
|         @Comment ("\nSet how many files a computer can have open at the same time. Set to 0 for unlimited.") public int maximum_open_files = |  | ||||||
|             ComputerCraft.maximumFilesOpen; |  | ||||||
|  |  | ||||||
|         @Comment ("\nSet 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.") public boolean disable_lua51_features = ComputerCraft.disable_lua51_features; |  | ||||||
|  |  | ||||||
|         @Comment ("\nA 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") public String default_computer_settings = |  | ||||||
|             ComputerCraft.default_computer_settings; |  | ||||||
|  |  | ||||||
|         @Comment ("\nEnable Lua's debug library. This is sandboxed to each computer, so is generally safe to be used by players.") public boolean debug_enabled = ComputerCraft.debug_enable; |  | ||||||
|  |  | ||||||
|         @Comment ("\nLog 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.") public boolean log_computer_errors = ComputerCraft.logPeripheralErrors; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static class Execution { |  | ||||||
|         @Comment ("\nSet 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.") public int computer_threads = |  | ||||||
|             ComputerCraft.computer_threads; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe 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.") public long max_main_global_time = TimeUnit.NANOSECONDS.toMillis( |  | ||||||
|             ComputerCraft.maxMainGlobalTime); |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe 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.") public long max_main_computer_time = TimeUnit.NANOSECONDS.toMillis( |  | ||||||
|             ComputerCraft.maxMainComputerTime); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static class Http { |  | ||||||
|         @Comment ("\nEnable the \"http\" API on Computers (see \"http_whitelist\" and \"http_blacklist\" for " + "more fine grained control than this)") public boolean enabled = ComputerCraft.http_enable; |  | ||||||
|  |  | ||||||
|         @Comment ("\nEnable use of http websockets. This requires the \"http_enable\" option to also be true.") public boolean websocket_enabled = |  | ||||||
|             ComputerCraft.http_websocket_enable; |  | ||||||
|  |  | ||||||
|         @Comment ("\nA 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\").") public String[] whitelist = new String[] {"*"}; |  | ||||||
|  |  | ||||||
|         @Comment ("\nA 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\").") public String[] blacklist = new String[] {"$private"}; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe period of time (in milliseconds) to wait before a HTTP request times out. Set to 0 for unlimited.") public int timeout = |  | ||||||
|             ComputerCraft.httpTimeout; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe 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.") public int max_requests = ComputerCraft.httpMaxRequests; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe 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.") public long max_download = ComputerCraft.httpMaxDownload; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe maximum size (in bytes) that a computer can upload in a single request. This " + "includes headers and POST text.") public long max_upload = ComputerCraft.httpMaxUpload; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe number of websockets a computer can have open at one time. Set to 0 for unlimited.") public int max_websockets = |  | ||||||
|             ComputerCraft.httpMaxWebsockets; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe maximum size (in bytes) that a computer can send or receive in one websocket packet.") public int max_websocket_message = |  | ||||||
|             ComputerCraft.httpMaxWebsocketMessage; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static class Peripheral { |  | ||||||
|         @Comment ("\n\nEnable Command Block peripheral support") public boolean command_block_enabled = ComputerCraft.enableCommandBlock; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe range of Wireless Modems at low altitude in clear weather, in meters") public int modem_range = ComputerCraft.modem_range; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe range of Wireless Modems at maximum altitude in clear weather, in meters") public int modem_high_altitude_range = |  | ||||||
|             ComputerCraft.modem_highAltitudeRange; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe range of Wireless Modems at low altitude in stormy weather, in meters") public int modem_range_during_storm = |  | ||||||
|             ComputerCraft.modem_rangeDuringStorm; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe range of Wireless Modems at maximum altitude in stormy weather, in meters") public int modem_high_altitude_range_during_storm = |  | ||||||
|             ComputerCraft.modem_highAltitudeRangeDuringStorm; |  | ||||||
|  |  | ||||||
|         @Comment ("\nMaximum amount of notes a speaker can play at once") public int max_notes_per_tick = ComputerCraft.maxNotesPerTick; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static class Turtle { |  | ||||||
|         @Comment ("\nSet whether Turtles require fuel to move") public boolean need_fuel = ComputerCraft.turtlesNeedFuel; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe fuel limit for Turtles") public int normal_fuel_limit = ComputerCraft.turtleFuelLimit; |  | ||||||
|  |  | ||||||
|         @Comment ("\nThe fuel limit for Advanced Turtles") public int advanced_fuel_limit = ComputerCraft.advancedTurtleFuelLimit; |  | ||||||
|  |  | ||||||
|         @Comment ("\nIf set to true, Turtles will be unable to build, dig, or enter protected " + "areas (such as near the server spawn point)") public boolean obey_block_protection = ComputerCraft.turtlesObeyBlockProtection; |  | ||||||
|  |  | ||||||
|         @Comment ("\nIf set to true, Turtles will push entities out of the way instead of stopping if " + "there is space to do so") public boolean can_push = ComputerCraft.turtlesCanPush; |  | ||||||
|  |  | ||||||
|         @Comment ("\nA list of turtle actions which are disabled.") public String[] disabled_actions = new String[0]; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -33,6 +33,9 @@ | |||||||
|         ], |         ], | ||||||
|         "client": [ |         "client": [ | ||||||
|             "dan200.computercraft.client.proxy.ComputerCraftProxyClient" |             "dan200.computercraft.client.proxy.ComputerCraftProxyClient" | ||||||
|  |         ], | ||||||
|  |         "modmenu": [ | ||||||
|  |             "dan200.computercraft.shared.integration.ModMenuIntegration" | ||||||
|         ] |         ] | ||||||
|     }, |     }, | ||||||
|     "mixins": [ |     "mixins": [ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ToadDev
					ToadDev