mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-06 00:22:58 +00:00
Compare commits
20 Commits
v1.15.2-1.
...
mc-1.15.x
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10a3a223a0 | ||
|
|
2dc970a8bb | ||
|
|
f74c4cc83c | ||
|
|
227b444d81 | ||
|
|
d50db8a6f3 | ||
|
|
3a80b51a9f | ||
|
|
03396cf07a | ||
|
|
0568c86628 | ||
|
|
b31e66686d | ||
|
|
924b8ef30f | ||
|
|
82ca19c296 | ||
|
|
56d8a5d585 | ||
|
|
aa5fbb2980 | ||
|
|
db0bb071f5 | ||
|
|
ab702e2ba1 | ||
|
|
d4efacd40a | ||
|
|
c2316ef256 | ||
|
|
51dde077fe | ||
|
|
31d0b7afcd | ||
|
|
95b0d950aa |
2
.github/workflows/make-doc.yml
vendored
2
.github/workflows/make-doc.yml
vendored
@@ -3,7 +3,7 @@ name: Build documentation
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- mc-1.15.x
|
- mc-1.16.x
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
make_doc:
|
make_doc:
|
||||||
|
|||||||
@@ -472,11 +472,12 @@ tasks.register('publishModrinth', TaskModrinthUpload.class).configure {
|
|||||||
project.hasProperty('modrinthApiKey')
|
project.hasProperty('modrinthApiKey')
|
||||||
}
|
}
|
||||||
|
|
||||||
token = project.hasProperty('curseForgeApiKey')
|
token = project.hasProperty('modrinthApiKey') ? project.getProperty('modrinthApiKey') : ''
|
||||||
projectId = 'gu7yAYhd'
|
projectId = 'gu7yAYhd'
|
||||||
versionNumber = project.mod_version
|
versionNumber = "${project.mc_version}-${project.mod_version}"
|
||||||
uploadFile = jar
|
uploadFile = jar
|
||||||
addGameVersion(project.mc_version)
|
addGameVersion(project.mc_version)
|
||||||
|
changelog = "Release notes can be found on the [GitHub repository](https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
|
||||||
addLoader('forge')
|
addLoader('forge')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,7 +547,7 @@ githubRelease {
|
|||||||
tagName "v${mc_version}-${mod_version}"
|
tagName "v${mc_version}-${mod_version}"
|
||||||
releaseName "[${mc_version}] ${mod_version}"
|
releaseName "[${mc_version}] ${mod_version}"
|
||||||
body.set(project.provider({
|
body.set(project.provider({
|
||||||
"## " + new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
|
"## " + new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
|
||||||
.readLines()
|
.readLines()
|
||||||
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
|
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
|
||||||
.join("\n").trim()
|
.join("\n").trim()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Mod properties
|
# Mod properties
|
||||||
mod_version=1.97.0
|
mod_version=1.97.1
|
||||||
|
|
||||||
# Minecraft properties (update mods.toml when changing)
|
# Minecraft properties (update mods.toml when changing)
|
||||||
mc_version=1.15.2
|
mc_version=1.15.2
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ public final class ComputerCraft
|
|||||||
|
|
||||||
public static int httpMaxRequests = 16;
|
public static int httpMaxRequests = 16;
|
||||||
public static int httpMaxWebsockets = 4;
|
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 boolean enableCommandBlock = false;
|
||||||
public static int modemRange = 64;
|
public static int modemRange = 64;
|
||||||
|
|||||||
@@ -55,9 +55,6 @@ public class GuiTurtle extends ComputerScreenBase<ContainerTurtle>
|
|||||||
minecraft.getTextureManager().bind( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
|
minecraft.getTextureManager().bind( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
|
||||||
blit( leftPos + ComputerSidebar.WIDTH, topPos, 0, 0, TEX_WIDTH, TEX_HEIGHT );
|
blit( leftPos + ComputerSidebar.WIDTH, topPos, 0, 0, TEX_WIDTH, TEX_HEIGHT );
|
||||||
|
|
||||||
minecraft.getTextureManager().bind( advanced ? ComputerBorderRenderer.BACKGROUND_ADVANCED : ComputerBorderRenderer.BACKGROUND_NORMAL );
|
|
||||||
ComputerSidebar.renderBackground( leftPos, topPos + sidebarYOffset );
|
|
||||||
|
|
||||||
int slot = getMenu().getSelectedSlot();
|
int slot = getMenu().getSelectedSlot();
|
||||||
if( slot >= 0 )
|
if( slot >= 0 )
|
||||||
{
|
{
|
||||||
@@ -69,5 +66,8 @@ public class GuiTurtle extends ComputerScreenBase<ContainerTurtle>
|
|||||||
0, 217, 24, 24
|
0, 217, 24, 24
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
minecraft.getTextureManager().bind( advanced ? ComputerBorderRenderer.BACKGROUND_ADVANCED : ComputerBorderRenderer.BACKGROUND_NORMAL );
|
||||||
|
ComputerSidebar.renderBackground( leftPos, topPos + sidebarYOffset );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ public interface IAPIEnvironment
|
|||||||
@Nullable
|
@Nullable
|
||||||
IPeripheral getPeripheral( ComputerSide side );
|
IPeripheral getPeripheral( ComputerSide side );
|
||||||
|
|
||||||
|
@Nullable
|
||||||
String getLabel();
|
String getLabel();
|
||||||
|
|
||||||
void setLabel( @Nullable String label );
|
void setLabel( @Nullable String label );
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import io.netty.handler.codec.http.websocketx.WebSocketHandshakeException;
|
|||||||
import io.netty.handler.ssl.SslContext;
|
import io.netty.handler.ssl.SslContext;
|
||||||
import io.netty.handler.ssl.SslContextBuilder;
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
import io.netty.handler.timeout.ReadTimeoutException;
|
import io.netty.handler.timeout.ReadTimeoutException;
|
||||||
|
import io.netty.handler.traffic.AbstractTrafficShapingHandler;
|
||||||
|
import io.netty.handler.traffic.GlobalTrafficShapingHandler;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
@@ -28,9 +30,7 @@ import javax.net.ssl.TrustManagerFactory;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.SynchronousQueue;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,10 +38,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
*/
|
*/
|
||||||
public final class NetworkUtils
|
public final class NetworkUtils
|
||||||
{
|
{
|
||||||
public static final ExecutorService EXECUTOR = new ThreadPoolExecutor(
|
public static final ScheduledThreadPoolExecutor EXECUTOR = new ScheduledThreadPoolExecutor(
|
||||||
4, Integer.MAX_VALUE,
|
4,
|
||||||
60L, TimeUnit.SECONDS,
|
|
||||||
new SynchronousQueue<>(),
|
|
||||||
ThreadUtils.builder( "Network" )
|
ThreadUtils.builder( "Network" )
|
||||||
.setPriority( Thread.MIN_PRIORITY + (Thread.NORM_PRIORITY - Thread.MIN_PRIORITY) / 2 )
|
.setPriority( Thread.MIN_PRIORITY + (Thread.NORM_PRIORITY - Thread.MIN_PRIORITY) / 2 )
|
||||||
.build()
|
.build()
|
||||||
@@ -52,6 +50,15 @@ public final class NetworkUtils
|
|||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static final AbstractTrafficShapingHandler SHAPING_HANDLER = new GlobalTrafficShapingHandler(
|
||||||
|
EXECUTOR, ComputerCraft.httpUploadBandwidth, ComputerCraft.httpDownloadBandwidth
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
EXECUTOR.setKeepAliveTime( 60, TimeUnit.SECONDS );
|
||||||
|
}
|
||||||
|
|
||||||
private NetworkUtils()
|
private NetworkUtils()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -107,6 +114,16 @@ public final class NetworkUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void reloadConfig()
|
||||||
|
{
|
||||||
|
SHAPING_HANDLER.configure( ComputerCraft.httpUploadBandwidth, ComputerCraft.httpDownloadBandwidth );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void reset()
|
||||||
|
{
|
||||||
|
SHAPING_HANDLER.trafficCounter().resetCumulativeTime();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link InetSocketAddress} from a {@link java.net.URI}.
|
* Create a {@link InetSocketAddress} from a {@link java.net.URI}.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ public class HttpRequest extends Resource<HttpRequest>
|
|||||||
}
|
}
|
||||||
|
|
||||||
ChannelPipeline p = ch.pipeline();
|
ChannelPipeline p = ch.pipeline();
|
||||||
|
p.addLast( NetworkUtils.SHAPING_HANDLER );
|
||||||
if( sslContext != null )
|
if( sslContext != null )
|
||||||
{
|
{
|
||||||
p.addLast( sslContext.newHandler( ch.alloc(), uri.getHost(), socketAddress.getPort() ) );
|
p.addLast( sslContext.newHandler( ch.alloc(), uri.getHost(), socketAddress.getPort() ) );
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import io.netty.handler.codec.http.HttpObjectAggregator;
|
|||||||
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
|
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
|
||||||
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
|
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
|
||||||
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
|
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
|
||||||
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketClientCompressionHandler;
|
|
||||||
import io.netty.handler.ssl.SslContext;
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@@ -146,6 +145,7 @@ public class Websocket extends Resource<Websocket>
|
|||||||
protected void initChannel( SocketChannel ch )
|
protected void initChannel( SocketChannel ch )
|
||||||
{
|
{
|
||||||
ChannelPipeline p = ch.pipeline();
|
ChannelPipeline p = ch.pipeline();
|
||||||
|
p.addLast( NetworkUtils.SHAPING_HANDLER );
|
||||||
if( sslContext != null )
|
if( sslContext != null )
|
||||||
{
|
{
|
||||||
p.addLast( sslContext.newHandler( ch.alloc(), uri.getHost(), socketAddress.getPort() ) );
|
p.addLast( sslContext.newHandler( ch.alloc(), uri.getHost(), socketAddress.getPort() ) );
|
||||||
@@ -160,7 +160,7 @@ public class Websocket extends Resource<Websocket>
|
|||||||
p.addLast(
|
p.addLast(
|
||||||
new HttpClientCodec(),
|
new HttpClientCodec(),
|
||||||
new HttpObjectAggregator( 8192 ),
|
new HttpObjectAggregator( 8192 ),
|
||||||
WebSocketClientCompressionHandler.INSTANCE,
|
WebsocketCompressionHandler.INSTANCE,
|
||||||
new WebsocketHandler( Websocket.this, handshaker, options )
|
new WebsocketHandler( Websocket.this, handshaker, options )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.apis.http.websocket;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
|
import io.netty.handler.codec.compression.ZlibCodecFactory;
|
||||||
|
import io.netty.handler.codec.http.websocketx.extensions.WebSocketClientExtensionHandler;
|
||||||
|
import io.netty.handler.codec.http.websocketx.extensions.compression.DeflateFrameClientExtensionHandshaker;
|
||||||
|
import io.netty.handler.codec.http.websocketx.extensions.compression.PerMessageDeflateClientExtensionHandshaker;
|
||||||
|
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketClientCompressionHandler;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.websocketx.extensions.compression.PerMessageDeflateServerExtensionHandshaker.MAX_WINDOW_SIZE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An alternative to {@link WebSocketClientCompressionHandler} which supports the {@literal client_no_context_takeover}
|
||||||
|
* extension. Makes CC <em>slightly</em> more flexible.
|
||||||
|
*/
|
||||||
|
@ChannelHandler.Sharable
|
||||||
|
final class WebsocketCompressionHandler extends WebSocketClientExtensionHandler
|
||||||
|
{
|
||||||
|
public static final WebsocketCompressionHandler INSTANCE = new WebsocketCompressionHandler();
|
||||||
|
|
||||||
|
private WebsocketCompressionHandler()
|
||||||
|
{
|
||||||
|
super(
|
||||||
|
new PerMessageDeflateClientExtensionHandshaker(
|
||||||
|
6, ZlibCodecFactory.isSupportingWindowSizeAndMemLevel(), MAX_WINDOW_SIZE,
|
||||||
|
true, false
|
||||||
|
),
|
||||||
|
new DeflateFrameClientExtensionHandshaker( false ),
|
||||||
|
new DeflateFrameClientExtensionHandshaker( true )
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
package dan200.computercraft.shared;
|
package dan200.computercraft.shared;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.core.apis.http.NetworkUtils;
|
||||||
import dan200.computercraft.core.computer.MainThread;
|
import dan200.computercraft.core.computer.MainThread;
|
||||||
import dan200.computercraft.core.tracking.Tracking;
|
import dan200.computercraft.core.tracking.Tracking;
|
||||||
import dan200.computercraft.shared.command.CommandComputerCraft;
|
import dan200.computercraft.shared.command.CommandComputerCraft;
|
||||||
@@ -83,6 +84,7 @@ public final class CommonHooks
|
|||||||
ComputerCraft.serverComputerRegistry.reset();
|
ComputerCraft.serverComputerRegistry.reset();
|
||||||
WirelessNetwork.resetNetworks();
|
WirelessNetwork.resetNetworks();
|
||||||
Tracking.reset();
|
Tracking.reset();
|
||||||
|
NetworkUtils.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
@@ -91,6 +93,7 @@ public final class CommonHooks
|
|||||||
ComputerCraft.serverComputerRegistry.reset();
|
ComputerCraft.serverComputerRegistry.reset();
|
||||||
WirelessNetwork.resetNetworks();
|
WirelessNetwork.resetNetworks();
|
||||||
Tracking.reset();
|
Tracking.reset();
|
||||||
|
NetworkUtils.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final ResourceLocation LOOT_TREASURE_DISK = new ResourceLocation( ComputerCraft.MOD_ID, "treasure_disk" );
|
public static final ResourceLocation LOOT_TREASURE_DISK = new ResourceLocation( ComputerCraft.MOD_ID, "treasure_disk" );
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ 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.NetworkUtils;
|
||||||
import dan200.computercraft.core.apis.http.options.Action;
|
import dan200.computercraft.core.apis.http.options.Action;
|
||||||
import dan200.computercraft.core.apis.http.options.AddressRuleConfig;
|
import dan200.computercraft.core.apis.http.options.AddressRuleConfig;
|
||||||
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
||||||
@@ -56,6 +57,9 @@ public final class Config
|
|||||||
private static final ConfigValue<Integer> httpMaxRequests;
|
private static final ConfigValue<Integer> httpMaxRequests;
|
||||||
private static final ConfigValue<Integer> httpMaxWebsockets;
|
private static final ConfigValue<Integer> httpMaxWebsockets;
|
||||||
|
|
||||||
|
private static final ConfigValue<Integer> httpDownloadBandwidth;
|
||||||
|
private static final ConfigValue<Integer> httpUploadBandwidth;
|
||||||
|
|
||||||
private static final ConfigValue<Boolean> commandBlockEnabled;
|
private static final ConfigValue<Boolean> commandBlockEnabled;
|
||||||
private static final ConfigValue<Integer> modemRange;
|
private static final ConfigValue<Integer> modemRange;
|
||||||
private static final ConfigValue<Integer> modemHighAltitudeRange;
|
private static final ConfigValue<Integer> modemHighAltitudeRange;
|
||||||
@@ -187,6 +191,20 @@ public final class Config
|
|||||||
.comment( "The number of websockets a computer can have open at one time. Set to 0 for unlimited." )
|
.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", ComputerCraft.httpMaxWebsockets, 1, Integer.MAX_VALUE );
|
||||||
|
|
||||||
|
builder
|
||||||
|
.comment( "Limits bandwidth used by computers" )
|
||||||
|
.push( "bandwidth" );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
builder.pop();
|
||||||
|
|
||||||
builder.pop();
|
builder.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,6 +347,8 @@ public final class Config
|
|||||||
|
|
||||||
ComputerCraft.httpMaxRequests = httpMaxRequests.get();
|
ComputerCraft.httpMaxRequests = httpMaxRequests.get();
|
||||||
ComputerCraft.httpMaxWebsockets = httpMaxWebsockets.get();
|
ComputerCraft.httpMaxWebsockets = httpMaxWebsockets.get();
|
||||||
|
ComputerCraft.httpDownloadBandwidth = httpDownloadBandwidth.get();
|
||||||
|
NetworkUtils.reloadConfig();
|
||||||
|
|
||||||
// Peripheral
|
// Peripheral
|
||||||
ComputerCraft.enableCommandBlock = commandBlockEnabled.get();
|
ComputerCraft.enableCommandBlock = commandBlockEnabled.get();
|
||||||
|
|||||||
@@ -7,11 +7,13 @@ package dan200.computercraft.shared.command;
|
|||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.util.IDAssigner;
|
import dan200.computercraft.shared.util.IDAssigner;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.util.Util;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.client.event.ClientChatEvent;
|
import net.minecraftforge.client.event.ClientChatEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.server.ServerLifecycleHooks;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@@ -35,6 +37,9 @@ public final class ClientCommands
|
|||||||
// Emulate the command on the client side
|
// Emulate the command on the client side
|
||||||
if( event.getMessage().startsWith( OPEN_COMPUTER ) )
|
if( event.getMessage().startsWith( OPEN_COMPUTER ) )
|
||||||
{
|
{
|
||||||
|
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
|
||||||
|
if( server == null || server.isDedicatedServer() ) return;
|
||||||
|
|
||||||
event.setCanceled( true );
|
event.setCanceled( true );
|
||||||
|
|
||||||
String idStr = event.getMessage().substring( OPEN_COMPUTER.length() ).trim();
|
String idStr = event.getMessage().substring( OPEN_COMPUTER.length() ).trim();
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import net.minecraftforge.fml.network.NetworkEvent;
|
|||||||
import net.minecraftforge.fml.network.NetworkRegistry;
|
import net.minecraftforge.fml.network.NetworkRegistry;
|
||||||
import net.minecraftforge.fml.network.PacketDistributor;
|
import net.minecraftforge.fml.network.PacketDistributor;
|
||||||
import net.minecraftforge.fml.network.simple.SimpleChannel;
|
import net.minecraftforge.fml.network.simple.SimpleChannel;
|
||||||
import net.minecraftforge.fml.server.ServerLifecycleHooks;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
@@ -68,10 +67,7 @@ public final class NetworkHandler
|
|||||||
|
|
||||||
public static void sendToAllPlayers( NetworkMessage packet )
|
public static void sendToAllPlayers( NetworkMessage packet )
|
||||||
{
|
{
|
||||||
for( ServerPlayerEntity player : ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayers() )
|
network.send( PacketDistributor.ALL.noArg(), packet );
|
||||||
{
|
|
||||||
sendToPlayer( player, packet );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendToServer( NetworkMessage packet )
|
public static void sendToServer( NetworkMessage packet )
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public class TerminalState
|
|||||||
if( !compress ) return buffer;
|
if( !compress ) return buffer;
|
||||||
if( compressed != null ) return compressed;
|
if( compressed != null ) return compressed;
|
||||||
|
|
||||||
ByteBuf compressed = Unpooled.directBuffer();
|
ByteBuf compressed = Unpooled.buffer();
|
||||||
OutputStream stream = null;
|
OutputStream stream = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -442,7 +442,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
|||||||
|
|
||||||
private void updateBlockState()
|
private void updateBlockState()
|
||||||
{
|
{
|
||||||
if( remove ) return;
|
if( remove || level == null ) return;
|
||||||
|
|
||||||
if( !diskStack.isEmpty() )
|
if( !diskStack.isEmpty() )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* 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.peripheral.monitor;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
final class MonitorState
|
||||||
|
{
|
||||||
|
public static final MonitorState UNLOADED = new MonitorState( State.UNLOADED, null );
|
||||||
|
public static final MonitorState MISSING = new MonitorState( State.MISSING, null );
|
||||||
|
|
||||||
|
private final State state;
|
||||||
|
private final TileMonitor monitor;
|
||||||
|
|
||||||
|
private MonitorState( @Nonnull State state, @Nullable TileMonitor monitor )
|
||||||
|
{
|
||||||
|
this.state = state;
|
||||||
|
this.monitor = monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MonitorState present( @Nonnull TileMonitor monitor )
|
||||||
|
{
|
||||||
|
return new MonitorState( State.PRESENT, monitor );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPresent()
|
||||||
|
{
|
||||||
|
return state == State.PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMissing()
|
||||||
|
{
|
||||||
|
return state == State.MISSING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public TileMonitor getMonitor()
|
||||||
|
{
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
UNLOADED,
|
||||||
|
MISSING,
|
||||||
|
PRESENT,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -56,6 +56,7 @@ public class TileMonitor extends TileGeneric
|
|||||||
private final Set<IComputerAccess> computers = new HashSet<>();
|
private final Set<IComputerAccess> computers = new HashSet<>();
|
||||||
|
|
||||||
private boolean needsUpdate = false;
|
private boolean needsUpdate = false;
|
||||||
|
private boolean needsValidating = false;
|
||||||
private boolean destroyed = false;
|
private boolean destroyed = false;
|
||||||
private boolean visiting = false;
|
private boolean visiting = false;
|
||||||
|
|
||||||
@@ -78,6 +79,7 @@ public class TileMonitor extends TileGeneric
|
|||||||
public void onLoad()
|
public void onLoad()
|
||||||
{
|
{
|
||||||
super.onLoad();
|
super.onLoad();
|
||||||
|
needsValidating = true;
|
||||||
TickScheduler.schedule( this );
|
TickScheduler.schedule( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +150,12 @@ public class TileMonitor extends TileGeneric
|
|||||||
@Override
|
@Override
|
||||||
public void blockTick()
|
public void blockTick()
|
||||||
{
|
{
|
||||||
|
if( needsValidating )
|
||||||
|
{
|
||||||
|
needsValidating = false;
|
||||||
|
validate();
|
||||||
|
}
|
||||||
|
|
||||||
if( needsUpdate )
|
if( needsUpdate )
|
||||||
{
|
{
|
||||||
needsUpdate = false;
|
needsUpdate = false;
|
||||||
@@ -164,7 +172,7 @@ public class TileMonitor extends TileGeneric
|
|||||||
{
|
{
|
||||||
for( int y = 0; y < height; y++ )
|
for( int y = 0; y < height; y++ )
|
||||||
{
|
{
|
||||||
TileMonitor monitor = getNeighbour( x, y );
|
TileMonitor monitor = getNeighbour( x, y ).getMonitor();
|
||||||
if( monitor == null ) continue;
|
if( monitor == null ) continue;
|
||||||
|
|
||||||
for( IComputerAccess computer : monitor.computers )
|
for( IComputerAccess computer : monitor.computers )
|
||||||
@@ -208,7 +216,7 @@ public class TileMonitor extends TileGeneric
|
|||||||
{
|
{
|
||||||
if( serverMonitor != null ) return serverMonitor;
|
if( serverMonitor != null ) return serverMonitor;
|
||||||
|
|
||||||
TileMonitor origin = getOrigin();
|
TileMonitor origin = getOrigin().getMonitor();
|
||||||
if( origin == null ) return null;
|
if( origin == null ) return null;
|
||||||
|
|
||||||
return serverMonitor = origin.serverMonitor;
|
return serverMonitor = origin.serverMonitor;
|
||||||
@@ -229,7 +237,7 @@ public class TileMonitor extends TileGeneric
|
|||||||
{
|
{
|
||||||
for( int y = 0; y < height; y++ )
|
for( int y = 0; y < height; y++ )
|
||||||
{
|
{
|
||||||
TileMonitor monitor = getNeighbour( x, y );
|
TileMonitor monitor = getNeighbour( x, y ).getMonitor();
|
||||||
if( monitor != null ) monitor.serverMonitor = serverMonitor;
|
if( monitor != null ) monitor.serverMonitor = serverMonitor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -374,24 +382,24 @@ public class TileMonitor extends TileGeneric
|
|||||||
return yIndex;
|
return yIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TileMonitor getSimilarMonitorAt( BlockPos pos )
|
@Nonnull
|
||||||
|
private MonitorState getSimilarMonitorAt( BlockPos pos )
|
||||||
{
|
{
|
||||||
if( pos.equals( getBlockPos() ) ) return this;
|
if( pos.equals( getBlockPos() ) ) return MonitorState.present( this );
|
||||||
|
|
||||||
int y = pos.getY();
|
|
||||||
World world = getLevel();
|
World world = getLevel();
|
||||||
if( world == null || !world.isAreaLoaded( pos, 0 ) ) return null;
|
if( world == null || !world.isAreaLoaded( pos, 0 ) ) return MonitorState.UNLOADED;
|
||||||
|
|
||||||
TileEntity tile = world.getBlockEntity( pos );
|
TileEntity tile = world.getBlockEntity( pos );
|
||||||
if( !(tile instanceof TileMonitor) ) return null;
|
if( !(tile instanceof TileMonitor) ) return MonitorState.MISSING;
|
||||||
|
|
||||||
TileMonitor monitor = (TileMonitor) tile;
|
TileMonitor monitor = (TileMonitor) tile;
|
||||||
return !monitor.visiting && !monitor.destroyed && advanced == monitor.advanced
|
return !monitor.visiting && !monitor.destroyed && advanced == monitor.advanced
|
||||||
&& getDirection() == monitor.getDirection() && getOrientation() == monitor.getOrientation()
|
&& getDirection() == monitor.getDirection() && getOrientation() == monitor.getOrientation()
|
||||||
? monitor : null;
|
? MonitorState.present( monitor ) : MonitorState.MISSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TileMonitor getNeighbour( int x, int y )
|
private MonitorState getNeighbour( int x, int y )
|
||||||
{
|
{
|
||||||
BlockPos pos = getBlockPos();
|
BlockPos pos = getBlockPos();
|
||||||
Direction right = getRight();
|
Direction right = getRight();
|
||||||
@@ -401,7 +409,7 @@ public class TileMonitor extends TileGeneric
|
|||||||
return getSimilarMonitorAt( pos.relative( right, xOffset ).relative( down, yOffset ) );
|
return getSimilarMonitorAt( pos.relative( right, xOffset ).relative( down, yOffset ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private TileMonitor getOrigin()
|
private MonitorState getOrigin()
|
||||||
{
|
{
|
||||||
return getNeighbour( 0, 0 );
|
return getNeighbour( 0, 0 );
|
||||||
}
|
}
|
||||||
@@ -425,7 +433,7 @@ public class TileMonitor extends TileGeneric
|
|||||||
{
|
{
|
||||||
for( int y = 0; y < height; y++ )
|
for( int y = 0; y < height; y++ )
|
||||||
{
|
{
|
||||||
TileMonitor monitor = getNeighbour( x, y );
|
TileMonitor monitor = getNeighbour( x, y ).getMonitor();
|
||||||
if( monitor != null && monitor.peripheral != null )
|
if( monitor != null && monitor.peripheral != null )
|
||||||
{
|
{
|
||||||
needsTerminal = true;
|
needsTerminal = true;
|
||||||
@@ -453,7 +461,7 @@ public class TileMonitor extends TileGeneric
|
|||||||
{
|
{
|
||||||
for( int y = 0; y < height; y++ )
|
for( int y = 0; y < height; y++ )
|
||||||
{
|
{
|
||||||
TileMonitor monitor = getNeighbour( x, y );
|
TileMonitor monitor = getNeighbour( x, y ).getMonitor();
|
||||||
if( monitor == null ) continue;
|
if( monitor == null ) continue;
|
||||||
|
|
||||||
monitor.xIndex = x;
|
monitor.xIndex = x;
|
||||||
@@ -469,13 +477,13 @@ public class TileMonitor extends TileGeneric
|
|||||||
|
|
||||||
private boolean mergeLeft()
|
private boolean mergeLeft()
|
||||||
{
|
{
|
||||||
TileMonitor left = getNeighbour( -1, 0 );
|
TileMonitor left = getNeighbour( -1, 0 ).getMonitor();
|
||||||
if( left == null || left.yIndex != 0 || left.height != height ) return false;
|
if( left == null || left.yIndex != 0 || left.height != height ) return false;
|
||||||
|
|
||||||
int width = left.width + this.width;
|
int width = left.width + this.width;
|
||||||
if( width > ComputerCraft.monitorWidth ) return false;
|
if( width > ComputerCraft.monitorWidth ) return false;
|
||||||
|
|
||||||
TileMonitor origin = left.getOrigin();
|
TileMonitor origin = left.getOrigin().getMonitor();
|
||||||
if( origin != null ) origin.resize( width, height );
|
if( origin != null ) origin.resize( width, height );
|
||||||
left.expand();
|
left.expand();
|
||||||
return true;
|
return true;
|
||||||
@@ -483,13 +491,13 @@ public class TileMonitor extends TileGeneric
|
|||||||
|
|
||||||
private boolean mergeRight()
|
private boolean mergeRight()
|
||||||
{
|
{
|
||||||
TileMonitor right = getNeighbour( width, 0 );
|
TileMonitor right = getNeighbour( width, 0 ).getMonitor();
|
||||||
if( right == null || right.yIndex != 0 || right.height != height ) return false;
|
if( right == null || right.yIndex != 0 || right.height != height ) return false;
|
||||||
|
|
||||||
int width = this.width + right.width;
|
int width = this.width + right.width;
|
||||||
if( width > ComputerCraft.monitorWidth ) return false;
|
if( width > ComputerCraft.monitorWidth ) return false;
|
||||||
|
|
||||||
TileMonitor origin = getOrigin();
|
TileMonitor origin = getOrigin().getMonitor();
|
||||||
if( origin != null ) origin.resize( width, height );
|
if( origin != null ) origin.resize( width, height );
|
||||||
expand();
|
expand();
|
||||||
return true;
|
return true;
|
||||||
@@ -497,13 +505,13 @@ public class TileMonitor extends TileGeneric
|
|||||||
|
|
||||||
private boolean mergeUp()
|
private boolean mergeUp()
|
||||||
{
|
{
|
||||||
TileMonitor above = getNeighbour( 0, height );
|
TileMonitor above = getNeighbour( 0, height ).getMonitor();
|
||||||
if( above == null || above.xIndex != 0 || above.width != width ) return false;
|
if( above == null || above.xIndex != 0 || above.width != width ) return false;
|
||||||
|
|
||||||
int height = above.height + this.height;
|
int height = above.height + this.height;
|
||||||
if( height > ComputerCraft.monitorHeight ) return false;
|
if( height > ComputerCraft.monitorHeight ) return false;
|
||||||
|
|
||||||
TileMonitor origin = getOrigin();
|
TileMonitor origin = getOrigin().getMonitor();
|
||||||
if( origin != null ) origin.resize( width, height );
|
if( origin != null ) origin.resize( width, height );
|
||||||
expand();
|
expand();
|
||||||
return true;
|
return true;
|
||||||
@@ -511,13 +519,13 @@ public class TileMonitor extends TileGeneric
|
|||||||
|
|
||||||
private boolean mergeDown()
|
private boolean mergeDown()
|
||||||
{
|
{
|
||||||
TileMonitor below = getNeighbour( 0, -1 );
|
TileMonitor below = getNeighbour( 0, -1 ).getMonitor();
|
||||||
if( below == null || below.xIndex != 0 || below.width != width ) return false;
|
if( below == null || below.xIndex != 0 || below.width != width ) return false;
|
||||||
|
|
||||||
int height = this.height + below.height;
|
int height = this.height + below.height;
|
||||||
if( height > ComputerCraft.monitorHeight ) return false;
|
if( height > ComputerCraft.monitorHeight ) return false;
|
||||||
|
|
||||||
TileMonitor origin = below.getOrigin();
|
TileMonitor origin = below.getOrigin().getMonitor();
|
||||||
if( origin != null ) origin.resize( width, height );
|
if( origin != null ) origin.resize( width, height );
|
||||||
below.expand();
|
below.expand();
|
||||||
return true;
|
return true;
|
||||||
@@ -546,22 +554,22 @@ public class TileMonitor extends TileGeneric
|
|||||||
visiting = true;
|
visiting = true;
|
||||||
if( xIndex > 0 )
|
if( xIndex > 0 )
|
||||||
{
|
{
|
||||||
TileMonitor left = getNeighbour( xIndex - 1, yIndex );
|
TileMonitor left = getNeighbour( xIndex - 1, yIndex ).getMonitor();
|
||||||
if( left != null ) left.contract();
|
if( left != null ) left.contract();
|
||||||
}
|
}
|
||||||
if( xIndex + 1 < width )
|
if( xIndex + 1 < width )
|
||||||
{
|
{
|
||||||
TileMonitor right = getNeighbour( xIndex + 1, yIndex );
|
TileMonitor right = getNeighbour( xIndex + 1, yIndex ).getMonitor();
|
||||||
if( right != null ) right.contract();
|
if( right != null ) right.contract();
|
||||||
}
|
}
|
||||||
if( yIndex > 0 )
|
if( yIndex > 0 )
|
||||||
{
|
{
|
||||||
TileMonitor below = getNeighbour( xIndex, yIndex - 1 );
|
TileMonitor below = getNeighbour( xIndex, yIndex - 1 ).getMonitor();
|
||||||
if( below != null ) below.contract();
|
if( below != null ) below.contract();
|
||||||
}
|
}
|
||||||
if( yIndex + 1 < height )
|
if( yIndex + 1 < height )
|
||||||
{
|
{
|
||||||
TileMonitor above = getNeighbour( xIndex, yIndex + 1 );
|
TileMonitor above = getNeighbour( xIndex, yIndex + 1 ).getMonitor();
|
||||||
if( above != null ) above.contract();
|
if( above != null ) above.contract();
|
||||||
}
|
}
|
||||||
visiting = false;
|
visiting = false;
|
||||||
@@ -572,11 +580,11 @@ public class TileMonitor extends TileGeneric
|
|||||||
int height = this.height;
|
int height = this.height;
|
||||||
int width = this.width;
|
int width = this.width;
|
||||||
|
|
||||||
TileMonitor origin = getOrigin();
|
TileMonitor origin = getOrigin().getMonitor();
|
||||||
if( origin == null )
|
if( origin == null )
|
||||||
{
|
{
|
||||||
TileMonitor right = width > 1 ? getNeighbour( 1, 0 ) : null;
|
TileMonitor right = width > 1 ? getNeighbour( 1, 0 ).getMonitor() : null;
|
||||||
TileMonitor below = height > 1 ? getNeighbour( 0, 1 ) : null;
|
TileMonitor below = height > 1 ? getNeighbour( 0, 1 ).getMonitor() : null;
|
||||||
|
|
||||||
if( right != null ) right.resize( width - 1, 1 );
|
if( right != null ) right.resize( width - 1, 1 );
|
||||||
if( below != null ) below.resize( width, height - 1 );
|
if( below != null ) below.resize( width, height - 1 );
|
||||||
@@ -590,7 +598,7 @@ public class TileMonitor extends TileGeneric
|
|||||||
{
|
{
|
||||||
for( int x = 0; x < width; x++ )
|
for( int x = 0; x < width; x++ )
|
||||||
{
|
{
|
||||||
TileMonitor monitor = origin.getNeighbour( x, y );
|
TileMonitor monitor = origin.getNeighbour( x, y ).getMonitor();
|
||||||
if( monitor != null ) continue;
|
if( monitor != null ) continue;
|
||||||
|
|
||||||
// Decompose
|
// Decompose
|
||||||
@@ -606,17 +614,17 @@ public class TileMonitor extends TileGeneric
|
|||||||
}
|
}
|
||||||
if( x > 0 )
|
if( x > 0 )
|
||||||
{
|
{
|
||||||
left = origin.getNeighbour( 0, y );
|
left = origin.getNeighbour( 0, y ).getMonitor();
|
||||||
left.resize( x, 1 );
|
left.resize( x, 1 );
|
||||||
}
|
}
|
||||||
if( x + 1 < width )
|
if( x + 1 < width )
|
||||||
{
|
{
|
||||||
right = origin.getNeighbour( x + 1, y );
|
right = origin.getNeighbour( x + 1, y ).getMonitor();
|
||||||
right.resize( width - (x + 1), 1 );
|
right.resize( width - (x + 1), 1 );
|
||||||
}
|
}
|
||||||
if( y + 1 < height )
|
if( y + 1 < height )
|
||||||
{
|
{
|
||||||
below = origin.getNeighbour( 0, y + 1 );
|
below = origin.getNeighbour( 0, y + 1 ).getMonitor();
|
||||||
below.resize( width, height - (y + 1) );
|
below.resize( width, height - (y + 1) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,6 +638,38 @@ public class TileMonitor extends TileGeneric
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkMonitorAt( int xIndex, int yIndex )
|
||||||
|
{
|
||||||
|
BlockPos pos = getBlockPos();
|
||||||
|
Direction right = getRight();
|
||||||
|
Direction down = getDown();
|
||||||
|
|
||||||
|
MonitorState state = getSimilarMonitorAt( pos.relative( right, xIndex ).relative( down, yIndex ) );
|
||||||
|
|
||||||
|
if( state.isMissing() ) return false;
|
||||||
|
|
||||||
|
TileMonitor monitor = state.getMonitor();
|
||||||
|
if( monitor == null ) return true;
|
||||||
|
|
||||||
|
return monitor.xIndex == xIndex && monitor.yIndex == yIndex && monitor.width == width && monitor.height == height;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validate()
|
||||||
|
{
|
||||||
|
if( xIndex == 0 && yIndex == 0 && width == 1 || height == 1 ) return;
|
||||||
|
|
||||||
|
if( checkMonitorAt( 0, 0 ) && checkMonitorAt( 0, height - 1 ) &&
|
||||||
|
checkMonitorAt( width - 1, 0 ) && checkMonitorAt( width - 1, height - 1 ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Something in our monitor is invalid. For now, let's just reset ourselves and then try to integrate ourselves
|
||||||
|
// later.
|
||||||
|
resize( 1, 1 );
|
||||||
|
needsUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void monitorTouched( float xPos, float yPos, float zPos )
|
private void monitorTouched( float xPos, float yPos, float zPos )
|
||||||
{
|
{
|
||||||
XYPair pair = XYPair
|
XYPair pair = XYPair
|
||||||
@@ -657,7 +697,7 @@ public class TileMonitor extends TileGeneric
|
|||||||
{
|
{
|
||||||
for( int x = 0; x < width; x++ )
|
for( int x = 0; x < width; x++ )
|
||||||
{
|
{
|
||||||
TileMonitor monitor = getNeighbour( x, y );
|
TileMonitor monitor = getNeighbour( x, y ).getMonitor();
|
||||||
if( monitor == null ) continue;
|
if( monitor == null ) continue;
|
||||||
|
|
||||||
for( IComputerAccess computer : monitor.computers )
|
for( IComputerAccess computer : monitor.computers )
|
||||||
@@ -683,8 +723,8 @@ public class TileMonitor extends TileGeneric
|
|||||||
@Override
|
@Override
|
||||||
public AxisAlignedBB getRenderBoundingBox()
|
public AxisAlignedBB getRenderBoundingBox()
|
||||||
{
|
{
|
||||||
TileMonitor start = getNeighbour( 0, 0 );
|
TileMonitor start = getNeighbour( 0, 0 ).getMonitor();
|
||||||
TileMonitor end = getNeighbour( width - 1, height - 1 );
|
TileMonitor end = getNeighbour( width - 1, height - 1 ).getMonitor();
|
||||||
if( start != null && end != null )
|
if( start != null && end != null )
|
||||||
{
|
{
|
||||||
BlockPos startPos = start.getBlockPos();
|
BlockPos startPos = start.getBlockPos();
|
||||||
|
|||||||
@@ -438,7 +438,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
|||||||
|
|
||||||
private void updateBlockState( boolean top, boolean bottom )
|
private void updateBlockState( boolean top, boolean bottom )
|
||||||
{
|
{
|
||||||
if( remove ) return;
|
if( remove || level == null ) return;
|
||||||
|
|
||||||
BlockState state = getBlockState();
|
BlockState state = getBlockState();
|
||||||
if( state.getValue( BlockPrinter.TOP ) == top & state.getValue( BlockPrinter.BOTTOM ) == bottom ) return;
|
if( state.getValue( BlockPrinter.TOP ) == top & state.getValue( BlockPrinter.BOTTOM ) == bottom ) return;
|
||||||
|
|||||||
@@ -47,7 +47,10 @@ public class TileSpeaker extends TileGeneric implements ITickableTileEntity
|
|||||||
public void setRemoved()
|
public void setRemoved()
|
||||||
{
|
{
|
||||||
super.setRemoved();
|
super.setRemoved();
|
||||||
NetworkHandler.sendToAllPlayers( new SpeakerStopClientMessage( source ) );
|
if( level != null && !level.isClientSide )
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToAllPlayers( new SpeakerStopClientMessage( source ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
|||||||
@@ -681,6 +681,7 @@ if http then
|
|||||||
local nativeCheckURL = http.checkURL
|
local nativeCheckURL = http.checkURL
|
||||||
http.checkURLAsync = nativeCheckURL
|
http.checkURLAsync = nativeCheckURL
|
||||||
http.checkURL = function(_url)
|
http.checkURL = function(_url)
|
||||||
|
expect(1, _url, "string")
|
||||||
local ok, err = nativeCheckURL(_url)
|
local ok, err = nativeCheckURL(_url)
|
||||||
if not ok then return ok, err end
|
if not ok then return ok, err end
|
||||||
|
|
||||||
|
|||||||
@@ -351,12 +351,12 @@ function run()
|
|||||||
-- Got a modem message, process it and add it to the rednet event queue
|
-- Got a modem message, process it and add it to the rednet event queue
|
||||||
local sModem, nChannel, nReplyChannel, tMessage = p1, p2, p3, p4
|
local sModem, nChannel, nReplyChannel, tMessage = p1, p2, p3, p4
|
||||||
if isOpen(sModem) and (nChannel == os.getComputerID() or nChannel == CHANNEL_BROADCAST) then
|
if isOpen(sModem) and (nChannel == os.getComputerID() or nChannel == CHANNEL_BROADCAST) then
|
||||||
if type(tMessage) == "table" and tMessage.nMessageID then
|
if type(tMessage) == "table" and type(tMessage.nMessageID) == "number"
|
||||||
if not tReceivedMessages[tMessage.nMessageID] then
|
and tMessage.nMessageID == tMessage.nMessageID and not tReceivedMessages[tMessage.nMessageID]
|
||||||
tReceivedMessages[tMessage.nMessageID] = true
|
then
|
||||||
tReceivedMessageTimeouts[os.startTimer(30)] = tMessage.nMessageID
|
tReceivedMessages[tMessage.nMessageID] = true
|
||||||
os.queueEvent("rednet_message", nReplyChannel, tMessage.message, tMessage.sProtocol)
|
tReceivedMessageTimeouts[os.startTimer(30)] = tMessage.nMessageID
|
||||||
end
|
os.queueEvent("rednet_message", nReplyChannel, tMessage.message, tMessage.sProtocol)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ for _, v in ipairs(valid_types) do valid_types[v] = true end
|
|||||||
-- will error.
|
-- will error.
|
||||||
function define(name, options)
|
function define(name, options)
|
||||||
expect(1, name, "string")
|
expect(1, name, "string")
|
||||||
expect(2, options, "table", nil)
|
expect(2, options, "table", "nil")
|
||||||
|
|
||||||
if options then
|
if options then
|
||||||
options = {
|
options = {
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
# New features in CC: Tweaked 1.97.1
|
||||||
|
* Add config options to limit total bandwidth used by the HTTP API.
|
||||||
|
|
||||||
|
And several bug fixes:
|
||||||
|
* Fix selected slot indicator not appearing in turtle interface.
|
||||||
|
* Fix crash when printers are placed as part of world generation.
|
||||||
|
* Fix crash when breaking a speaker on a multiplayer world.
|
||||||
|
* Prevent issue in rednet when the message ID is NaN.
|
||||||
|
* Fix `help` program crashing when terminal changes width.
|
||||||
|
* Ensure monitors are well-formed when placed, preventing graphical glitches
|
||||||
|
when using Carry On or Quark.
|
||||||
|
* Accept several more extensions in the websocket client.
|
||||||
|
* Prevent `wget` crashing when given an invalid URL and no filename.
|
||||||
|
|
||||||
# New features in CC: Tweaked 1.97.0
|
# New features in CC: Tweaked 1.97.0
|
||||||
|
|
||||||
* Update several translations (Anavrins, Jummit, Naheulf).
|
* Update several translations (Anavrins, Jummit, Naheulf).
|
||||||
|
|||||||
@@ -1,27 +1,15 @@
|
|||||||
New features in CC: Tweaked 1.97.0
|
New features in CC: Tweaked 1.97.1
|
||||||
|
* Add config options to limit total bandwidth used by the HTTP API.
|
||||||
* Update several translations (Anavrins, Jummit, Naheulf).
|
|
||||||
* Add button to view a computer's folder to `/computercraft dump`.
|
|
||||||
* Allow cleaning dyed turtles in a cauldron.
|
|
||||||
* Add scale subcommand to `monitor` program (MCJack123).
|
|
||||||
* Add option to make `textutils.serialize` not write an indent (magiczocker10).
|
|
||||||
* Allow comparing vectors using `==` (fatboychummy).
|
|
||||||
* Improve HTTP error messages for SSL failures.
|
|
||||||
* Allow `craft` program to craft unlimited items (fatboychummy).
|
|
||||||
* Impose some limits on various command queues.
|
|
||||||
* Add buttons to shutdown and terminate to computer GUIs.
|
|
||||||
* Add program subcompletion to several programs (Wojbie).
|
|
||||||
* Update the `help` program to accept and (partially) highlight markdown files.
|
|
||||||
* Remove config option for the debug API.
|
|
||||||
* Allow setting the subprotocol header for websockets.
|
|
||||||
|
|
||||||
And several bug fixes:
|
And several bug fixes:
|
||||||
* Fix NPE when using a treasure disk when no treasure disks are available.
|
* Fix selected slot indicator not appearing in turtle interface.
|
||||||
* Prevent command computers discarding command ouput when certain game rules are off.
|
* Fix crash when printers are placed as part of world generation.
|
||||||
* Fix turtles not updating peripherals when upgrades are unequipped (Ronan-H).
|
* Fix crash when breaking a speaker on a multiplayer world.
|
||||||
* Fix computers not shutting down on fatal errors within the Lua VM.
|
* Prevent issue in rednet when the message ID is NaN.
|
||||||
* Speakers now correctly stop playing when broken, and sound follows noisy turtles and pocket computers.
|
* Fix `help` program crashing when terminal changes width.
|
||||||
* Update the `wget` to be more resiliant in the face of user-errors.
|
* Ensure monitors are well-formed when placed, preventing graphical glitches
|
||||||
* Fix exiting `paint` typing "e" in the shell.
|
when using Carry On or Quark.
|
||||||
|
* Accept several more extensions in the websocket client.
|
||||||
|
* Prevent `wget` crashing when given an invalid URL and no filename.
|
||||||
|
|
||||||
Type "help changelog" to see the full version history.
|
Type "help changelog" to see the full version history.
|
||||||
|
|||||||
@@ -21,3 +21,4 @@ The "equip" programs let you add upgrades to a turtle without crafting.
|
|||||||
You can change the color of a disk by crafting or right clicking it with dye.
|
You can change the color of a disk by crafting or right clicking it with dye.
|
||||||
You can print on a printed page again to get multiple colors.
|
You can print on a printed page again to get multiple colors.
|
||||||
Holding the Ctrl and T keys terminates the running program.
|
Holding the Ctrl and T keys terminates the running program.
|
||||||
|
You can drag and drop files onto an open computer to upload them.
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ while true do
|
|||||||
local new_width, new_height = term.getSize()
|
local new_width, new_height = term.getSize()
|
||||||
|
|
||||||
if new_width ~= width then
|
if new_width ~= width then
|
||||||
lines = word_wrap(contents, new_width)
|
lines, fg, bg = word_wrap(contents, new_width)
|
||||||
print_height = #lines
|
print_height = #lines
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ if run then
|
|||||||
printError(err)
|
printError(err)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local sFile = tArgs[1] or getFilename(url)
|
local sFile = tArgs[1] or getFilename(url) or url
|
||||||
local sPath = shell.resolve(sFile)
|
local sPath = shell.resolve(sFile)
|
||||||
if fs.exists(sPath) then
|
if fs.exists(sPath) then
|
||||||
print("File already exists")
|
print("File already exists")
|
||||||
|
|||||||
121
src/test/java/dan200/computercraft/core/apis/AsyncRunner.kt
Normal file
121
src/test/java/dan200/computercraft/core/apis/AsyncRunner.kt
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
package dan200.computercraft.core.apis
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft
|
||||||
|
import dan200.computercraft.api.lua.ILuaAPI
|
||||||
|
import dan200.computercraft.api.lua.MethodResult
|
||||||
|
import dan200.computercraft.api.peripheral.IPeripheral
|
||||||
|
import dan200.computercraft.api.peripheral.IWorkMonitor
|
||||||
|
import dan200.computercraft.core.computer.BasicEnvironment
|
||||||
|
import dan200.computercraft.core.computer.ComputerSide
|
||||||
|
import dan200.computercraft.core.computer.IComputerEnvironment
|
||||||
|
import dan200.computercraft.core.filesystem.FileSystem
|
||||||
|
import dan200.computercraft.core.terminal.Terminal
|
||||||
|
import dan200.computercraft.core.tracking.TrackingField
|
||||||
|
import kotlinx.coroutines.channels.Channel
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.withTimeout
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.ExperimentalTime
|
||||||
|
import kotlin.time.seconds
|
||||||
|
|
||||||
|
|
||||||
|
abstract class NullApiEnvironment : IAPIEnvironment {
|
||||||
|
private val computerEnv = BasicEnvironment()
|
||||||
|
|
||||||
|
override fun getComputerID(): Int = 0
|
||||||
|
override fun getComputerEnvironment(): IComputerEnvironment = computerEnv
|
||||||
|
override fun getMainThreadMonitor(): IWorkMonitor = throw IllegalStateException("Work monitor not available")
|
||||||
|
override fun getTerminal(): Terminal = throw IllegalStateException("Terminal not available")
|
||||||
|
override fun getFileSystem(): FileSystem = throw IllegalStateException("Terminal not available")
|
||||||
|
override fun shutdown() {}
|
||||||
|
override fun reboot() {}
|
||||||
|
override fun setOutput(side: ComputerSide?, output: Int) {}
|
||||||
|
override fun getOutput(side: ComputerSide?): Int = 0
|
||||||
|
override fun getInput(side: ComputerSide?): Int = 0
|
||||||
|
override fun setBundledOutput(side: ComputerSide?, output: Int) {}
|
||||||
|
override fun getBundledOutput(side: ComputerSide?): Int = 0
|
||||||
|
override fun getBundledInput(side: ComputerSide?): Int = 0
|
||||||
|
override fun setPeripheralChangeListener(listener: IAPIEnvironment.IPeripheralChangeListener?) {}
|
||||||
|
override fun getPeripheral(side: ComputerSide?): IPeripheral? = null
|
||||||
|
override fun getLabel(): String? = null
|
||||||
|
override fun setLabel(label: String?) {}
|
||||||
|
override fun startTimer(ticks: Long): Int = 0
|
||||||
|
override fun cancelTimer(id: Int) {}
|
||||||
|
override fun addTrackingChange(field: TrackingField, change: Long) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventResult(val name: String, val args: Array<Any?>)
|
||||||
|
|
||||||
|
class AsyncRunner : NullApiEnvironment() {
|
||||||
|
private val eventStream: Channel<Array<Any?>> = Channel(Int.MAX_VALUE)
|
||||||
|
private val apis: MutableList<ILuaAPI> = mutableListOf()
|
||||||
|
|
||||||
|
override fun queueEvent(event: String?, vararg args: Any?) {
|
||||||
|
ComputerCraft.log.debug("Queue event $event ${args.contentToString()}")
|
||||||
|
if (!eventStream.offer(arrayOf(event, *args))) {
|
||||||
|
throw IllegalStateException("Queue is full")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shutdown() {
|
||||||
|
super.shutdown()
|
||||||
|
eventStream.close()
|
||||||
|
apis.forEach { it.shutdown() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : ILuaAPI> addApi(api: T): T {
|
||||||
|
apis.add(api)
|
||||||
|
api.startup()
|
||||||
|
return api
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun resultOf(toRun: MethodResult): Array<Any?> {
|
||||||
|
var running = toRun
|
||||||
|
while (running.callback != null) running = runOnce(running)
|
||||||
|
return running.result ?: empty
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun runOnce(obj: MethodResult): MethodResult {
|
||||||
|
val callback = obj.callback ?: throw NullPointerException("Callback cannot be null")
|
||||||
|
|
||||||
|
val result = obj.result
|
||||||
|
val filter: String? = if (result.isNullOrEmpty() || result[0] !is String) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
result[0] as String
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback.resume(pullEventImpl(filter))
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun pullEventImpl(filter: String?): Array<Any?> {
|
||||||
|
for (event in eventStream) {
|
||||||
|
ComputerCraft.log.debug("Pulled event ${event.contentToString()}")
|
||||||
|
val eventName = event[0] as String
|
||||||
|
if (filter == null || eventName == filter || eventName == "terminate") return event
|
||||||
|
}
|
||||||
|
|
||||||
|
throw IllegalStateException("No more events")
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun pullEvent(filter: String? = null): EventResult {
|
||||||
|
val result = pullEventImpl(filter)
|
||||||
|
return EventResult(result[0] as String, result.copyOfRange(1, result.size))
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val empty: Array<Any?> = arrayOf()
|
||||||
|
|
||||||
|
@OptIn(ExperimentalTime::class)
|
||||||
|
fun runTest(timeout: Duration = 5.seconds, fn: suspend AsyncRunner.() -> Unit) {
|
||||||
|
runBlocking {
|
||||||
|
val runner = AsyncRunner()
|
||||||
|
try {
|
||||||
|
withTimeout(timeout) { fn(runner) }
|
||||||
|
} finally {
|
||||||
|
runner.shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package dan200.computercraft.core.apis.http.options
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft
|
||||||
|
import dan200.computercraft.core.apis.AsyncRunner
|
||||||
|
import dan200.computercraft.core.apis.HTTPAPI
|
||||||
|
import org.junit.jupiter.api.AfterAll
|
||||||
|
import org.junit.jupiter.api.Assertions.assertArrayEquals
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.BeforeAll
|
||||||
|
import org.junit.jupiter.api.Disabled
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Disabled("Requires some setup locally.")
|
||||||
|
class TestHttpApi {
|
||||||
|
companion object {
|
||||||
|
private const val WS_ADDRESS = "ws://127.0.0.1:8080"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@BeforeAll
|
||||||
|
fun before() {
|
||||||
|
ComputerCraft.httpRules = listOf(AddressRule.parse("*", null, Action.ALLOW.toPartial()))
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@AfterAll
|
||||||
|
fun after() {
|
||||||
|
ComputerCraft.httpRules = Collections.unmodifiableList(
|
||||||
|
listOf(
|
||||||
|
AddressRule.parse("\$private", null, Action.DENY.toPartial()),
|
||||||
|
AddressRule.parse("*", null, Action.ALLOW.toPartial())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Connects to websocket`() {
|
||||||
|
AsyncRunner.runTest {
|
||||||
|
val httpApi = addApi(HTTPAPI(this))
|
||||||
|
|
||||||
|
val result = httpApi.websocket(WS_ADDRESS, Optional.empty())
|
||||||
|
assertArrayEquals(arrayOf(true), result, "Should have created websocket")
|
||||||
|
|
||||||
|
val event = pullEvent()
|
||||||
|
assertEquals("websocket_success", event.name) {
|
||||||
|
"Websocket failed to connect: ${event.args.contentToString()}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/test/java/dan200/computercraft/ingame/CraftOsTest.kt
Normal file
13
src/test/java/dan200/computercraft/ingame/CraftOsTest.kt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package dan200.computercraft.ingame
|
||||||
|
|
||||||
|
import dan200.computercraft.ingame.api.GameTest
|
||||||
|
import dan200.computercraft.ingame.api.TestContext
|
||||||
|
import dan200.computercraft.ingame.api.checkComputerOk
|
||||||
|
|
||||||
|
class CraftOsTest {
|
||||||
|
/**
|
||||||
|
* Sends a rednet message to another a computer and back again.
|
||||||
|
*/
|
||||||
|
@GameTest
|
||||||
|
suspend fun `Sends basic rednet messages`(context: TestContext) = context.checkComputerOk(13)
|
||||||
|
}
|
||||||
39
src/test/java/dan200/computercraft/ingame/MonitorTest.kt
Normal file
39
src/test/java/dan200/computercraft/ingame/MonitorTest.kt
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package dan200.computercraft.ingame
|
||||||
|
|
||||||
|
import dan200.computercraft.ingame.api.*
|
||||||
|
import dan200.computercraft.shared.Registry
|
||||||
|
import dan200.computercraft.shared.peripheral.monitor.TileMonitor
|
||||||
|
import net.minecraft.block.Blocks
|
||||||
|
import net.minecraft.command.arguments.BlockStateInput
|
||||||
|
import net.minecraft.nbt.CompoundNBT
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.fail
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class MonitorTest {
|
||||||
|
@GameTest
|
||||||
|
suspend fun `Ensures valid on place`(context: TestContext) {
|
||||||
|
val pos = BlockPos(2, 0, 2)
|
||||||
|
val tag = CompoundNBT()
|
||||||
|
tag.putInt("Width", 2)
|
||||||
|
tag.putInt("Height", 2)
|
||||||
|
|
||||||
|
val toSet = BlockStateInput(
|
||||||
|
Registry.ModBlocks.MONITOR_ADVANCED.get().defaultBlockState(),
|
||||||
|
Collections.emptySet(),
|
||||||
|
tag
|
||||||
|
)
|
||||||
|
|
||||||
|
context.setBlock(pos, Blocks.AIR.defaultBlockState())
|
||||||
|
context.setBlock(pos, toSet)
|
||||||
|
|
||||||
|
context.sleep(2)
|
||||||
|
|
||||||
|
val tile = context.getTile(pos)
|
||||||
|
if (tile !is TileMonitor) fail("Expected tile to be monitor, is $tile")
|
||||||
|
|
||||||
|
assertEquals(1, tile.width, "Width should be 1")
|
||||||
|
assertEquals(1, tile.height, "Width should be 1")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package dan200.computercraft.ingame.api
|
|||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.command.arguments.BlockStateInput
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.math.AxisAlignedBB
|
import net.minecraft.util.math.AxisAlignedBB
|
||||||
@@ -54,6 +55,11 @@ fun TestContext.setBlock(pos: BlockPos, state: BlockState) {
|
|||||||
tracker.level.setBlockAndUpdate(offset(pos), state)
|
tracker.level.setBlockAndUpdate(offset(pos), state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a block within the test structure.
|
||||||
|
*/
|
||||||
|
fun TestContext.setBlock(pos: BlockPos, state: BlockStateInput) = state.place(tracker.level, offset(pos), 3)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modify a block state within the test.
|
* Modify a block state within the test.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
-- TurtleTest.`Use compostors`
|
||||||
|
|
||||||
test.eq(true, turtle.dropDown(), "Drop items into compostor")
|
test.eq(true, turtle.dropDown(), "Drop items into compostor")
|
||||||
|
|
||||||
test.ok()
|
test.ok()
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
-- TurtleTest.`Cleaned with cauldrons`
|
||||||
|
|
||||||
local old_details = turtle.getItemDetail(1, true)
|
local old_details = turtle.getItemDetail(1, true)
|
||||||
|
|
||||||
test.assert(turtle.place(), "Dyed turtle")
|
test.assert(turtle.place(), "Dyed turtle")
|
||||||
|
|||||||
14
src/test/server-files/computers/computer/13/startup.lua
Normal file
14
src/test/server-files/computers/computer/13/startup.lua
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-- CraftOsTest.`Sends basic rednet messages`
|
||||||
|
|
||||||
|
rednet.open("top")
|
||||||
|
|
||||||
|
local id, msg
|
||||||
|
repeat
|
||||||
|
rednet.send(14, "Test msg") -- Keep sending, as other computer may not have started yet.
|
||||||
|
|
||||||
|
id, msg = rednet.receive(nil, 1)
|
||||||
|
print(id, msg)
|
||||||
|
until id == 14
|
||||||
|
|
||||||
|
test.eq("Test msg", msg)
|
||||||
|
test.ok()
|
||||||
7
src/test/server-files/computers/computer/14/startup.lua
Normal file
7
src/test/server-files/computers/computer/14/startup.lua
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
-- CraftOsTest.`Sends basic rednet messages`
|
||||||
|
|
||||||
|
rednet.open("top")
|
||||||
|
while true do
|
||||||
|
local id, msg, protocol = rednet.receive()
|
||||||
|
rednet.send(id, msg, protocol)
|
||||||
|
end
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"computer": 12
|
"computer": 14
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,555 @@
|
|||||||
|
{
|
||||||
|
size: [5, 5, 5],
|
||||||
|
entities: [],
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
pos: [0, 0, 0],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 0, 0],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 0, 0],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 0, 0],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 0, 0],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 0, 1],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 0, 1],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 0, 1],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 0, 1],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 0, 1],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 0, 2],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 0, 2],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 0, 2],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 0, 2],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 0, 2],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 0, 3],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 0, 3],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 0, 3],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 0, 3],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 0, 3],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 0, 4],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 0, 4],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 0, 4],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 0, 4],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 0, 4],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nbt: {
|
||||||
|
Label: "Echo",
|
||||||
|
id: "computercraft:computer_advanced",
|
||||||
|
ComputerId: 14,
|
||||||
|
On: 1b
|
||||||
|
},
|
||||||
|
pos: [1, 1, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nbt: {
|
||||||
|
Label: "Main",
|
||||||
|
id: "computercraft:computer_advanced",
|
||||||
|
ComputerId: 13,
|
||||||
|
On: 1b
|
||||||
|
},
|
||||||
|
pos: [3, 1, 2],
|
||||||
|
state: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nbt: {
|
||||||
|
id: "computercraft:wireless_modem_normal"
|
||||||
|
},
|
||||||
|
pos: [1, 2, 2],
|
||||||
|
state: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nbt: {
|
||||||
|
id: "computercraft:wireless_modem_normal"
|
||||||
|
},
|
||||||
|
pos: [3, 2, 2],
|
||||||
|
state: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 1, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 1, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 1, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 1, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 1, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 2, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 2, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 2, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 2, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 2, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 3, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 3, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 3, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 3, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 3, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 4, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 4, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 4, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 4, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 4, 0],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 1, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 1, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 1, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 1, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 1, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 2, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 2, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 2, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 2, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 2, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 3, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 3, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 3, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 3, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 3, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 4, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 4, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 4, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 4, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 4, 1],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 1, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 1, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 1, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 2, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 2, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 2, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 3, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 3, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 3, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 3, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 3, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 4, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 4, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 4, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 4, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 4, 2],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 1, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 1, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 1, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 1, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 1, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 2, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 2, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 2, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 2, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 2, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 3, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 3, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 3, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 3, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 3, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 4, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 4, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 4, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 4, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 4, 3],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 1, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 1, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 1, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 1, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 1, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 2, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 2, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 2, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 2, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 2, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 3, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 3, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 3, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 3, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 3, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 4, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 4, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 4, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 4, 4],
|
||||||
|
state: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 4, 4],
|
||||||
|
state: 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
palette: [
|
||||||
|
{
|
||||||
|
Name: "minecraft:polished_andesite"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Properties: {
|
||||||
|
facing: "north",
|
||||||
|
state: "on"
|
||||||
|
},
|
||||||
|
Name: "computercraft:computer_advanced"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Properties: {
|
||||||
|
facing: "north",
|
||||||
|
state: "blinking"
|
||||||
|
},
|
||||||
|
Name: "computercraft:computer_advanced"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Properties: {
|
||||||
|
waterlogged: "false",
|
||||||
|
facing: "down",
|
||||||
|
on: "true"
|
||||||
|
},
|
||||||
|
Name: "computercraft:wireless_modem_normal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "minecraft:air"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
DataVersion: 2230
|
||||||
|
}
|
||||||
@@ -0,0 +1,515 @@
|
|||||||
|
{
|
||||||
|
size: [5, 5, 5],
|
||||||
|
entities: [],
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
pos: [0, 0, 0],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 0, 0],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 0, 0],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 0, 0],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 0, 0],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 0, 1],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 0, 1],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 0, 1],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 0, 1],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 0, 1],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 0, 2],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 0, 2],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 0, 2],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 0, 2],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 0, 2],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 0, 3],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 0, 3],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 0, 3],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 0, 3],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 0, 3],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 0, 4],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 0, 4],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 0, 4],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 0, 4],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 0, 4],
|
||||||
|
state: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 1, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 1, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 1, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 1, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 1, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 2, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 2, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 2, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 2, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 2, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 3, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 3, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 3, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 3, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 3, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 4, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 4, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 4, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 4, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 4, 0],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 1, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 1, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 1, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 1, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 1, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 2, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 2, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 2, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 2, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 2, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 3, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 3, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 3, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 3, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 3, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 4, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 4, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 4, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 4, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 4, 1],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 1, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 1, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 1, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 1, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 1, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 2, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 2, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 2, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 2, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 2, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 3, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 3, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 3, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 3, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 3, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 4, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 4, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 4, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 4, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 4, 2],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 1, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 1, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 1, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 1, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 1, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 2, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 2, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 2, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 2, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 2, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 3, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 3, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 3, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 3, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 3, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 4, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 4, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 4, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 4, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 4, 3],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 1, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 1, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 1, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 1, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 1, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 2, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 2, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 2, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 2, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 2, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 3, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 3, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 3, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 3, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 3, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [0, 4, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [1, 4, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [2, 4, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [3, 4, 4],
|
||||||
|
state: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: [4, 4, 4],
|
||||||
|
state: 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
palette: [
|
||||||
|
{
|
||||||
|
Name: "minecraft:polished_andesite"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "minecraft:air"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
DataVersion: 2230
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user