mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 13:42:59 +00:00 
			
		
		
		
	Prepare dan200.computercraft.core for splitting off
- Move core-specific config options to a separate CoreConfig class. - Use class-specific loggers, instead of a global one. - Use log markers instead of a logComputerErrors option.
This commit is contained in:
		| @@ -5,8 +5,6 @@ | ||||
|  */ | ||||
| package dan200.computercraft; | ||||
| 
 | ||||
| import dan200.computercraft.core.apis.http.options.Action; | ||||
| import dan200.computercraft.core.apis.http.options.AddressRule; | ||||
| import dan200.computercraft.shared.Config; | ||||
| import dan200.computercraft.shared.Registry; | ||||
| import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer; | ||||
| @@ -14,37 +12,15 @@ import net.minecraftforge.fml.common.Mod; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.OptionalInt; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| @Mod(ComputerCraft.MOD_ID) | ||||
| public final class ComputerCraft { | ||||
|     public static final String MOD_ID = "computercraft"; | ||||
| 
 | ||||
|     public static int computerSpaceLimit = 1000 * 1000; | ||||
|     public static int floppySpaceLimit = 125 * 1000; | ||||
|     public static int maximumFilesOpen = 128; | ||||
|     public static boolean disableLua51Features = false; | ||||
|     public static String defaultComputerSettings = ""; | ||||
|     public static boolean logComputerErrors = true; | ||||
|     public static boolean commandRequireCreative = true; | ||||
| 
 | ||||
|     public static int computerThreads = 1; | ||||
|     public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(10); | ||||
|     public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(5); | ||||
| 
 | ||||
|     public static boolean httpEnabled = true; | ||||
|     public static boolean httpWebsocketEnabled = true; | ||||
|     public static List<AddressRule> httpRules = List.of( | ||||
|         AddressRule.parse("$private", OptionalInt.empty(), Action.DENY.toPartial()), | ||||
|         AddressRule.parse("*", OptionalInt.empty(), Action.ALLOW.toPartial()) | ||||
|     ); | ||||
| 
 | ||||
|     public static int httpMaxRequests = 16; | ||||
|     public static int httpMaxWebsockets = 4; | ||||
|     public static int httpDownloadBandwidth = 32 * 1024 * 1024; | ||||
|     public static int httpUploadBandwidth = 32 * 1024 * 1024; | ||||
| 
 | ||||
|     public static boolean enableCommandBlock = false; | ||||
|     public static int modemRange = 64; | ||||
|   | ||||
							
								
								
									
										42
									
								
								src/main/java/dan200/computercraft/core/CoreConfig.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/main/java/dan200/computercraft/core/CoreConfig.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| /* | ||||
|  * This file is part of ComputerCraft - http://www.computercraft.info | ||||
|  * Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission. | ||||
|  * Send enquiries to dratcliffe@gmail.com | ||||
|  */ | ||||
| package dan200.computercraft.core; | ||||
| 
 | ||||
| import dan200.computercraft.core.apis.http.options.Action; | ||||
| import dan200.computercraft.core.apis.http.options.AddressRule; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.OptionalInt; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| /** | ||||
|  * Config options for ComputerCraft's Lua runtime. | ||||
|  */ | ||||
| public final class CoreConfig { | ||||
|     // TODO: Ideally this would be an instance in {@link ComputerContext}, but sharing this everywhere it needs to be is | ||||
|     //  tricky. | ||||
| 
 | ||||
|     private CoreConfig() { | ||||
|     } | ||||
| 
 | ||||
|     public static int maximumFilesOpen = 128; | ||||
|     public static boolean disableLua51Features = false; | ||||
|     public static String defaultComputerSettings = ""; | ||||
| 
 | ||||
|     public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(10); | ||||
|     public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(5); | ||||
| 
 | ||||
|     public static boolean httpEnabled = true; | ||||
|     public static boolean httpWebsocketEnabled = true; | ||||
|     public static List<AddressRule> httpRules = List.of( | ||||
|         AddressRule.parse("$private", OptionalInt.empty(), Action.DENY.toPartial()), | ||||
|         AddressRule.parse("*", OptionalInt.empty(), Action.ALLOW.toPartial()) | ||||
|     ); | ||||
|     public static int httpMaxRequests = 16; | ||||
|     public static int httpMaxWebsockets = 4; | ||||
|     public static int httpDownloadBandwidth = 32 * 1024 * 1024; | ||||
|     public static int httpUploadBandwidth = 32 * 1024 * 1024; | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/main/java/dan200/computercraft/core/Logging.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/main/java/dan200/computercraft/core/Logging.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| /* | ||||
|  * This file is part of ComputerCraft - http://www.computercraft.info | ||||
|  * Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission. | ||||
|  * Send enquiries to dratcliffe@gmail.com | ||||
|  */ | ||||
| package dan200.computercraft.core; | ||||
| 
 | ||||
| import org.slf4j.Marker; | ||||
| import org.slf4j.MarkerFactory; | ||||
| 
 | ||||
| /** | ||||
|  * Shared log markers for ComputerCraft. | ||||
|  */ | ||||
| public final class Logging { | ||||
|     public static final Marker COMPUTER_ERROR = MarkerFactory.getMarker("COMPUTER_ERROR"); | ||||
|     public static final Marker HTTP_ERROR = MarkerFactory.getMarker("COMPUTER_ERROR.HTTP"); | ||||
|     public static final Marker JAVA_ERROR = MarkerFactory.getMarker("COMPUTER_ERROR.JAVA"); | ||||
| 
 | ||||
|     static { | ||||
|         HTTP_ERROR.add(COMPUTER_ERROR); | ||||
|         JAVA_ERROR.add(JAVA_ERROR); | ||||
|     } | ||||
| 
 | ||||
|     private Logging() { | ||||
|     } | ||||
| } | ||||
| @@ -5,12 +5,13 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.apis; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.filesystem.IMount; | ||||
| import dan200.computercraft.api.filesystem.IWritableMount; | ||||
| import dan200.computercraft.api.peripheral.IComputerAccess; | ||||
| import dan200.computercraft.api.peripheral.IWorkMonitor; | ||||
| import dan200.computercraft.core.filesystem.FileSystemException; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| import java.util.HashSet; | ||||
| @@ -18,6 +19,8 @@ import java.util.Objects; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| public abstract class ComputerAccess implements IComputerAccess { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(ComputerAccess.class); | ||||
| 
 | ||||
|     private final IAPIEnvironment environment; | ||||
|     private final Set<String> mounts = new HashSet<>(); | ||||
| 
 | ||||
| @@ -28,7 +31,7 @@ public abstract class ComputerAccess implements IComputerAccess { | ||||
|     public void unmountAll() { | ||||
|         var fileSystem = environment.getFileSystem(); | ||||
|         if (!mounts.isEmpty()) { | ||||
|             ComputerCraft.log.warn("Peripheral or API called mount but did not call unmount for {}", mounts); | ||||
|             LOG.warn("Peripheral or API called mount but did not call unmount for {}", mounts); | ||||
|         } | ||||
| 
 | ||||
|         for (var mount : mounts) { | ||||
|   | ||||
| @@ -5,11 +5,11 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.apis; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.lua.IArguments; | ||||
| import dan200.computercraft.api.lua.ILuaAPI; | ||||
| import dan200.computercraft.api.lua.LuaException; | ||||
| import dan200.computercraft.api.lua.LuaFunction; | ||||
| import dan200.computercraft.core.CoreConfig; | ||||
| import dan200.computercraft.core.apis.http.*; | ||||
| import dan200.computercraft.core.apis.http.request.HttpRequest; | ||||
| import dan200.computercraft.core.apis.http.websocket.Websocket; | ||||
| @@ -36,8 +36,8 @@ public class HTTPAPI implements ILuaAPI { | ||||
|     private final IAPIEnvironment apiEnvironment; | ||||
| 
 | ||||
|     private final ResourceGroup<CheckUrl> checkUrls = new ResourceGroup<>(ResourceGroup.DEFAULT); | ||||
|     private final ResourceGroup<HttpRequest> requests = new ResourceQueue<>(() -> ComputerCraft.httpMaxRequests); | ||||
|     private final ResourceGroup<Websocket> websockets = new ResourceGroup<>(() -> ComputerCraft.httpMaxWebsockets); | ||||
|     private final ResourceGroup<HttpRequest> requests = new ResourceQueue<>(() -> CoreConfig.httpMaxRequests); | ||||
|     private final ResourceGroup<Websocket> websockets = new ResourceGroup<>(() -> CoreConfig.httpMaxWebsockets); | ||||
| 
 | ||||
|     public HTTPAPI(IAPIEnvironment environment) { | ||||
|         apiEnvironment = environment; | ||||
| @@ -137,7 +137,7 @@ public class HTTPAPI implements ILuaAPI { | ||||
| 
 | ||||
|     @LuaFunction | ||||
|     public final Object[] websocket(String address, Optional<Map<?, ?>> headerTbl) throws LuaException { | ||||
|         if (!ComputerCraft.httpWebsocketEnabled) { | ||||
|         if (!CoreConfig.httpWebsocketEnabled) { | ||||
|             throw new LuaException("Websocket connections are disabled"); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.apis.http; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.core.CoreConfig; | ||||
| import dan200.computercraft.core.apis.http.options.Action; | ||||
| import dan200.computercraft.core.apis.http.options.AddressRule; | ||||
| import dan200.computercraft.core.apis.http.options.Options; | ||||
| @@ -22,6 +22,8 @@ import io.netty.handler.ssl.SslContextBuilder; | ||||
| import io.netty.handler.timeout.ReadTimeoutException; | ||||
| import io.netty.handler.traffic.AbstractTrafficShapingHandler; | ||||
| import io.netty.handler.traffic.GlobalTrafficShapingHandler; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| import javax.net.ssl.SSLException; | ||||
| @@ -37,6 +39,8 @@ import java.util.concurrent.TimeUnit; | ||||
|  * Just a shared object for executing simple HTTP related tasks. | ||||
|  */ | ||||
| public final class NetworkUtils { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(NetworkUtils.class); | ||||
| 
 | ||||
|     public static final ScheduledThreadPoolExecutor EXECUTOR = new ScheduledThreadPoolExecutor( | ||||
|         4, | ||||
|         ThreadUtils.builder("Network") | ||||
| @@ -50,7 +54,7 @@ public final class NetworkUtils { | ||||
|     ); | ||||
| 
 | ||||
|     public static final AbstractTrafficShapingHandler SHAPING_HANDLER = new GlobalTrafficShapingHandler( | ||||
|         EXECUTOR, ComputerCraft.httpUploadBandwidth, ComputerCraft.httpDownloadBandwidth | ||||
|         EXECUTOR, CoreConfig.httpUploadBandwidth, CoreConfig.httpDownloadBandwidth | ||||
|     ); | ||||
| 
 | ||||
|     static { | ||||
| @@ -75,7 +79,7 @@ public final class NetworkUtils { | ||||
|                 tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); | ||||
|                 tmf.init((KeyStore) null); | ||||
|             } catch (Exception e) { | ||||
|                 ComputerCraft.log.error("Cannot setup trust manager", e); | ||||
|                 LOG.error("Cannot setup trust manager", e); | ||||
|             } | ||||
| 
 | ||||
|             return trustManager = tmf; | ||||
| @@ -92,7 +96,7 @@ public final class NetworkUtils { | ||||
|                     .trustManager(getTrustManager()) | ||||
|                     .build(); | ||||
|             } catch (SSLException e) { | ||||
|                 ComputerCraft.log.error("Cannot construct SSL context", e); | ||||
|                 LOG.error("Cannot construct SSL context", e); | ||||
|                 triedSslContext = true; | ||||
|                 sslContext = null; | ||||
| 
 | ||||
| @@ -102,7 +106,7 @@ public final class NetworkUtils { | ||||
|     } | ||||
| 
 | ||||
|     public static void reloadConfig() { | ||||
|         SHAPING_HANDLER.configure(ComputerCraft.httpUploadBandwidth, ComputerCraft.httpDownloadBandwidth); | ||||
|         SHAPING_HANDLER.configure(CoreConfig.httpUploadBandwidth, CoreConfig.httpDownloadBandwidth); | ||||
|     } | ||||
| 
 | ||||
|     public static void reset() { | ||||
| @@ -150,7 +154,7 @@ public final class NetworkUtils { | ||||
|      * @throws HTTPRequestException If the host is not permitted | ||||
|      */ | ||||
|     public static Options getOptions(String host, InetSocketAddress address) throws HTTPRequestException { | ||||
|         var options = AddressRule.apply(ComputerCraft.httpRules, host, address); | ||||
|         var options = AddressRule.apply(CoreConfig.httpRules, host, address); | ||||
|         if (options.action == Action.DENY) throw new HTTPRequestException("Domain not permitted"); | ||||
|         return options; | ||||
|     } | ||||
|   | ||||
| @@ -6,7 +6,8 @@ | ||||
| package dan200.computercraft.core.apis.http.options; | ||||
| 
 | ||||
| import com.google.common.net.InetAddresses; | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import java.net.InetAddress; | ||||
| import java.net.InetSocketAddress; | ||||
| @@ -18,6 +19,8 @@ import java.util.regex.Pattern; | ||||
|  * @see AddressRule#apply(Iterable, String, InetSocketAddress) for the actual handling of this rule. | ||||
|  */ | ||||
| interface AddressPredicate { | ||||
|     Logger LOG = LoggerFactory.getLogger(AddressPredicate.class); | ||||
| 
 | ||||
|     default boolean matches(String domain) { | ||||
|         return false; | ||||
|     } | ||||
| @@ -53,7 +56,7 @@ interface AddressPredicate { | ||||
|             try { | ||||
|                 prefixSize = Integer.parseInt(prefixSizeStr); | ||||
|             } catch (NumberFormatException e) { | ||||
|                 ComputerCraft.log.error( | ||||
|                 LOG.error( | ||||
|                     "Malformed http whitelist/blacklist entry '{}': Cannot extract size of CIDR mask from '{}'.", | ||||
|                     addressStr + '/' + prefixSizeStr, prefixSizeStr | ||||
|                 ); | ||||
| @@ -64,7 +67,7 @@ interface AddressPredicate { | ||||
|             try { | ||||
|                 address = InetAddresses.forString(addressStr); | ||||
|             } catch (IllegalArgumentException e) { | ||||
|                 ComputerCraft.log.error( | ||||
|                 LOG.error( | ||||
|                     "Malformed http whitelist/blacklist entry '{}': Cannot extract IP address from '{}'.", | ||||
|                     addressStr + '/' + prefixSizeStr, prefixSizeStr | ||||
|                 ); | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.apis.http.request; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.core.Logging; | ||||
| import dan200.computercraft.core.apis.IAPIEnvironment; | ||||
| import dan200.computercraft.core.apis.http.HTTPRequestException; | ||||
| import dan200.computercraft.core.apis.http.NetworkUtils; | ||||
| @@ -21,6 +21,8 @@ import io.netty.channel.socket.SocketChannel; | ||||
| import io.netty.channel.socket.nio.NioSocketChannel; | ||||
| import io.netty.handler.codec.http.*; | ||||
| import io.netty.handler.timeout.ReadTimeoutHandler; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import java.net.URI; | ||||
| import java.net.URISyntaxException; | ||||
| @@ -34,6 +36,7 @@ import java.util.concurrent.atomic.AtomicInteger; | ||||
|  * Represents an in-progress HTTP request. | ||||
|  */ | ||||
| public class HttpRequest extends Resource<HttpRequest> { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(HttpRequest.class); | ||||
|     private static final String SUCCESS_EVENT = "http_success"; | ||||
|     private static final String FAILURE_EVENT = "http_failure"; | ||||
| 
 | ||||
| @@ -171,7 +174,7 @@ public class HttpRequest extends Resource<HttpRequest> { | ||||
|             failure(e.getMessage()); | ||||
|         } catch (Exception e) { | ||||
|             failure(NetworkUtils.toFriendlyError(e)); | ||||
|             if (ComputerCraft.logComputerErrors) ComputerCraft.log.error("Error in HTTP request", e); | ||||
|             LOG.error(Logging.HTTP_ERROR, "Error in HTTP request", e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.apis.http.request; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.core.Logging; | ||||
| import dan200.computercraft.core.apis.handles.ArrayByteChannel; | ||||
| import dan200.computercraft.core.apis.handles.BinaryReadableHandle; | ||||
| import dan200.computercraft.core.apis.handles.EncodedReadableHandle; | ||||
| @@ -17,6 +17,8 @@ import io.netty.buffer.CompositeByteBuf; | ||||
| import io.netty.channel.ChannelHandlerContext; | ||||
| import io.netty.channel.SimpleChannelInboundHandler; | ||||
| import io.netty.handler.codec.http.*; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import java.io.Closeable; | ||||
| import java.net.URI; | ||||
| @@ -29,6 +31,8 @@ import java.util.Map; | ||||
| import static dan200.computercraft.core.apis.http.request.HttpRequest.getHeaderSize; | ||||
| 
 | ||||
| public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpObject> implements Closeable { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(HttpRequestHandler.class); | ||||
| 
 | ||||
|     /** | ||||
|      * Same as {@link io.netty.handler.codec.MessageAggregator}. | ||||
|      */ | ||||
| @@ -158,7 +162,7 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpOb | ||||
| 
 | ||||
|     @Override | ||||
|     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { | ||||
|         if (ComputerCraft.logComputerErrors) ComputerCraft.log.error("Error handling HTTP response", cause); | ||||
|         LOG.error(Logging.HTTP_ERROR, "Error handling HTTP response", cause); | ||||
|         request.failure(NetworkUtils.toFriendlyError(cause)); | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| package dan200.computercraft.core.apis.http.websocket; | ||||
| 
 | ||||
| import com.google.common.base.Strings; | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.core.Logging; | ||||
| import dan200.computercraft.core.apis.IAPIEnvironment; | ||||
| import dan200.computercraft.core.apis.http.HTTPRequestException; | ||||
| import dan200.computercraft.core.apis.http.NetworkUtils; | ||||
| @@ -26,6 +26,8 @@ import io.netty.handler.codec.http.HttpHeaders; | ||||
| import io.netty.handler.codec.http.HttpObjectAggregator; | ||||
| import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker; | ||||
| import io.netty.handler.codec.http.websocketx.WebSocketVersion; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import java.lang.ref.WeakReference; | ||||
| import java.net.URI; | ||||
| @@ -36,6 +38,8 @@ import java.util.concurrent.Future; | ||||
|  * Provides functionality to verify and connect to a remote websocket. | ||||
|  */ | ||||
| public class Websocket extends Resource<Websocket> { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(Websocket.class); | ||||
| 
 | ||||
|     /** | ||||
|      * We declare the maximum size to be 2^30 bytes. While messages can be much longer, we set an arbitrary limit as | ||||
|      * working with larger messages (especially within a Lua VM) is absurd. | ||||
| @@ -151,7 +155,7 @@ public class Websocket extends Resource<Websocket> { | ||||
|             failure(e.getMessage()); | ||||
|         } catch (Exception e) { | ||||
|             failure(NetworkUtils.toFriendlyError(e)); | ||||
|             if (ComputerCraft.logComputerErrors) ComputerCraft.log.error("Error in websocket", e); | ||||
|             LOG.error(Logging.HTTP_ERROR, "Error in websocket", e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -10,7 +10,6 @@ import com.google.common.cache.CacheLoader; | ||||
| import com.google.common.cache.LoadingCache; | ||||
| import com.google.common.primitives.Primitives; | ||||
| import com.google.common.reflect.TypeToken; | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.lua.IArguments; | ||||
| import dan200.computercraft.api.lua.LuaException; | ||||
| import dan200.computercraft.api.lua.LuaFunction; | ||||
| @@ -19,6 +18,8 @@ import dan200.computercraft.api.peripheral.PeripheralType; | ||||
| import org.objectweb.asm.ClassWriter; | ||||
| import org.objectweb.asm.MethodVisitor; | ||||
| import org.objectweb.asm.Type; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| import javax.annotation.Nullable; | ||||
| @@ -35,6 +36,8 @@ import java.util.function.Function; | ||||
| import static org.objectweb.asm.Opcodes.*; | ||||
| 
 | ||||
| public final class Generator<T> { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(Generator.class); | ||||
| 
 | ||||
|     private static final AtomicInteger METHOD_ID = new AtomicInteger(); | ||||
| 
 | ||||
|     private static final String METHOD_NAME = "apply"; | ||||
| @@ -79,7 +82,7 @@ public final class Generator<T> { | ||||
|         try { | ||||
|             return classCache.get(klass); | ||||
|         } catch (ExecutionException e) { | ||||
|             ComputerCraft.log.error("Error getting methods for {}.", klass.getName(), e.getCause()); | ||||
|             LOG.error("Error getting methods for {}.", klass.getName(), e.getCause()); | ||||
|             return Collections.emptyList(); | ||||
|         } | ||||
|     } | ||||
| @@ -92,7 +95,7 @@ public final class Generator<T> { | ||||
|             if (annotation == null) continue; | ||||
| 
 | ||||
|             if (Modifier.isStatic(method.getModifiers())) { | ||||
|                 ComputerCraft.log.warn("LuaFunction method {}.{} should be an instance method.", method.getDeclaringClass(), method.getName()); | ||||
|                 LOG.warn("LuaFunction method {}.{} should be an instance method.", method.getDeclaringClass(), method.getName()); | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
| @@ -137,32 +140,32 @@ public final class Generator<T> { | ||||
| 
 | ||||
|         // Instance methods must be final - this prevents them being overridden and potentially exposed twice. | ||||
|         if (!Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) { | ||||
|             ComputerCraft.log.warn("Lua Method {} should be final.", name); | ||||
|             LOG.warn("Lua Method {} should be final.", name); | ||||
|         } | ||||
| 
 | ||||
|         if (!Modifier.isPublic(modifiers)) { | ||||
|             ComputerCraft.log.error("Lua Method {} should be a public method.", name); | ||||
|             LOG.error("Lua Method {} should be a public method.", name); | ||||
|             return Optional.empty(); | ||||
|         } | ||||
| 
 | ||||
|         if (!Modifier.isPublic(method.getDeclaringClass().getModifiers())) { | ||||
|             ComputerCraft.log.error("Lua Method {} should be on a public class.", name); | ||||
|             LOG.error("Lua Method {} should be on a public class.", name); | ||||
|             return Optional.empty(); | ||||
|         } | ||||
| 
 | ||||
|         ComputerCraft.log.debug("Generating method wrapper for {}.", name); | ||||
|         LOG.debug("Generating method wrapper for {}.", name); | ||||
| 
 | ||||
|         var exceptions = method.getExceptionTypes(); | ||||
|         for (var exception : exceptions) { | ||||
|             if (exception != LuaException.class) { | ||||
|                 ComputerCraft.log.error("Lua Method {} cannot throw {}.", name, exception.getName()); | ||||
|                 LOG.error("Lua Method {} cannot throw {}.", name, exception.getName()); | ||||
|                 return Optional.empty(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         var annotation = method.getAnnotation(LuaFunction.class); | ||||
|         if (annotation.unsafe() && annotation.mainThread()) { | ||||
|             ComputerCraft.log.error("Lua Method {} cannot use unsafe and mainThread", name); | ||||
|             LOG.error("Lua Method {} cannot use unsafe and mainThread", name); | ||||
|             return Optional.empty(); | ||||
|         } | ||||
| 
 | ||||
| @@ -180,7 +183,7 @@ public final class Generator<T> { | ||||
|             var instance = klass.asSubclass(base).getDeclaredConstructor().newInstance(); | ||||
|             return Optional.of(annotation.mainThread() ? wrap.apply(instance) : instance); | ||||
|         } catch (ReflectiveOperationException | ClassFormatError | RuntimeException e) { | ||||
|             ComputerCraft.log.error("Error generating wrapper for {}.", name, e); | ||||
|             LOG.error("Error generating wrapper for {}.", name, e); | ||||
|             return Optional.empty(); | ||||
|         } | ||||
| 
 | ||||
| @@ -317,7 +320,7 @@ public final class Generator<T> { | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         ComputerCraft.log.error("Unknown parameter type {} for method {}.{}.", | ||||
|         LOG.error("Unknown parameter type {} for method {}.{}.", | ||||
|             arg.getName(), method.getDeclaringClass().getName(), method.getName()); | ||||
|         return null; | ||||
|     } | ||||
| @@ -330,7 +333,7 @@ public final class Generator<T> { | ||||
|             } catch (Exception | LinkageError e) { | ||||
|                 // LinkageError due to possible codegen bugs and NoClassDefFoundError. The latter occurs when fetching | ||||
|                 // methods on a class which references non-existent (i.e. client-only) types. | ||||
|                 ComputerCraft.log.error("Error generating @LuaFunctions", e); | ||||
|                 LOG.error("Error generating @LuaFunctions", e); | ||||
|                 return def; | ||||
|             } | ||||
|         }; | ||||
|   | ||||
| @@ -5,11 +5,12 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.asm; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.lua.GenericSource; | ||||
| import dan200.computercraft.api.lua.LuaFunction; | ||||
| import dan200.computercraft.api.peripheral.GenericPeripheral; | ||||
| import dan200.computercraft.api.peripheral.PeripheralType; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| import java.lang.reflect.Method; | ||||
| @@ -24,6 +25,8 @@ import java.util.stream.Stream; | ||||
|  * A generic method is a method belonging to a {@link GenericSource} with a known target. | ||||
|  */ | ||||
| public class GenericMethod { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(GenericMethod.class); | ||||
| 
 | ||||
|     final Method method; | ||||
|     final LuaFunction annotation; | ||||
|     final Class<?> target; | ||||
| @@ -53,7 +56,7 @@ public class GenericMethod { | ||||
|         Objects.requireNonNull(source, "Source cannot be null"); | ||||
| 
 | ||||
|         if (cache != null) { | ||||
|             ComputerCraft.log.warn("Registering a generic source {} after cache has been built. This source will be ignored.", cache); | ||||
|             LOG.warn("Registering a generic source {} after cache has been built. This source will be ignored.", cache); | ||||
|         } | ||||
| 
 | ||||
|         sources.add(source); | ||||
| @@ -69,13 +72,13 @@ public class GenericMethod { | ||||
|                 if (annotation == null) return null; | ||||
| 
 | ||||
|                 if (!Modifier.isStatic(method.getModifiers())) { | ||||
|                     ComputerCraft.log.error("GenericSource method {}.{} should be static.", method.getDeclaringClass(), method.getName()); | ||||
|                     LOG.error("GenericSource method {}.{} should be static.", method.getDeclaringClass(), method.getName()); | ||||
|                     return null; | ||||
|                 } | ||||
| 
 | ||||
|                 var types = method.getGenericParameterTypes(); | ||||
|                 if (types.length == 0) { | ||||
|                     ComputerCraft.log.error("GenericSource method {}.{} has no parameters.", method.getDeclaringClass(), method.getName()); | ||||
|                     LOG.error("GenericSource method {}.{} has no parameters.", method.getDeclaringClass(), method.getName()); | ||||
|                     return null; | ||||
|                 } | ||||
| 
 | ||||
|   | ||||
| @@ -5,9 +5,10 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.asm; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.lua.LuaTable; | ||||
| import org.objectweb.asm.MethodVisitor; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import javax.annotation.Nullable; | ||||
| import java.lang.reflect.*; | ||||
| @@ -18,6 +19,7 @@ import java.util.Optional; | ||||
| import static org.objectweb.asm.Opcodes.ICONST_0; | ||||
| 
 | ||||
| final class Reflect { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(Reflect.class); | ||||
|     static final java.lang.reflect.Type OPTIONAL_IN = Optional.class.getTypeParameters()[0]; | ||||
| 
 | ||||
|     private Reflect() { | ||||
| @@ -54,7 +56,7 @@ final class Reflect { | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         ComputerCraft.log.error("Method {}.{} has generic type {} with non-wildcard argument {}.", method.getDeclaringClass(), method.getName(), root, arg); | ||||
|                         LOG.error("Method {}.{} has generic type {} with non-wildcard argument {}.", method.getDeclaringClass(), method.getName(), root, arg); | ||||
|                         return null; | ||||
|                     } | ||||
|                 } | ||||
| @@ -64,7 +66,7 @@ final class Reflect { | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             ComputerCraft.log.error("Method {}.{} has unknown generic type {}.", method.getDeclaringClass(), method.getName(), root); | ||||
|             LOG.error("Method {}.{} has unknown generic type {}.", method.getDeclaringClass(), method.getName(), root); | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -5,11 +5,11 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.computer; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.filesystem.IMount; | ||||
| import dan200.computercraft.api.filesystem.IWritableMount; | ||||
| import dan200.computercraft.api.lua.ILuaAPI; | ||||
| import dan200.computercraft.core.ComputerContext; | ||||
| import dan200.computercraft.core.CoreConfig; | ||||
| import dan200.computercraft.core.apis.*; | ||||
| import dan200.computercraft.core.filesystem.FileSystem; | ||||
| import dan200.computercraft.core.filesystem.FileSystemException; | ||||
| @@ -19,6 +19,8 @@ import dan200.computercraft.core.metrics.Metrics; | ||||
| import dan200.computercraft.core.metrics.MetricsObserver; | ||||
| import dan200.computercraft.shared.util.Colour; | ||||
| import dan200.computercraft.shared.util.IoUtil; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| import javax.annotation.Nullable; | ||||
| @@ -51,6 +53,7 @@ import java.util.concurrent.locks.ReentrantLock; | ||||
|  * method. This should only be called when the computer is actually on ({@link #isOn}). | ||||
|  */ | ||||
| final class ComputerExecutor { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(ComputerExecutor.class); | ||||
|     private static final int QUEUE_LIMIT = 256; | ||||
| 
 | ||||
|     private final Computer computer; | ||||
| @@ -175,7 +178,7 @@ final class ComputerExecutor { | ||||
|         apis.add(new FSAPI(environment)); | ||||
|         apis.add(new PeripheralAPI(environment)); | ||||
|         apis.add(new OSAPI(environment)); | ||||
|         if (ComputerCraft.httpEnabled) apis.add(new HTTPAPI(environment)); | ||||
|         if (CoreConfig.httpEnabled) apis.add(new HTTPAPI(environment)); | ||||
| 
 | ||||
|         // Load in the externally registered APIs. | ||||
|         for (var factory : ApiFactories.getAll()) { | ||||
| @@ -341,7 +344,7 @@ final class ComputerExecutor { | ||||
|             return filesystem; | ||||
|         } catch (FileSystemException e) { | ||||
|             if (filesystem != null) filesystem.close(); | ||||
|             ComputerCraft.log.error("Cannot mount computer filesystem", e); | ||||
|             LOG.error("Cannot mount computer filesystem", e); | ||||
| 
 | ||||
|             displayFailure("Cannot mount computer system", null); | ||||
|             return null; | ||||
|   | ||||
| @@ -7,9 +7,11 @@ package dan200.computercraft.core.computer; | ||||
| 
 | ||||
| import com.google.common.annotations.VisibleForTesting; | ||||
| import com.google.errorprone.annotations.concurrent.GuardedBy; | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.core.ComputerContext; | ||||
| import dan200.computercraft.core.Logging; | ||||
| import dan200.computercraft.shared.util.ThreadUtils; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| import javax.annotation.Nullable; | ||||
| @@ -52,6 +54,7 @@ import java.util.concurrent.locks.ReentrantLock; | ||||
|  * @see ComputerExecutor For how computers actually do execution. | ||||
|  */ | ||||
| public final class ComputerThread { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(ComputerThread.class); | ||||
|     private static final ThreadFactory monitorFactory = ThreadUtils.factory("Computer-Monitor"); | ||||
|     private static final ThreadFactory workerFactory = ThreadUtils.factory("Computer-Worker"); | ||||
| 
 | ||||
| @@ -160,7 +163,7 @@ public final class ComputerThread { | ||||
| 
 | ||||
|     @GuardedBy("threadLock") | ||||
|     private void addWorker(int index) { | ||||
|         ComputerCraft.log.trace("Spawning new worker {}.", index); | ||||
|         LOG.trace("Spawning new worker {}.", index); | ||||
|         (workers[index] = new Worker(index)).owner.start(); | ||||
|         workerCount++; | ||||
|     } | ||||
| @@ -176,7 +179,7 @@ public final class ComputerThread { | ||||
| 
 | ||||
|         threadLock.lock(); | ||||
|         try { | ||||
|             ComputerCraft.log.trace("Possibly spawning a worker or monitor."); | ||||
|             LOG.trace("Possibly spawning a worker or monitor."); | ||||
| 
 | ||||
|             if (monitor == null || !monitor.isAlive()) (monitor = monitorFactory.newThread(new Monitor())).start(); | ||||
|             if (idleWorkers.get() == 0 || workerCount < workers.length) { | ||||
| @@ -355,7 +358,7 @@ public final class ComputerThread { | ||||
|         var currentThread = executor.executingThread.getAndSet(null); | ||||
|         if (currentThread != runner.owner) { | ||||
| 
 | ||||
|             ComputerCraft.log.error( | ||||
|             LOG.error( | ||||
|                 "Expected computer #{} to be running on {}, but already running on {}. This is a SERIOUS bug, please report with your debug.log.", | ||||
|                 executor.getComputer().getID(), | ||||
|                 runner.owner.getName(), | ||||
| @@ -422,7 +425,7 @@ public final class ComputerThread { | ||||
|         // worker finishes normally. | ||||
|         if (!worker.running.getAndSet(false)) return; | ||||
| 
 | ||||
|         ComputerCraft.log.trace("Worker {} finished.", worker.index); | ||||
|         LOG.trace("Worker {} finished.", worker.index); | ||||
| 
 | ||||
|         var executor = worker.currentExecutor.getAndSet(null); | ||||
|         if (executor != null) executor.afterWork(); | ||||
| @@ -432,7 +435,7 @@ public final class ComputerThread { | ||||
|             workerCount--; | ||||
| 
 | ||||
|             if (workers[worker.index] != worker) { | ||||
|                 ComputerCraft.log.error("Worker {} closed, but new runner has been spawned.", worker.index); | ||||
|                 LOG.error("Worker {} closed, but new runner has been spawned.", worker.index); | ||||
|             } else if (state.get() == RUNNING || (state.get() == STOPPING && hasPendingWork())) { | ||||
|                 addWorker(worker.index); | ||||
|                 workerCount++; | ||||
| @@ -453,11 +456,11 @@ public final class ComputerThread { | ||||
|     private final class Monitor implements Runnable { | ||||
|         @Override | ||||
|         public void run() { | ||||
|             ComputerCraft.log.trace("Monitor starting."); | ||||
|             LOG.trace("Monitor starting."); | ||||
|             try { | ||||
|                 runImpl(); | ||||
|             } finally { | ||||
|                 ComputerCraft.log.trace("Monitor shutting down. Current state is {}.", state.get()); | ||||
|                 LOG.trace("Monitor shutting down. Current state is {}.", state.get()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @@ -470,7 +473,7 @@ public final class ComputerThread { | ||||
|                     // flags, which are far less granular. | ||||
|                     monitorWakeup.awaitNanos(isBusy() ? scaledPeriod() : MONITOR_WAKEUP); | ||||
|                 } catch (InterruptedException e) { | ||||
|                     ComputerCraft.log.error("Monitor thread interrupted. Computers may behave very badly!", e); | ||||
|                     LOG.error("Monitor thread interrupted. Computers may behave very badly!", e); | ||||
|                     break; | ||||
|                 } finally { | ||||
|                     computerLock.unlock(); | ||||
| @@ -592,7 +595,7 @@ public final class ComputerThread { | ||||
|                 while (!executor.executingThread.compareAndSet(null, owner)) { | ||||
|                     var existing = executor.executingThread.get(); | ||||
|                     if (existing != null) { | ||||
|                         ComputerCraft.log.error( | ||||
|                         LOG.error( | ||||
|                             "Trying to run computer #{} on thread {}, but already running on {}. This is a SERIOUS bug, please report with your debug.log.", | ||||
|                             executor.getComputer().getID(), owner.getName(), existing.getName() | ||||
|                         ); | ||||
| @@ -614,7 +617,7 @@ public final class ComputerThread { | ||||
|                 try { | ||||
|                     executor.work(); | ||||
|                 } catch (Exception | LinkageError | VirtualMachineError e) { | ||||
|                     ComputerCraft.log.error("Error running task on computer #" + executor.getComputer().getID(), e); | ||||
|                     LOG.error("Error running task on computer #" + executor.getComputer().getID(), e); | ||||
|                     // Tear down the computer immediately. There's no guarantee it's well-behaved from now on. | ||||
|                     executor.fastFail(); | ||||
|                 } finally { | ||||
| @@ -625,7 +628,7 @@ public final class ComputerThread { | ||||
|         } | ||||
| 
 | ||||
|         private void reportTimeout(ComputerExecutor executor, long time) { | ||||
|             if (!ComputerCraft.logComputerErrors) return; | ||||
|             if (!LOG.isErrorEnabled(Logging.COMPUTER_ERROR)) return; | ||||
| 
 | ||||
|             // Attempt to debounce stack trace reporting, limiting ourselves to one every second. There's no need to be | ||||
|             // ultra-precise in our atomics, as long as one of them wins! | ||||
| @@ -654,7 +657,7 @@ public final class ComputerThread { | ||||
| 
 | ||||
|             executor.printState(builder); | ||||
| 
 | ||||
|             ComputerCraft.log.warn(builder.toString()); | ||||
|             LOG.warn(builder.toString()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,14 +5,17 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.computer; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.lua.ILuaContext; | ||||
| import dan200.computercraft.api.lua.ILuaTask; | ||||
| import dan200.computercraft.api.lua.LuaException; | ||||
| import dan200.computercraft.core.Logging; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| 
 | ||||
| class LuaContext implements ILuaContext { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(LuaContext.class); | ||||
|     private final Computer computer; | ||||
| 
 | ||||
|     LuaContext(Computer computer) { | ||||
| @@ -38,7 +41,7 @@ class LuaContext implements ILuaContext { | ||||
|             } catch (LuaException e) { | ||||
|                 computer.queueEvent("task_complete", new Object[]{ taskID, false, e.getMessage() }); | ||||
|             } catch (Exception t) { | ||||
|                 if (ComputerCraft.logComputerErrors) ComputerCraft.log.error("Error running task", t); | ||||
|                 LOG.error(Logging.JAVA_ERROR, "Error running task", t); | ||||
|                 computer.queueEvent("task_complete", new Object[]{ | ||||
|                     taskID, false, "Java Exception Thrown: " + t, | ||||
|                 }); | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.computer.mainthread; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.core.CoreConfig; | ||||
| import dan200.computercraft.core.metrics.MetricsObserver; | ||||
| 
 | ||||
| import java.util.HashSet; | ||||
| @@ -21,7 +21,7 @@ import java.util.TreeSet; | ||||
|  * {@link MainThread} starts cool, and runs as many tasks as it can in the current {@link #budget}ns. Any external tasks | ||||
|  * (those run by tile entities, etc...) will also consume the budget | ||||
|  * <p> | ||||
|  * Next tick, we add {@link ComputerCraft#maxMainGlobalTime} to our budget (clamp it to that value too). If we're still | ||||
|  * Next tick, we add {@link CoreConfig#maxMainGlobalTime} to our budget (clamp it to that value too). If we're still | ||||
|  * over budget, then we should not execute <em>any</em> work (either as part of {@link MainThread} or externally). | ||||
|  */ | ||||
| public final class MainThread implements MainThreadScheduler { | ||||
| @@ -80,7 +80,7 @@ public final class MainThread implements MainThreadScheduler { | ||||
|             var newRuntime = minimumTime; | ||||
| 
 | ||||
|             // Slow down new computers a little bit. | ||||
|             if (executor.virtualTime == 0) newRuntime += ComputerCraft.maxMainComputerTime; | ||||
|             if (executor.virtualTime == 0) newRuntime += CoreConfig.maxMainComputerTime; | ||||
| 
 | ||||
|             executor.virtualTime = Math.max(newRuntime, executor.virtualTime); | ||||
| 
 | ||||
| @@ -111,7 +111,7 @@ public final class MainThread implements MainThreadScheduler { | ||||
|         // Of course, we'll go over the MAX_TICK_TIME most of the time, but eventually that overrun will accumulate | ||||
|         // and we'll skip a whole tick - bringing the average back down again. | ||||
|         currentTick++; | ||||
|         budget = Math.min(budget + ComputerCraft.maxMainGlobalTime, ComputerCraft.maxMainGlobalTime); | ||||
|         budget = Math.min(budget + CoreConfig.maxMainGlobalTime, CoreConfig.maxMainGlobalTime); | ||||
|         canExecute = budget > 0; | ||||
| 
 | ||||
|         // Cool down any warm computers. | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.computer.mainthread; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.peripheral.IWorkMonitor; | ||||
| import dan200.computercraft.core.CoreConfig; | ||||
| import dan200.computercraft.core.computer.Computer; | ||||
| import dan200.computercraft.core.metrics.Metrics; | ||||
| import dan200.computercraft.core.metrics.MetricsObserver; | ||||
| @@ -23,7 +23,7 @@ import java.util.concurrent.TimeUnit; | ||||
|  * those run elsewhere (such as during the turtle's tick). In order to handle this, the executor goes through three | ||||
|  * stages: | ||||
|  * <p> | ||||
|  * When {@link State#COOL}, the computer is allocated {@link ComputerCraft#maxMainComputerTime}ns to execute any work | ||||
|  * When {@link State#COOL}, the computer is allocated {@link CoreConfig#maxMainComputerTime}ns to execute any work | ||||
|  * this tick. At the beginning of the tick, we execute as many {@link MainThread} tasks as possible, until our | ||||
|  * time-frame or the global time frame has expired. | ||||
|  * <p> | ||||
| @@ -34,13 +34,13 @@ import java.util.concurrent.TimeUnit; | ||||
|  * {@link State#HOT}. This means it will no longer be able to execute {@link MainThread} tasks (though will still | ||||
|  * execute tile entity tasks, in order to prevent the main thread from exhausting work every tick). | ||||
|  * <p> | ||||
|  * At the beginning of the next tick, we increment the budget e by {@link ComputerCraft#maxMainComputerTime} and any | ||||
|  * At the beginning of the next tick, we increment the budget e by {@link CoreConfig#maxMainComputerTime} and any | ||||
|  * {@link State#HOT} executors are marked as {@link State#COOLING}. They will remain cooling until their budget is fully | ||||
|  * replenished (is equal to {@link ComputerCraft#maxMainComputerTime}). Note, this is different to {@link MainThread}, | ||||
|  * replenished (is equal to {@link CoreConfig#maxMainComputerTime}). Note, this is different to {@link MainThread}, | ||||
|  * which allows running when it has any budget left. When cooling, <em>no</em> tasks are executed - be they on the tile | ||||
|  * entity or main thread. | ||||
|  * <p> | ||||
|  * This mechanism means that, on average, computers will use at most {@link ComputerCraft#maxMainComputerTime}ns per | ||||
|  * This mechanism means that, on average, computers will use at most {@link CoreConfig#maxMainComputerTime}ns per | ||||
|  * second, but one task source will not prevent others from executing. | ||||
|  * | ||||
|  * @see MainThread | ||||
| @@ -190,7 +190,7 @@ final class MainThreadExecutor implements MainThreadScheduler.Executor { | ||||
|         // #tickCooling() isn't called, and so we didn't overrun the previous tick. | ||||
|         if (currentTick != scheduler.currentTick()) { | ||||
|             currentTick = scheduler.currentTick(); | ||||
|             budget = ComputerCraft.maxMainComputerTime; | ||||
|             budget = CoreConfig.maxMainComputerTime; | ||||
|         } | ||||
| 
 | ||||
|         budget -= time; | ||||
| @@ -203,15 +203,15 @@ final class MainThreadExecutor implements MainThreadScheduler.Executor { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Move this executor forward one tick, replenishing the budget by {@link ComputerCraft#maxMainComputerTime}. | ||||
|      * Move this executor forward one tick, replenishing the budget by {@link CoreConfig#maxMainComputerTime}. | ||||
|      * | ||||
|      * @return Whether this executor has cooled down, and so is safe to run again. | ||||
|      */ | ||||
|     boolean tickCooling() { | ||||
|         state = State.COOLING; | ||||
|         currentTick = scheduler.currentTick(); | ||||
|         budget = Math.min(budget + ComputerCraft.maxMainComputerTime, ComputerCraft.maxMainComputerTime); | ||||
|         if (budget < ComputerCraft.maxMainComputerTime) return false; | ||||
|         budget = Math.min(budget + CoreConfig.maxMainComputerTime, CoreConfig.maxMainComputerTime); | ||||
|         if (budget < CoreConfig.maxMainComputerTime) return false; | ||||
| 
 | ||||
|         state = State.COOL; | ||||
|         synchronized (queueLock) { | ||||
|   | ||||
| @@ -6,9 +6,10 @@ | ||||
| package dan200.computercraft.core.filesystem; | ||||
| 
 | ||||
| import com.google.common.collect.Sets; | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.filesystem.FileOperationException; | ||||
| import dan200.computercraft.api.filesystem.IWritableMount; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| import java.io.File; | ||||
| @@ -23,6 +24,7 @@ import java.util.OptionalLong; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| public class FileMount implements IWritableMount { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(FileMount.class); | ||||
|     private static final int MINIMUM_FILE_SIZE = 500; | ||||
|     private static final Set<OpenOption> READ_OPTIONS = Collections.singleton(StandardOpenOption.READ); | ||||
|     private static final Set<OpenOption> WRITE_OPTIONS = Sets.newHashSet(StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); | ||||
| @@ -330,7 +332,7 @@ public class FileMount implements IWritableMount { | ||||
| 
 | ||||
|         @Override | ||||
|         public FileVisitResult visitFileFailed(Path file, IOException exc) { | ||||
|             ComputerCraft.log.error("Error computing file size for {}", file, exc); | ||||
|             LOG.error("Error computing file size for {}", file, exc); | ||||
|             return FileVisitResult.CONTINUE; | ||||
|         } | ||||
|     } | ||||
| @@ -343,7 +345,7 @@ public class FileMount implements IWritableMount { | ||||
|             Files.walkFileTree(file.toPath(), visitor); | ||||
|             return visitor.size; | ||||
|         } catch (IOException e) { | ||||
|             ComputerCraft.log.error("Error computing file size for {}", file, e); | ||||
|             LOG.error("Error computing file size for {}", file, e); | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -6,10 +6,10 @@ | ||||
| package dan200.computercraft.core.filesystem; | ||||
| 
 | ||||
| import com.google.common.io.ByteStreams; | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.filesystem.IFileSystem; | ||||
| import dan200.computercraft.api.filesystem.IMount; | ||||
| import dan200.computercraft.api.filesystem.IWritableMount; | ||||
| import dan200.computercraft.core.CoreConfig; | ||||
| import dan200.computercraft.shared.util.IoUtil; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| @@ -329,8 +329,8 @@ public class FileSystem { | ||||
| 
 | ||||
|     private synchronized <T extends Closeable> FileSystemWrapper<T> openFile(@Nonnull MountWrapper mount, @Nonnull Channel channel, @Nonnull T file) throws FileSystemException { | ||||
|         synchronized (openFiles) { | ||||
|             if (ComputerCraft.maximumFilesOpen > 0 && | ||||
|                 openFiles.size() >= ComputerCraft.maximumFilesOpen) { | ||||
|             if (CoreConfig.maximumFilesOpen > 0 && | ||||
|                 openFiles.size() >= CoreConfig.maximumFilesOpen) { | ||||
|                 IoUtil.closeQuietly(file); | ||||
|                 IoUtil.closeQuietly(channel); | ||||
|                 throw new FileSystemException("Too many files already open"); | ||||
|   | ||||
| @@ -5,11 +5,13 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.lua; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.lua.ILuaContext; | ||||
| import dan200.computercraft.api.lua.LuaException; | ||||
| import dan200.computercraft.api.lua.MethodResult; | ||||
| import dan200.computercraft.core.Logging; | ||||
| import dan200.computercraft.core.asm.LuaMethod; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.squiddev.cobalt.LuaError; | ||||
| import org.squiddev.cobalt.LuaState; | ||||
| import org.squiddev.cobalt.Varargs; | ||||
| @@ -21,6 +23,7 @@ import org.squiddev.cobalt.function.VarArgFunction; | ||||
|  * As we never yield, we do not need to push a function to the stack, which removes a small amount of overhead. | ||||
|  */ | ||||
| class BasicFunction extends VarArgFunction { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(BasicFunction.class); | ||||
|     private final CobaltLuaMachine machine; | ||||
|     private final LuaMethod method; | ||||
|     private final Object instance; | ||||
| @@ -44,9 +47,7 @@ class BasicFunction extends VarArgFunction { | ||||
|         } catch (LuaException e) { | ||||
|             throw wrap(e); | ||||
|         } catch (Throwable t) { | ||||
|             if (ComputerCraft.logComputerErrors) { | ||||
|                 ComputerCraft.log.error("Error calling " + name + " on " + instance, t); | ||||
|             } | ||||
|             LOG.error(Logging.JAVA_ERROR, "Error calling {} on {}", name, instance, t); | ||||
|             throw new LuaError("Java Exception Thrown: " + t, 0); | ||||
|         } finally { | ||||
|             arguments.close(); | ||||
|   | ||||
| @@ -5,16 +5,19 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.lua; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.lua.IDynamicLuaObject; | ||||
| import dan200.computercraft.api.lua.ILuaAPI; | ||||
| import dan200.computercraft.api.lua.ILuaContext; | ||||
| import dan200.computercraft.api.lua.ILuaFunction; | ||||
| import dan200.computercraft.core.CoreConfig; | ||||
| import dan200.computercraft.core.Logging; | ||||
| import dan200.computercraft.core.asm.LuaMethod; | ||||
| import dan200.computercraft.core.asm.ObjectSource; | ||||
| import dan200.computercraft.core.computer.TimeoutState; | ||||
| import dan200.computercraft.core.metrics.Metrics; | ||||
| import dan200.computercraft.shared.util.ThreadUtils; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.squiddev.cobalt.*; | ||||
| import org.squiddev.cobalt.compiler.CompileException; | ||||
| import org.squiddev.cobalt.compiler.LoadState; | ||||
| @@ -39,6 +42,8 @@ import static org.squiddev.cobalt.debug.DebugFrame.FLAG_HOOKED; | ||||
| import static org.squiddev.cobalt.debug.DebugFrame.FLAG_HOOKYIELD; | ||||
| 
 | ||||
| public class CobaltLuaMachine implements ILuaMachine { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(CobaltLuaMachine.class); | ||||
| 
 | ||||
|     private static final ThreadPoolExecutor COROUTINES = new ThreadPoolExecutor( | ||||
|         0, Integer.MAX_VALUE, | ||||
|         5L, TimeUnit.MINUTES, | ||||
| @@ -102,8 +107,8 @@ public class CobaltLuaMachine implements ILuaMachine { | ||||
|         // Add version globals | ||||
|         globals.rawset("_VERSION", valueOf("Lua 5.1")); | ||||
|         globals.rawset("_HOST", valueOf(environment.hostString())); | ||||
|         globals.rawset("_CC_DEFAULT_SETTINGS", valueOf(ComputerCraft.defaultComputerSettings)); | ||||
|         if (ComputerCraft.disableLua51Features) { | ||||
|         globals.rawset("_CC_DEFAULT_SETTINGS", valueOf(CoreConfig.defaultComputerSettings)); | ||||
|         if (CoreConfig.disableLua51Features) { | ||||
|             globals.rawset("_CC_DISABLE_LUA51_FEATURES", Constants.TRUE); | ||||
|         } | ||||
|     } | ||||
| @@ -113,7 +118,7 @@ public class CobaltLuaMachine implements ILuaMachine { | ||||
|         // Add the methods of an API to the global table | ||||
|         var table = wrapLuaObject(api); | ||||
|         if (table == null) { | ||||
|             ComputerCraft.log.warn("API {} does not provide any methods", api); | ||||
|             LOG.warn("API {} does not provide any methods", api); | ||||
|             table = new LuaTable(); | ||||
|         } | ||||
| 
 | ||||
| @@ -134,7 +139,7 @@ public class CobaltLuaMachine implements ILuaMachine { | ||||
|             close(); | ||||
|             return MachineResult.error(e); | ||||
|         } catch (Exception e) { | ||||
|             ComputerCraft.log.warn("Could not load bios.lua", e); | ||||
|             LOG.warn("Could not load bios.lua", e); | ||||
|             close(); | ||||
|             return MachineResult.GENERIC_ERROR; | ||||
|         } | ||||
| @@ -180,7 +185,7 @@ public class CobaltLuaMachine implements ILuaMachine { | ||||
|             return MachineResult.TIMEOUT; | ||||
|         } catch (LuaError e) { | ||||
|             close(); | ||||
|             ComputerCraft.log.warn("Top level coroutine errored", e); | ||||
|             LOG.warn("Top level coroutine errored", e); | ||||
|             return MachineResult.error(e); | ||||
|         } | ||||
|     } | ||||
| @@ -294,9 +299,7 @@ public class CobaltLuaMachine implements ILuaMachine { | ||||
|             return wrapped; | ||||
|         } | ||||
| 
 | ||||
|         if (ComputerCraft.logComputerErrors) { | ||||
|             ComputerCraft.log.warn("Received unknown type '{}', returning nil.", object.getClass().getName()); | ||||
|         } | ||||
|         LOG.warn(Logging.JAVA_ERROR, "Received unknown type '{}', returning nil.", object.getClass().getName()); | ||||
|         return Constants.NIL; | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -21,6 +21,10 @@ import dan200.computercraft.core.metrics.MetricsObserver; | ||||
|  * @param hostString A {@linkplain GlobalEnvironment#getHostString() host string} to identify the current environment. | ||||
|  * @see ILuaMachine.Factory | ||||
|  */ | ||||
| public record MachineEnvironment(ILuaContext context, MetricsObserver metrics, TimeoutState timeout, | ||||
|                                  String hostString) { | ||||
| public record MachineEnvironment( | ||||
|     ILuaContext context, | ||||
|     MetricsObserver metrics, | ||||
|     TimeoutState timeout, | ||||
|     String hostString | ||||
| ) { | ||||
| } | ||||
|   | ||||
| @@ -5,12 +5,14 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.lua; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.lua.ILuaCallback; | ||||
| import dan200.computercraft.api.lua.ILuaContext; | ||||
| import dan200.computercraft.api.lua.LuaException; | ||||
| import dan200.computercraft.api.lua.MethodResult; | ||||
| import dan200.computercraft.core.Logging; | ||||
| import dan200.computercraft.core.asm.LuaMethod; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.squiddev.cobalt.*; | ||||
| import org.squiddev.cobalt.debug.DebugFrame; | ||||
| import org.squiddev.cobalt.function.ResumableVarArgFunction; | ||||
| @@ -22,6 +24,8 @@ import javax.annotation.Nonnull; | ||||
|  * and resuming the supplied continuation. | ||||
|  */ | ||||
| class ResultInterpreterFunction extends ResumableVarArgFunction<ResultInterpreterFunction.Container> { | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(ResultInterpreterFunction.class); | ||||
| 
 | ||||
|     @Nonnull | ||||
|     static class Container { | ||||
|         ILuaCallback callback; | ||||
| @@ -56,9 +60,7 @@ class ResultInterpreterFunction extends ResumableVarArgFunction<ResultInterprete | ||||
|         } catch (LuaException e) { | ||||
|             throw wrap(e, 0); | ||||
|         } catch (Throwable t) { | ||||
|             if (ComputerCraft.logComputerErrors) { | ||||
|                 ComputerCraft.log.error("Error calling " + name + " on " + instance, t); | ||||
|             } | ||||
|             LOG.error(Logging.JAVA_ERROR, "Error calling {} on {}", name, instance, t); | ||||
|             throw new LuaError("Java Exception Thrown: " + t, 0); | ||||
|         } finally { | ||||
|             arguments.close(); | ||||
| @@ -82,9 +84,7 @@ class ResultInterpreterFunction extends ResumableVarArgFunction<ResultInterprete | ||||
|         } catch (LuaException e) { | ||||
|             throw wrap(e, container.errorAdjust); | ||||
|         } catch (Throwable t) { | ||||
|             if (ComputerCraft.logComputerErrors) { | ||||
|                 ComputerCraft.log.error("Error calling " + name + " on " + container.callback, t); | ||||
|             } | ||||
|             LOG.error(Logging.JAVA_ERROR, "Error calling {} on {}", name, container.callback, t); | ||||
|             throw new LuaError("Java Exception Thrown: " + t, 0); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -3,12 +3,15 @@ | ||||
|  * Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission. | ||||
|  * Send enquiries to dratcliffe@gmail.com | ||||
|  */ | ||||
| package dan200.computercraft.core.apis.http.options; | ||||
| package dan200.computercraft.shared; | ||||
| 
 | ||||
| import com.electronwill.nightconfig.core.Config; | ||||
| import com.electronwill.nightconfig.core.InMemoryCommentedFormat; | ||||
| import com.electronwill.nightconfig.core.UnmodifiableConfig; | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.core.apis.http.options.Action; | ||||
| import dan200.computercraft.core.apis.http.options.AddressRule; | ||||
| import dan200.computercraft.core.apis.http.options.PartialOptions; | ||||
| 
 | ||||
| import javax.annotation.Nullable; | ||||
| import java.util.Locale; | ||||
| @@ -7,9 +7,10 @@ package dan200.computercraft.shared; | ||||
| 
 | ||||
| import com.electronwill.nightconfig.core.UnmodifiableConfig; | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.core.CoreConfig; | ||||
| import dan200.computercraft.core.Logging; | ||||
| import dan200.computercraft.core.apis.http.NetworkUtils; | ||||
| import dan200.computercraft.core.apis.http.options.Action; | ||||
| import dan200.computercraft.core.apis.http.options.AddressRuleConfig; | ||||
| import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer; | ||||
| import net.minecraftforge.common.ForgeConfigSpec; | ||||
| import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; | ||||
| @@ -18,6 +19,9 @@ import net.minecraftforge.fml.ModLoadingContext; | ||||
| import net.minecraftforge.fml.common.Mod; | ||||
| import net.minecraftforge.fml.config.ModConfig; | ||||
| import net.minecraftforge.fml.event.config.ModConfigEvent; | ||||
| import org.apache.logging.log4j.core.Filter; | ||||
| import org.apache.logging.log4j.core.LoggerContext; | ||||
| import org.apache.logging.log4j.core.filter.MarkerFilter; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| @@ -82,10 +86,14 @@ public final class Config { | ||||
|     private static final ForgeConfigSpec serverSpec; | ||||
|     private static final ForgeConfigSpec clientSpec; | ||||
| 
 | ||||
|     private static MarkerFilter logFilter = MarkerFilter.createFilter(Logging.COMPUTER_ERROR.getName(), Filter.Result.ACCEPT, Filter.Result.NEUTRAL); | ||||
| 
 | ||||
|     private Config() { | ||||
|     } | ||||
| 
 | ||||
|     static { | ||||
|         LoggerContext.getContext().addFilter(logFilter); | ||||
| 
 | ||||
|         var builder = new ForgeConfigSpec.Builder(); | ||||
| 
 | ||||
|         { // General computers | ||||
| @@ -102,27 +110,27 @@ public final class Config { | ||||
|             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); | ||||
|                 .defineInRange("maximum_open_files", CoreConfig.maximumFilesOpen, 0, Integer.MAX_VALUE); | ||||
| 
 | ||||
|             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.disableLua51Features); | ||||
|                 .define("disable_lua51_features", CoreConfig.disableLua51Features); | ||||
| 
 | ||||
|             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.defaultComputerSettings); | ||||
|                 .define("default_computer_settings", CoreConfig.defaultComputerSettings); | ||||
| 
 | ||||
|             logComputerErrors = builder | ||||
|                 .comment(""" | ||||
|                     Log exceptions thrown by peripherals and other Lua objects. 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.logComputerErrors); | ||||
|                 .define("log_computer_errors", true); | ||||
| 
 | ||||
|             commandRequireCreative = builder | ||||
|                 .comment(""" | ||||
| @@ -151,14 +159,14 @@ public final class Config { | ||||
|                     milliseconds. | ||||
|                     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", (int) TimeUnit.NANOSECONDS.toMillis(ComputerCraft.maxMainGlobalTime), 1, Integer.MAX_VALUE); | ||||
|                 .defineInRange("max_main_global_time", (int) TimeUnit.NANOSECONDS.toMillis(CoreConfig.maxMainGlobalTime), 1, Integer.MAX_VALUE); | ||||
| 
 | ||||
|             maxMainComputerTime = builder | ||||
|                 .comment(""" | ||||
|                     The ideal maximum time a computer can execute for in a tick, in milliseconds. | ||||
|                     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", (int) TimeUnit.NANOSECONDS.toMillis(ComputerCraft.maxMainComputerTime), 1, Integer.MAX_VALUE); | ||||
|                 .defineInRange("max_main_computer_time", (int) TimeUnit.NANOSECONDS.toMillis(CoreConfig.maxMainComputerTime), 1, Integer.MAX_VALUE); | ||||
| 
 | ||||
|             builder.pop(); | ||||
|         } | ||||
| @@ -172,11 +180,11 @@ public final class Config { | ||||
|                     Enable the "http" API on Computers. This also disables the "pastebin" and "wget" | ||||
|                     programs, that many users rely on. It's recommended to leave this on and use the | ||||
|                     "rules" config option to impose more fine-grained control.""") | ||||
|                 .define("enabled", ComputerCraft.httpEnabled); | ||||
|                 .define("enabled", CoreConfig.httpEnabled); | ||||
| 
 | ||||
|             httpWebsocketEnabled = builder | ||||
|                 .comment("Enable use of http websockets. This requires the \"http_enable\" option to also be true.") | ||||
|                 .define("websocket_enabled", ComputerCraft.httpWebsocketEnabled); | ||||
|                 .define("websocket_enabled", CoreConfig.httpWebsocketEnabled); | ||||
| 
 | ||||
|             httpRules = builder | ||||
|                 .comment(""" | ||||
| @@ -197,11 +205,11 @@ public final class Config { | ||||
|                     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); | ||||
|                 .defineInRange("max_requests", CoreConfig.httpMaxRequests, 0, Integer.MAX_VALUE); | ||||
| 
 | ||||
|             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); | ||||
|                 .defineInRange("max_websockets", CoreConfig.httpMaxWebsockets, 1, Integer.MAX_VALUE); | ||||
| 
 | ||||
|             builder | ||||
|                 .comment("Limits bandwidth used by computers.") | ||||
| @@ -209,11 +217,11 @@ public final class Config { | ||||
| 
 | ||||
|             httpDownloadBandwidth = builder | ||||
|                 .comment("The number of bytes which can be downloaded in a second. This is shared across all computers. (bytes/s).") | ||||
|                 .defineInRange("global_download", ComputerCraft.httpDownloadBandwidth, 1, Integer.MAX_VALUE); | ||||
|                 .defineInRange("global_download", CoreConfig.httpDownloadBandwidth, 1, Integer.MAX_VALUE); | ||||
| 
 | ||||
|             httpUploadBandwidth = builder | ||||
|                 .comment("The number of bytes which can be uploaded in a second. This is shared across all computers. (bytes/s).") | ||||
|                 .defineInRange("global_upload", ComputerCraft.httpUploadBandwidth, 1, Integer.MAX_VALUE); | ||||
|                 .defineInRange("global_upload", CoreConfig.httpUploadBandwidth, 1, Integer.MAX_VALUE); | ||||
| 
 | ||||
|             builder.pop(); | ||||
| 
 | ||||
| @@ -349,28 +357,38 @@ public final class Config { | ||||
|         // General | ||||
|         ComputerCraft.computerSpaceLimit = computerSpaceLimit.get(); | ||||
|         ComputerCraft.floppySpaceLimit = floppySpaceLimit.get(); | ||||
|         ComputerCraft.maximumFilesOpen = maximumFilesOpen.get(); | ||||
|         ComputerCraft.disableLua51Features = disableLua51Features.get(); | ||||
|         ComputerCraft.defaultComputerSettings = defaultComputerSettings.get(); | ||||
|         CoreConfig.maximumFilesOpen = maximumFilesOpen.get(); | ||||
|         CoreConfig.disableLua51Features = disableLua51Features.get(); | ||||
|         CoreConfig.defaultComputerSettings = defaultComputerSettings.get(); | ||||
|         ComputerCraft.computerThreads = computerThreads.get(); | ||||
|         ComputerCraft.logComputerErrors = logComputerErrors.get(); | ||||
|         ComputerCraft.commandRequireCreative = commandRequireCreative.get(); | ||||
| 
 | ||||
|         // Execution | ||||
|         ComputerCraft.computerThreads = computerThreads.get(); | ||||
|         ComputerCraft.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(maxMainGlobalTime.get()); | ||||
|         ComputerCraft.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(maxMainComputerTime.get()); | ||||
|         CoreConfig.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(maxMainGlobalTime.get()); | ||||
|         CoreConfig.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(maxMainComputerTime.get()); | ||||
| 
 | ||||
|         // Update our log filter if needed. | ||||
|         var logFilter = MarkerFilter.createFilter( | ||||
|             Logging.COMPUTER_ERROR.getName(), | ||||
|             logComputerErrors.get() ? Filter.Result.ACCEPT : Filter.Result.DENY, | ||||
|             Filter.Result.NEUTRAL | ||||
|         ); | ||||
|         if (!logFilter.equals(Config.logFilter)) { | ||||
|             LoggerContext.getContext().removeFilter(Config.logFilter); | ||||
|             LoggerContext.getContext().addFilter(Config.logFilter = logFilter); | ||||
|         } | ||||
| 
 | ||||
|         // HTTP | ||||
|         ComputerCraft.httpEnabled = httpEnabled.get(); | ||||
|         ComputerCraft.httpWebsocketEnabled = httpWebsocketEnabled.get(); | ||||
|         ComputerCraft.httpRules = httpRules.get().stream() | ||||
|         CoreConfig.httpEnabled = httpEnabled.get(); | ||||
|         CoreConfig.httpWebsocketEnabled = httpWebsocketEnabled.get(); | ||||
|         CoreConfig.httpRules = httpRules.get().stream() | ||||
|             .map(AddressRuleConfig::parseRule).filter(Objects::nonNull).toList(); | ||||
| 
 | ||||
|         ComputerCraft.httpMaxRequests = httpMaxRequests.get(); | ||||
|         ComputerCraft.httpMaxWebsockets = httpMaxWebsockets.get(); | ||||
|         ComputerCraft.httpDownloadBandwidth = httpDownloadBandwidth.get(); | ||||
|         ComputerCraft.httpUploadBandwidth = httpUploadBandwidth.get(); | ||||
|         CoreConfig.httpMaxRequests = httpMaxRequests.get(); | ||||
|         CoreConfig.httpMaxWebsockets = httpMaxWebsockets.get(); | ||||
|         CoreConfig.httpDownloadBandwidth = httpDownloadBandwidth.get(); | ||||
|         CoreConfig.httpUploadBandwidth = httpUploadBandwidth.get(); | ||||
|         NetworkUtils.reloadConfig(); | ||||
| 
 | ||||
|         // Peripheral | ||||
|   | ||||
| @@ -11,6 +11,7 @@ import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.api.detail.BlockReference; | ||||
| import dan200.computercraft.api.detail.VanillaDetailRegistries; | ||||
| import dan200.computercraft.api.lua.*; | ||||
| import dan200.computercraft.core.Logging; | ||||
| import dan200.computercraft.shared.computer.blocks.TileCommandComputer; | ||||
| import dan200.computercraft.shared.util.NBTUtil; | ||||
| import net.minecraft.commands.CommandSourceStack; | ||||
| @@ -56,7 +57,7 @@ public class CommandAPI implements ILuaAPI { | ||||
|             var result = commandManager.performPrefixedCommand(computer.getSource(), command); | ||||
|             return new Object[]{ result > 0, receiver.copyOutput(), result }; | ||||
|         } catch (Throwable t) { | ||||
|             if (ComputerCraft.logComputerErrors) ComputerCraft.log.error("Error running command.", t); | ||||
|             ComputerCraft.log.error(Logging.JAVA_ERROR, "Error running command.", t); | ||||
|             return new Object[]{ false, createOutput("Java Exception Thrown: " + t) }; | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ package dan200.computercraft.shared.computer.terminal; | ||||
| 
 | ||||
| import dan200.computercraft.core.terminal.Terminal; | ||||
| import dan200.computercraft.shared.util.Colour; | ||||
| import dan200.computercraft.shared.util.Palette; | ||||
| import net.minecraft.nbt.CompoundTag; | ||||
| import net.minecraft.network.FriendlyByteBuf; | ||||
| 
 | ||||
| @@ -39,7 +40,9 @@ public class NetworkedTerminal extends Terminal { | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         palette.write(buffer); | ||||
|         for (var i = 0; i < Palette.PALETTE_SIZE; i++) { | ||||
|             for (var channel : palette.getColour(i)) buffer.writeByte((int) (channel * 0xFF) & 0xFF); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public synchronized void read(FriendlyByteBuf buffer) { | ||||
| @@ -64,7 +67,12 @@ public class NetworkedTerminal extends Terminal { | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         palette.read(buffer); | ||||
|         for (var i = 0; i < Palette.PALETTE_SIZE; i++) { | ||||
|             var r = (buffer.readByte() & 0xFF) / 255.0; | ||||
|             var g = (buffer.readByte() & 0xFF) / 255.0; | ||||
|             var b = (buffer.readByte() & 0xFF) / 255.0; | ||||
|             palette.setColour(i, r, g, b); | ||||
|         } | ||||
|         setChanged(); | ||||
|     } | ||||
| 
 | ||||
| @@ -80,7 +88,10 @@ public class NetworkedTerminal extends Terminal { | ||||
|             nbt.putString("term_textBgColour_" + n, backgroundColour[n].toString()); | ||||
|         } | ||||
| 
 | ||||
|         palette.writeToNBT(nbt); | ||||
|         var rgb8 = new int[Palette.PALETTE_SIZE]; | ||||
|         for (var i = 0; i < Palette.PALETTE_SIZE; i++) rgb8[i] = Palette.encodeRGB8(palette.getColour(i)); | ||||
|         nbt.putIntArray("term_palette", rgb8); | ||||
| 
 | ||||
|         return nbt; | ||||
|     } | ||||
| 
 | ||||
| @@ -106,7 +117,16 @@ public class NetworkedTerminal extends Terminal { | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         palette.readFromNBT(nbt); | ||||
|         if (nbt.contains("term_palette")) { | ||||
|             var rgb8 = nbt.getIntArray("term_palette"); | ||||
|             if (rgb8.length == Palette.PALETTE_SIZE) { | ||||
|                 for (var i = 0; i < Palette.PALETTE_SIZE; i++) { | ||||
|                     var colours = Palette.decodeRGB8(rgb8[i]); | ||||
|                     palette.setColour(i, colours[0], colours[1], colours[2]); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|         setChanged(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,13 +5,10 @@ | ||||
|  */ | ||||
| package dan200.computercraft.shared.util; | ||||
| 
 | ||||
| import net.minecraft.nbt.CompoundTag; | ||||
| import net.minecraft.network.FriendlyByteBuf; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| 
 | ||||
| public class Palette { | ||||
|     private static final int PALETTE_SIZE = 16; | ||||
|     public static final int PALETTE_SIZE = 16; | ||||
| 
 | ||||
|     private final boolean colour; | ||||
|     private final double[][] colours = new double[PALETTE_SIZE][3]; | ||||
| @@ -27,7 +24,7 @@ public class Palette { | ||||
|     } | ||||
| 
 | ||||
|     public void setColour(int i, double r, double g, double b) { | ||||
|         if (i < 0 || i >= colours.length) return; | ||||
|         if (i < 0 || i >= PALETTE_SIZE) return; | ||||
|         colours[i][0] = r; | ||||
|         colours[i][1] = g; | ||||
|         colours[i][2] = b; | ||||
| @@ -47,7 +44,7 @@ public class Palette { | ||||
|     } | ||||
| 
 | ||||
|     public double[] getColour(int i) { | ||||
|         return i >= 0 && i < colours.length ? colours[i] : null; | ||||
|         return i >= 0 && i < PALETTE_SIZE ? colours[i] : null; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @@ -65,7 +62,7 @@ public class Palette { | ||||
|     } | ||||
| 
 | ||||
|     public void resetColour(int i) { | ||||
|         if (i >= 0 && i < colours.length) setColour(i, Colour.VALUES[i]); | ||||
|         if (i >= 0 && i < PALETTE_SIZE) setColour(i, Colour.VALUES[i]); | ||||
|     } | ||||
| 
 | ||||
|     public void resetColours() { | ||||
| @@ -89,42 +86,4 @@ public class Palette { | ||||
|             (rgb & 0xFF) / 255.0f, | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     public void write(FriendlyByteBuf buffer) { | ||||
|         for (var colour : colours) { | ||||
|             for (var channel : colour) buffer.writeByte((int) (channel * 0xFF) & 0xFF); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void read(FriendlyByteBuf buffer) { | ||||
|         for (var i = 0; i < PALETTE_SIZE; i++) { | ||||
|             var r = (buffer.readByte() & 0xFF) / 255.0; | ||||
|             var g = (buffer.readByte() & 0xFF) / 255.0; | ||||
|             var b = (buffer.readByte() & 0xFF) / 255.0; | ||||
|             setColour(i, r, g, b); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public CompoundTag writeToNBT(CompoundTag nbt) { | ||||
|         var rgb8 = new int[colours.length]; | ||||
| 
 | ||||
|         for (var i = 0; i < colours.length; i++) { | ||||
|             rgb8[i] = encodeRGB8(colours[i]); | ||||
|         } | ||||
| 
 | ||||
|         nbt.putIntArray("term_palette", rgb8); | ||||
|         return nbt; | ||||
|     } | ||||
| 
 | ||||
|     public void readFromNBT(CompoundTag nbt) { | ||||
|         if (!nbt.contains("term_palette")) return; | ||||
|         var rgb8 = nbt.getIntArray("term_palette"); | ||||
| 
 | ||||
|         if (rgb8.length != colours.length) return; | ||||
| 
 | ||||
|         for (var i = 0; i < colours.length; i++) { | ||||
|             var colours = decodeRGB8(rgb8[i]); | ||||
|             setColour(i, colours[0], colours[1], colours[2]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -85,8 +85,6 @@ public class ComputerTestDelegate { | ||||
| 
 | ||||
|     @BeforeEach | ||||
|     public void before() throws IOException { | ||||
|         ComputerCraft.logComputerErrors = true; | ||||
| 
 | ||||
|         if (Files.deleteIfExists(REPORT_PATH)) ComputerCraft.log.info("Deleted previous coverage report."); | ||||
| 
 | ||||
|         var term = new Terminal(80, 100, true); | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.apis.http.options; | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft; | ||||
| import dan200.computercraft.core.CoreConfig; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.junit.jupiter.params.ParameterizedTest; | ||||
| import org.junit.jupiter.params.provider.ValueSource; | ||||
| @@ -35,7 +35,7 @@ public class AddressRuleTest { | ||||
|         "172.17.0.1", "192.168.1.114", "[0:0:0:0:0:ffff:c0a8:172]", "10.0.0.1" | ||||
|     }) | ||||
|     public void blocksLocalDomains(String domain) { | ||||
|         assertEquals(apply(ComputerCraft.httpRules, domain, 80).action, Action.DENY); | ||||
|         assertEquals(apply(CoreConfig.httpRules, domain, 80).action, Action.DENY); | ||||
|     } | ||||
| 
 | ||||
|     private Options apply(Iterable<AddressRule> rules, String host, int port) { | ||||
|   | ||||
| @@ -12,6 +12,7 @@ import dan200.computercraft.api.lua.ILuaAPI; | ||||
| import dan200.computercraft.api.lua.LuaException; | ||||
| import dan200.computercraft.api.lua.LuaFunction; | ||||
| import dan200.computercraft.core.ComputerContext; | ||||
| import dan200.computercraft.core.CoreConfig; | ||||
| import dan200.computercraft.core.computer.mainthread.MainThread; | ||||
| import dan200.computercraft.core.terminal.Terminal; | ||||
| import dan200.computercraft.test.core.computer.BasicEnvironment; | ||||
| @@ -43,8 +44,7 @@ public class ComputerBootstrap { | ||||
|     } | ||||
| 
 | ||||
|     public static void run(IWritableMount mount, Consumer<Computer> setup, int maxTicks) { | ||||
|         ComputerCraft.logComputerErrors = true; | ||||
|         ComputerCraft.maxMainComputerTime = ComputerCraft.maxMainGlobalTime = Integer.MAX_VALUE; | ||||
|         CoreConfig.maxMainComputerTime = CoreConfig.maxMainGlobalTime = Integer.MAX_VALUE; | ||||
| 
 | ||||
|         var term = new Terminal(ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight, true); | ||||
|         var mainThread = new MainThread(); | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| package dan200.computercraft.core.http | ||||
| 
 | ||||
| import dan200.computercraft.ComputerCraft | ||||
| import dan200.computercraft.core.CoreConfig | ||||
| import dan200.computercraft.core.apis.HTTPAPI | ||||
| import dan200.computercraft.core.apis.http.options.Action | ||||
| import dan200.computercraft.core.apis.http.options.AddressRule | ||||
| @@ -21,13 +21,13 @@ class TestHttpApi { | ||||
|         @JvmStatic | ||||
|         @BeforeAll | ||||
|         fun before() { | ||||
|             ComputerCraft.httpRules = listOf(AddressRule.parse("*", null, Action.ALLOW.toPartial())) | ||||
|             CoreConfig.httpRules = listOf(AddressRule.parse("*", null, Action.ALLOW.toPartial())) | ||||
|         } | ||||
| 
 | ||||
|         @JvmStatic | ||||
|         @AfterAll | ||||
|         fun after() { | ||||
|             ComputerCraft.httpRules = Collections.unmodifiableList( | ||||
|             CoreConfig.httpRules = Collections.unmodifiableList( | ||||
|                 listOf( | ||||
|                     AddressRule.parse("\$private", null, Action.DENY.toPartial()), | ||||
|                     AddressRule.parse("*", null, Action.ALLOW.toPartial()), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jonathan Coates
					Jonathan Coates