From 48edcde4ef3daee708cb241e8b896714295a8596 Mon Sep 17 00:00:00 2001 From: SquidDev Date: Fri, 19 Jun 2020 18:49:19 +0100 Subject: [PATCH] Fix handling of CC: T's version We never added back replacing of ${version} strings, which means that CC was reporting incorrect version numbers in _HOST, the user agent and network versions. This meant we would allow connections even on mismatched versions (#464). We shift all version handling into ComputerCraftAPI(Impl) - this now relies on Forge code, so we don't want to run it in emulators. --- build.gradle | 2 - .../dan200/computercraft/ComputerCraft.java | 5 -- .../computercraft/ComputerCraftAPIImpl.java | 15 +++--- .../computercraft/api/ComputerCraftAPI.java | 3 +- .../apis/http/request/HttpRequestHandler.java | 2 +- .../core/computer/IComputerEnvironment.java | 9 ++++ .../shared/computer/core/ServerComputer.java | 11 ++++- .../shared/network/NetworkHandler.java | 49 ++++++++++--------- .../peripheral/monitor/TileMonitor.java | 2 +- .../core/computer/BasicEnvironment.java | 11 ++++- 10 files changed, 66 insertions(+), 43 deletions(-) diff --git a/build.gradle b/build.gradle index 4b6864ec8..debd2965b 100644 --- a/build.gradle +++ b/build.gradle @@ -202,8 +202,6 @@ task proguardMove(dependsOn: proguard) { } } - - processResources { inputs.property "version", mod_version inputs.property "mcversion", mc_version diff --git a/src/main/java/dan200/computercraft/ComputerCraft.java b/src/main/java/dan200/computercraft/ComputerCraft.java index 4403a2334..22c039874 100644 --- a/src/main/java/dan200/computercraft/ComputerCraft.java +++ b/src/main/java/dan200/computercraft/ComputerCraft.java @@ -197,11 +197,6 @@ public ComputerCraft() Config.load(); } - public static String getVersion() - { - return "${version}"; - } - public static InputStream getResourceFile( String domain, String subPath ) { IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager(); diff --git a/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java b/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java index 1610ea5fb..28f6d4e71 100644 --- a/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java +++ b/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java @@ -5,7 +5,6 @@ */ package dan200.computercraft; -import com.google.common.collect.MapMaker; import dan200.computercraft.api.ComputerCraftAPI.IComputerCraftAPI; import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; @@ -28,17 +27,15 @@ import net.minecraft.resources.IReloadableResourceManager; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; -import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.server.ServerLifecycleHooks; import javax.annotation.Nonnull; import java.io.File; -import java.lang.ref.WeakReference; -import java.util.Map; import static dan200.computercraft.shared.Capabilities.CAPABILITY_WIRED_ELEMENT; @@ -46,18 +43,20 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI { public static final ComputerCraftAPIImpl INSTANCE = new ComputerCraftAPIImpl(); + private String version; + private ComputerCraftAPIImpl() { } - private WeakReference currentResources; - private final Map mountCache = new MapMaker().weakValues().concurrencyLevel( 1 ).makeMap(); - @Nonnull @Override public String getInstalledVersion() { - return "${version}"; + if( version != null ) return version; + return version = ModList.get().getModContainerById( ComputerCraft.MOD_ID ) + .map( x -> x.getModInfo().getVersion().toString() ) + .orElse( "unknown" ); } @Override diff --git a/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java b/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java index 4eb417e8c..42fa4dcce 100644 --- a/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java +++ b/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java @@ -43,9 +43,10 @@ public static String getInstalledVersion() } @Nonnull + @Deprecated public static String getAPIVersion() { - return "${version}"; + return getInstalledVersion(); } /** diff --git a/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java b/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java index 0f164d4f0..fac72ecfa 100644 --- a/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java +++ b/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java @@ -84,7 +84,7 @@ public void channelActive( ChannelHandlerContext ctx ) throws Exception } if( !request.headers().contains( HttpHeaderNames.USER_AGENT ) ) { - request.headers().set( HttpHeaderNames.USER_AGENT, ComputerCraft.MOD_ID + "/" + ComputerCraft.getVersion() ); + request.headers().set( HttpHeaderNames.USER_AGENT, this.request.environment().getComputerEnvironment().getUserAgent() ); } request.headers().set( HttpHeaderNames.HOST, uri.getHost() ); request.headers().set( HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE ); diff --git a/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java b/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java index a4229bd05..e51054768 100644 --- a/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java +++ b/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java @@ -8,6 +8,8 @@ import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.io.InputStream; public interface IComputerEnvironment @@ -20,13 +22,20 @@ public interface IComputerEnvironment long getComputerSpaceLimit(); + @Nonnull String getHostString(); + @Nonnull + String getUserAgent(); + int assignNewID(); + @Nullable IWritableMount createSaveDirMount( String subPath, long capacity ); + @Nullable IMount createResourceMount( String domain, String subPath ); + @Nullable InputStream createResourceFile( String domain, String subPath ); } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java index 63bdf24cc..3b2959ca6 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java @@ -30,6 +30,7 @@ import net.minecraftforge.fml.server.ServerLifecycleHooks; import net.minecraftforge.versions.mcp.MCPVersion; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.InputStream; @@ -341,10 +342,18 @@ public long getComputerSpaceLimit() return ComputerCraft.computerSpaceLimit; } + @Nonnull @Override public String getHostString() { - return "ComputerCraft ${version} (Minecraft " + MCPVersion.getMCVersion() + ")"; + return String.format( "ComputerCraft %s (Minecraft %s)", ComputerCraftAPI.getInstalledVersion(), MCPVersion.getMCVersion() ); + } + + @Nonnull + @Override + public String getUserAgent() + { + return ComputerCraft.MOD_ID + "/" + ComputerCraftAPI.getInstalledVersion(); } @Override diff --git a/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java b/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java index c28cd3375..5b905a76b 100644 --- a/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java +++ b/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java @@ -6,6 +6,7 @@ package dan200.computercraft.shared.network; import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.shared.network.client.*; import dan200.computercraft.shared.network.server.*; import net.minecraft.entity.player.PlayerEntity; @@ -35,26 +36,26 @@ private NetworkHandler() public static void setup() { - String version = ComputerCraft.getVersion(); + String version = ComputerCraftAPI.getInstalledVersion(); network = NetworkRegistry.ChannelBuilder.named( new ResourceLocation( ComputerCraft.MOD_ID, "network" ) ) .networkProtocolVersion( () -> version ) .clientAcceptedVersions( version::equals ).serverAcceptedVersions( version::equals ) .simpleChannel(); // Server messages - registerMainThread( 0, ComputerActionServerMessage::new ); - registerMainThread( 1, QueueEventServerMessage::new ); - registerMainThread( 2, RequestComputerMessage::new ); - registerMainThread( 3, KeyEventServerMessage::new ); - registerMainThread( 4, MouseEventServerMessage::new ); + registerMainThread( 0, NetworkDirection.PLAY_TO_SERVER, ComputerActionServerMessage::new ); + registerMainThread( 1, NetworkDirection.PLAY_TO_SERVER, QueueEventServerMessage::new ); + registerMainThread( 2, NetworkDirection.PLAY_TO_SERVER, RequestComputerMessage::new ); + registerMainThread( 3, NetworkDirection.PLAY_TO_SERVER, KeyEventServerMessage::new ); + registerMainThread( 4, NetworkDirection.PLAY_TO_SERVER, MouseEventServerMessage::new ); // Client messages - registerMainThread( 10, ChatTableClientMessage::new ); - registerMainThread( 11, ComputerDataClientMessage::new ); - registerMainThread( 12, ComputerDeletedClientMessage::new ); - registerMainThread( 13, ComputerTerminalClientMessage::new ); - registerMainThread( 14, PlayRecordClientMessage.class, PlayRecordClientMessage::new ); - registerMainThread( 15, MonitorClientMessage.class, MonitorClientMessage::new ); + registerMainThread( 10, NetworkDirection.PLAY_TO_CLIENT, ChatTableClientMessage::new ); + registerMainThread( 11, NetworkDirection.PLAY_TO_CLIENT, ComputerDataClientMessage::new ); + registerMainThread( 12, NetworkDirection.PLAY_TO_CLIENT, ComputerDeletedClientMessage::new ); + registerMainThread( 13, NetworkDirection.PLAY_TO_CLIENT, ComputerTerminalClientMessage::new ); + registerMainThread( 14, NetworkDirection.PLAY_TO_CLIENT, PlayRecordClientMessage.class, PlayRecordClientMessage::new ); + registerMainThread( 15, NetworkDirection.PLAY_TO_CLIENT, MonitorClientMessage.class, MonitorClientMessage::new ); } public static void sendToPlayer( PlayerEntity player, NetworkMessage packet ) @@ -90,13 +91,14 @@ public static void sendToAllTracking( NetworkMessage packet, Chunk chunk ) * /** * Register packet, and a thread-unsafe handler for it. * - * @param The type of the packet to send. - * @param id The identifier for this packet type - * @param factory The factory for this type of packet. + * @param The type of the packet to send. + * @param id The identifier for this packet type. + * @param direction A network direction which will be asserted before any processing of this message occurs. + * @param factory The factory for this type of packet. */ - private static void registerMainThread( int id, Supplier factory ) + private static void registerMainThread( int id, NetworkDirection direction, Supplier factory ) { - registerMainThread( id, getType( factory ), buf -> { + registerMainThread( id, direction, getType( factory ), buf -> { T instance = factory.get(); instance.fromBytes( buf ); return instance; @@ -107,14 +109,15 @@ private static void registerMainThread( int id, Suppl * /** * Register packet, and a thread-unsafe handler for it. * - * @param The type of the packet to send. - * @param type The class of the type of packet to send. - * @param id The identifier for this packet type - * @param decoder The factory for this type of packet. + * @param The type of the packet to send. + * @param type The class of the type of packet to send. + * @param id The identifier for this packet type. + * @param direction A network direction which will be asserted before any processing of this message occurs + * @param decoder The factory for this type of packet. */ - private static void registerMainThread( int id, Class type, Function decoder ) + private static void registerMainThread( int id, NetworkDirection direction, Class type, Function decoder ) { - network.messageBuilder( type, id ) + network.messageBuilder( type, id, direction ) .encoder( NetworkMessage::toBytes ) .decoder( decoder ) .consumer( ( packet, contextSup ) -> { diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java index 4409fe6ad..b51277910 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java @@ -11,8 +11,8 @@ import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.common.ServerTerminal; import dan200.computercraft.shared.common.TileGeneric; -import dan200.computercraft.shared.util.CapabilityUtil; import dan200.computercraft.shared.network.client.TerminalState; +import dan200.computercraft.shared.util.CapabilityUtil; import dan200.computercraft.shared.util.NamedTileEntityType; import dan200.computercraft.shared.util.TickScheduler; import net.minecraft.entity.player.PlayerEntity; diff --git a/src/test/java/dan200/computercraft/core/computer/BasicEnvironment.java b/src/test/java/dan200/computercraft/core/computer/BasicEnvironment.java index c57226bc9..ccdcc751b 100644 --- a/src/test/java/dan200/computercraft/core/computer/BasicEnvironment.java +++ b/src/test/java/dan200/computercraft/core/computer/BasicEnvironment.java @@ -12,6 +12,7 @@ import dan200.computercraft.core.filesystem.JarMount; import dan200.computercraft.core.filesystem.MemoryMount; +import javax.annotation.Nonnull; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -73,10 +74,18 @@ public long getComputerSpaceLimit() return ComputerCraft.computerSpaceLimit; } + @Nonnull @Override public String getHostString() { - return "ComputerCraft ${version} (Test environment)"; + return "ComputerCraft 1.0 (Test environment)"; + } + + @Nonnull + @Override + public String getUserAgent() + { + return "ComputerCraft/1.0"; } @Override