From 30dc4cb38c11da3ea06f12f0dddbb6db8283b72b Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 14 Jan 2024 22:52:25 +0000 Subject: [PATCH] Simplify our networking multi-platform code Historically we used Forge's SimpleChannel methods (and PacketDistributor) to send the packets to the client. However, we don't need to do that - it is sufficient to convert it to a vanilla packet, and send the packet ourselves. Given we need to do this on Fabric, it makes sense to do this on Forge as well. This allows us to unify (and thus simplify) a lot of how packet sending works. At the same time, we also remove the handling of speaker audio during decoding. We originally did this to avoid the additional copy of audio data. However, this doesn't work on 1.20.4 (as packets aren't encoded/decoded on singleplayer), so it makes sense to do this Correctly(TM). This also allows us to get rid of ClientNetworkContext.get(). We do still need to service load this class (as Forge's networking isn't split up in the same way Fabric's is), but we'll be able to drop that in 1.20.4. Finally, we move the record playing code from ClientNetworkContext to ClientPlatformHelper. This means the network context no longer needs to be platform-specific! --- .../client/gui/AbstractComputerScreen.java | 4 +- .../client/gui/ClientInputHandler.java | 22 ++--- .../client/network/ClientNetworking.java | 25 ++++++ ...ext.java => ClientNetworkContextImpl.java} | 45 +++++----- .../client/platform/ClientPlatformHelper.java | 20 ++++- .../client/sound/DfpwmStream.java | 12 +-- .../client/sound/SpeakerInstance.java | 8 +- .../shared/command/text/TableBuilder.java | 4 +- .../shared/computer/core/ServerComputer.java | 4 +- .../computer/menu/ServerInputState.java | 6 +- .../network/client/ClientNetworkContext.java | 26 +----- .../client/SpeakerAudioClientMessage.java | 16 ++-- .../network/server/ServerNetworking.java | 82 +++++++++++++++++++ .../diskdrive/DiskDriveBlockEntity.java | 4 +- .../peripheral/monitor/MonitorWatcher.java | 6 +- .../speaker/SpeakerBlockEntity.java | 4 +- .../peripheral/speaker/SpeakerPeripheral.java | 10 +-- .../speaker/UpgradeSpeakerPeripheral.java | 4 +- .../shared/platform/PlatformHelper.java | 47 ++--------- .../pocket/core/PocketServerComputer.java | 10 +-- .../computercraft/TestPlatformHelper.java | 48 ++++------- .../client/sound/DfpwmStreamTest.java | 6 +- .../client/ComputerCraftClient.java | 4 +- .../platform/ClientNetworkHandlerImpl.java | 24 ------ .../platform/ClientPlatformHelperImpl.java | 17 +++- .../computercraft/shared/ComputerCraft.java | 4 +- .../shared/platform/PlatformHelperImpl.java | 41 ++-------- .../platform/ClientNetworkContextImpl.java | 24 ------ .../platform/ClientPlatformHelperImpl.java | 14 +++- .../shared/ForgeCommonHooks.java | 6 +- .../shared/platform/NetworkHandler.java | 63 +++++++------- .../shared/platform/PlatformHelperImpl.java | 28 +------ 32 files changed, 309 insertions(+), 329 deletions(-) create mode 100644 projects/common/src/client/java/dan200/computercraft/client/network/ClientNetworking.java rename projects/common/src/client/java/dan200/computercraft/client/platform/{AbstractClientNetworkContext.java => ClientNetworkContextImpl.java} (69%) create mode 100644 projects/common/src/main/java/dan200/computercraft/shared/network/server/ServerNetworking.java delete mode 100644 projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientNetworkHandlerImpl.java delete mode 100644 projects/forge/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java index 6d66a55fd..50f12c15e 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java @@ -7,7 +7,7 @@ package dan200.computercraft.client.gui; import dan200.computercraft.client.gui.widgets.ComputerSidebar; import dan200.computercraft.client.gui.widgets.DynamicImageButton; import dan200.computercraft.client.gui.widgets.TerminalWidget; -import dan200.computercraft.client.platform.ClientPlatformHelper; +import dan200.computercraft.client.network.ClientNetworking; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.InputHandler; @@ -207,7 +207,7 @@ public abstract class AbstractComputerScreen ext return; } - if (toUpload.size() > 0) UploadFileMessage.send(menu, toUpload, ClientPlatformHelper.get()::sendToServer); + if (toUpload.size() > 0) UploadFileMessage.send(menu, toUpload, ClientNetworking::sendToServer); } public void uploadResult(UploadResult result, @Nullable Component message) { diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/ClientInputHandler.java b/projects/common/src/client/java/dan200/computercraft/client/gui/ClientInputHandler.java index 0ddc4607e..bb6827616 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/ClientInputHandler.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/ClientInputHandler.java @@ -4,7 +4,7 @@ package dan200.computercraft.client.gui; -import dan200.computercraft.client.platform.ClientPlatformHelper; +import dan200.computercraft.client.network.ClientNetworking; import dan200.computercraft.shared.computer.core.InputHandler; import dan200.computercraft.shared.computer.menu.ComputerMenu; import dan200.computercraft.shared.network.server.ComputerActionServerMessage; @@ -29,51 +29,51 @@ public final class ClientInputHandler implements InputHandler { @Override public void turnOn() { - ClientPlatformHelper.get().sendToServer(new ComputerActionServerMessage(menu, ComputerActionServerMessage.Action.TURN_ON)); + ClientNetworking.sendToServer(new ComputerActionServerMessage(menu, ComputerActionServerMessage.Action.TURN_ON)); } @Override public void shutdown() { - ClientPlatformHelper.get().sendToServer(new ComputerActionServerMessage(menu, ComputerActionServerMessage.Action.SHUTDOWN)); + ClientNetworking.sendToServer(new ComputerActionServerMessage(menu, ComputerActionServerMessage.Action.SHUTDOWN)); } @Override public void reboot() { - ClientPlatformHelper.get().sendToServer(new ComputerActionServerMessage(menu, ComputerActionServerMessage.Action.REBOOT)); + ClientNetworking.sendToServer(new ComputerActionServerMessage(menu, ComputerActionServerMessage.Action.REBOOT)); } @Override public void queueEvent(String event, @Nullable Object[] arguments) { - ClientPlatformHelper.get().sendToServer(new QueueEventServerMessage(menu, event, arguments)); + ClientNetworking.sendToServer(new QueueEventServerMessage(menu, event, arguments)); } @Override public void keyDown(int key, boolean repeat) { - ClientPlatformHelper.get().sendToServer(new KeyEventServerMessage(menu, repeat ? KeyEventServerMessage.TYPE_REPEAT : KeyEventServerMessage.TYPE_DOWN, key)); + ClientNetworking.sendToServer(new KeyEventServerMessage(menu, repeat ? KeyEventServerMessage.TYPE_REPEAT : KeyEventServerMessage.TYPE_DOWN, key)); } @Override public void keyUp(int key) { - ClientPlatformHelper.get().sendToServer(new KeyEventServerMessage(menu, KeyEventServerMessage.TYPE_UP, key)); + ClientNetworking.sendToServer(new KeyEventServerMessage(menu, KeyEventServerMessage.TYPE_UP, key)); } @Override public void mouseClick(int button, int x, int y) { - ClientPlatformHelper.get().sendToServer(new MouseEventServerMessage(menu, MouseEventServerMessage.TYPE_CLICK, button, x, y)); + ClientNetworking.sendToServer(new MouseEventServerMessage(menu, MouseEventServerMessage.TYPE_CLICK, button, x, y)); } @Override public void mouseUp(int button, int x, int y) { - ClientPlatformHelper.get().sendToServer(new MouseEventServerMessage(menu, MouseEventServerMessage.TYPE_UP, button, x, y)); + ClientNetworking.sendToServer(new MouseEventServerMessage(menu, MouseEventServerMessage.TYPE_UP, button, x, y)); } @Override public void mouseDrag(int button, int x, int y) { - ClientPlatformHelper.get().sendToServer(new MouseEventServerMessage(menu, MouseEventServerMessage.TYPE_DRAG, button, x, y)); + ClientNetworking.sendToServer(new MouseEventServerMessage(menu, MouseEventServerMessage.TYPE_DRAG, button, x, y)); } @Override public void mouseScroll(int direction, int x, int y) { - ClientPlatformHelper.get().sendToServer(new MouseEventServerMessage(menu, MouseEventServerMessage.TYPE_SCROLL, direction, x, y)); + ClientNetworking.sendToServer(new MouseEventServerMessage(menu, MouseEventServerMessage.TYPE_SCROLL, direction, x, y)); } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/network/ClientNetworking.java b/projects/common/src/client/java/dan200/computercraft/client/network/ClientNetworking.java new file mode 100644 index 000000000..bf8070fa9 --- /dev/null +++ b/projects/common/src/client/java/dan200/computercraft/client/network/ClientNetworking.java @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.client.network; + +import dan200.computercraft.client.platform.ClientPlatformHelper; +import dan200.computercraft.shared.network.NetworkMessage; +import dan200.computercraft.shared.network.server.ServerNetworkContext; +import net.minecraft.client.Minecraft; + +/** + * Methods for sending packets from clients to the server. + */ +public class ClientNetworking { + /** + * Send a network message to the server. + * + * @param message The message to send. + */ + public static void sendToServer(NetworkMessage message) { + var connection = Minecraft.getInstance().getConnection(); + if (connection != null) connection.send(ClientPlatformHelper.get().createPacket(message)); + } +} diff --git a/projects/common/src/client/java/dan200/computercraft/client/platform/AbstractClientNetworkContext.java b/projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java similarity index 69% rename from projects/common/src/client/java/dan200/computercraft/client/platform/AbstractClientNetworkContext.java rename to projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java index 7c454b47f..941c56c73 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/platform/AbstractClientNetworkContext.java +++ b/projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java @@ -4,6 +4,7 @@ package dan200.computercraft.client.platform; +import com.google.auto.service.AutoService; import dan200.computercraft.client.ClientTableFormatter; import dan200.computercraft.client.gui.AbstractComputerScreen; import dan200.computercraft.client.gui.OptionScreen; @@ -17,30 +18,30 @@ import dan200.computercraft.shared.computer.upload.UploadResult; import dan200.computercraft.shared.network.client.ClientNetworkContext; import dan200.computercraft.shared.peripheral.monitor.MonitorBlockEntity; import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; -import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import javax.annotation.Nullable; +import java.nio.ByteBuffer; import java.util.UUID; /** - * The base implementation of {@link ClientNetworkContext}. - *

- * This should be extended by mod loader specific modules with the remaining abstract methods. + * The client-side implementation of {@link ClientNetworkContext}. */ -public abstract class AbstractClientNetworkContext implements ClientNetworkContext { +@AutoService(ClientNetworkContext.class) +public final class ClientNetworkContextImpl implements ClientNetworkContext { @Override - public final void handleChatTable(TableBuilder table) { + public void handleChatTable(TableBuilder table) { ClientTableFormatter.INSTANCE.display(table); } @Override - public final void handleComputerTerminal(int containerId, TerminalState terminal) { + public void handleComputerTerminal(int containerId, TerminalState terminal) { Player player = Minecraft.getInstance().player; if (player != null && player.containerMenu.containerId == containerId && player.containerMenu instanceof ComputerMenu menu) { menu.updateTerminal(terminal); @@ -48,7 +49,7 @@ public abstract class AbstractClientNetworkContext implements ClientNetworkConte } @Override - public final void handleMonitorData(BlockPos pos, TerminalState terminal) { + public void handleMonitorData(BlockPos pos, TerminalState terminal) { var player = Minecraft.getInstance().player; if (player == null) return; @@ -59,44 +60,46 @@ public abstract class AbstractClientNetworkContext implements ClientNetworkConte } @Override - public final void handlePocketComputerData(int instanceId, ComputerState state, int lightState, TerminalState terminal) { + public void handlePlayRecord(BlockPos pos, @Nullable SoundEvent sound, @Nullable String name) { + var mc = Minecraft.getInstance(); + ClientPlatformHelper.get().playStreamingMusic(pos, sound); + if (name != null) mc.gui.setNowPlaying(Component.literal(name)); + } + + @Override + public void handlePocketComputerData(int instanceId, ComputerState state, int lightState, TerminalState terminal) { var computer = ClientPocketComputers.get(instanceId, terminal.colour); computer.setState(state, lightState); if (terminal.hasTerminal()) computer.setTerminal(terminal); } @Override - public final void handlePocketComputerDeleted(int instanceId) { + public void handlePocketComputerDeleted(int instanceId) { ClientPocketComputers.remove(instanceId); } @Override - public final void handleSpeakerAudio(UUID source, SpeakerPosition.Message position, float volume) { - SpeakerManager.getSound(source).playAudio(reifyPosition(position), volume); + public void handleSpeakerAudio(UUID source, SpeakerPosition.Message position, float volume, ByteBuffer buffer) { + SpeakerManager.getSound(source).playAudio(reifyPosition(position), volume, buffer); } @Override - public final void handleSpeakerAudioPush(UUID source, ByteBuf buffer) { - SpeakerManager.getSound(source).pushAudio(buffer); - } - - @Override - public final void handleSpeakerMove(UUID source, SpeakerPosition.Message position) { + public void handleSpeakerMove(UUID source, SpeakerPosition.Message position) { SpeakerManager.moveSound(source, reifyPosition(position)); } @Override - public final void handleSpeakerPlay(UUID source, SpeakerPosition.Message position, ResourceLocation sound, float volume, float pitch) { + public void handleSpeakerPlay(UUID source, SpeakerPosition.Message position, ResourceLocation sound, float volume, float pitch) { SpeakerManager.getSound(source).playSound(reifyPosition(position), sound, volume, pitch); } @Override - public final void handleSpeakerStop(UUID source) { + public void handleSpeakerStop(UUID source) { SpeakerManager.stopSound(source); } @Override - public final void handleUploadResult(int containerId, UploadResult result, @Nullable Component errorMessage) { + public void handleUploadResult(int containerId, UploadResult result, @Nullable Component errorMessage) { var minecraft = Minecraft.getInstance(); var screen = OptionScreen.unwrap(minecraft.screen); diff --git a/projects/common/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelper.java b/projects/common/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelper.java index 70d5dc327..4200f9545 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelper.java +++ b/projects/common/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelper.java @@ -9,6 +9,10 @@ import dan200.computercraft.shared.network.NetworkMessage; import dan200.computercraft.shared.network.server.ServerNetworkContext; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ServerGamePacketListener; +import net.minecraft.sounds.SoundEvent; import javax.annotation.Nullable; @@ -18,11 +22,12 @@ public interface ClientPlatformHelper extends dan200.computercraft.impl.client.C } /** - * Send a network message to the server. + * Convert a serverbound {@link NetworkMessage} to a Minecraft {@link Packet}. * - * @param message The message to send. + * @param message The messsge to convert. + * @return The converted message. */ - void sendToServer(NetworkMessage message); + Packet createPacket(NetworkMessage message); /** * Render a {@link BakedModel}, using any loader-specific hooks. @@ -35,4 +40,13 @@ public interface ClientPlatformHelper extends dan200.computercraft.impl.client.C * @param tints Block colour tints to apply to the model. */ void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, @Nullable int[] tints); + + /** + * Play a record at a particular position. + * + * @param pos The position to play this record. + * @param sound The record to play, or {@code null} to stop it. + * @see net.minecraft.client.renderer.LevelRenderer#playStreamingMusic(SoundEvent, BlockPos) + */ + void playStreamingMusic(BlockPos pos, @Nullable SoundEvent sound); } diff --git a/projects/common/src/client/java/dan200/computercraft/client/sound/DfpwmStream.java b/projects/common/src/client/java/dan200/computercraft/client/sound/DfpwmStream.java index 40739c2ec..6cbca4c3a 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/sound/DfpwmStream.java +++ b/projects/common/src/client/java/dan200/computercraft/client/sound/DfpwmStream.java @@ -6,7 +6,7 @@ package dan200.computercraft.client.sound; import com.mojang.blaze3d.audio.Channel; import dan200.computercraft.shared.peripheral.speaker.SpeakerPeripheral; -import io.netty.buffer.ByteBuf; +import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import net.minecraft.client.sounds.AudioStream; import net.minecraft.client.sounds.SoundEngine; import org.lwjgl.BufferUtils; @@ -36,7 +36,7 @@ class DfpwmStream implements AudioStream { /** * The {@link Channel} which this sound is playing on. * - * @see SpeakerInstance#pushAudio(ByteBuf) + * @see SpeakerInstance#playAudio(SpeakerPosition, float, ByteBuffer) */ @Nullable Channel channel; @@ -44,7 +44,7 @@ class DfpwmStream implements AudioStream { /** * The underlying {@link SoundEngine} executor. * - * @see SpeakerInstance#pushAudio(ByteBuf) + * @see SpeakerInstance#playAudio(SpeakerPosition, float, ByteBuffer) * @see SoundEngine#executor */ @Nullable @@ -58,12 +58,12 @@ class DfpwmStream implements AudioStream { DfpwmStream() { } - void push(ByteBuf input) { - var readable = input.readableBytes(); + void push(ByteBuffer input) { + var readable = input.remaining(); var output = ByteBuffer.allocate(readable * 8).order(ByteOrder.nativeOrder()); for (var i = 0; i < readable; i++) { - var inputByte = input.readByte(); + var inputByte = input.get(); for (var j = 0; j < 8; j++) { var currentBit = (inputByte & 1) != 0; var target = currentBit ? 127 : -128; diff --git a/projects/common/src/client/java/dan200/computercraft/client/sound/SpeakerInstance.java b/projects/common/src/client/java/dan200/computercraft/client/sound/SpeakerInstance.java index ca336b4d1..472bcffb1 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/sound/SpeakerInstance.java +++ b/projects/common/src/client/java/dan200/computercraft/client/sound/SpeakerInstance.java @@ -7,11 +7,11 @@ package dan200.computercraft.client.sound; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.core.util.Nullability; import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; -import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; import javax.annotation.Nullable; +import java.nio.ByteBuffer; /** * An instance of a speaker, which is either playing a {@link DfpwmStream} stream or a normal sound. @@ -25,7 +25,7 @@ public class SpeakerInstance { SpeakerInstance() { } - public synchronized void pushAudio(ByteBuf buffer) { + private void pushAudio(ByteBuffer buffer) { var sound = this.sound; var stream = currentStream; @@ -43,7 +43,9 @@ public class SpeakerInstance { } } - public void playAudio(SpeakerPosition position, float volume) { + public void playAudio(SpeakerPosition position, float volume, ByteBuffer buffer) { + pushAudio(buffer); + var soundManager = Minecraft.getInstance().getSoundManager(); if (sound != null && sound.stream != currentStream) { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java b/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java index fa683ab1f..2428e5637 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java @@ -7,7 +7,7 @@ package dan200.computercraft.shared.command.text; import dan200.computercraft.core.util.Nullability; import dan200.computercraft.shared.command.CommandUtils; import dan200.computercraft.shared.network.client.ChatTableClientMessage; -import dan200.computercraft.shared.platform.PlatformHelper; +import dan200.computercraft.shared.network.server.ServerNetworking; import net.minecraft.commands.CommandSourceStack; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; @@ -105,7 +105,7 @@ public class TableBuilder { if (CommandUtils.isPlayer(source)) { trim(18); var player = (ServerPlayer) Nullability.assertNonNull(source.getEntity()); - PlatformHelper.get().sendToPlayer(new ChatTableClientMessage(this), player); + ServerNetworking.sendToPlayer(new ChatTableClientMessage(this), player); } else { trim(100); new ServerTableFormatter(source).display(this); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java index 23eb06216..72bb03570 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java @@ -20,7 +20,7 @@ import dan200.computercraft.shared.config.Config; import dan200.computercraft.shared.network.NetworkMessage; import dan200.computercraft.shared.network.client.ClientNetworkContext; import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage; -import dan200.computercraft.shared.platform.PlatformHelper; +import dan200.computercraft.shared.network.server.ServerNetworking; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -142,7 +142,7 @@ public class ServerComputer implements InputHandler, ComputerEnvironment { for (var player : server.getPlayerList().getPlayers()) { if (player.containerMenu instanceof ComputerMenu && ((ComputerMenu) player.containerMenu).getComputer() == this) { - PlatformHelper.get().sendToPlayer(createPacket.apply(player.containerMenu), player); + ServerNetworking.sendToPlayer(createPacket.apply(player.containerMenu), player); } } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/menu/ServerInputState.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/menu/ServerInputState.java index f9fa8e1ed..21753d281 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/computer/menu/ServerInputState.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/menu/ServerInputState.java @@ -11,7 +11,7 @@ import dan200.computercraft.shared.computer.upload.FileSlice; import dan200.computercraft.shared.computer.upload.FileUpload; import dan200.computercraft.shared.computer.upload.UploadResult; import dan200.computercraft.shared.network.client.UploadResultMessage; -import dan200.computercraft.shared.platform.PlatformHelper; +import dan200.computercraft.shared.network.server.ServerNetworking; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; import net.minecraft.network.chat.Component; @@ -138,7 +138,7 @@ public class ServerInputState im return; } - PlatformHelper.get().sendToPlayer(finishUpload(uploader), uploader); + ServerNetworking.sendToPlayer(finishUpload(uploader), uploader); } private UploadResultMessage finishUpload(ServerPlayer player) { @@ -159,7 +159,7 @@ public class ServerInputState im toUpload.stream().map(x -> new TransferredFile(x.getName(), new ByteBufferChannel(x.getBytes()))).toList(), () -> { if (player.isAlive() && player.containerMenu == owner) { - PlatformHelper.get().sendToPlayer(UploadResultMessage.consumed(owner), player); + ServerNetworking.sendToPlayer(UploadResultMessage.consumed(owner), player); } }), }); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/network/client/ClientNetworkContext.java b/projects/common/src/main/java/dan200/computercraft/shared/network/client/ClientNetworkContext.java index a0268454f..d981544d4 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/network/client/ClientNetworkContext.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/network/client/ClientNetworkContext.java @@ -4,30 +4,24 @@ package dan200.computercraft.shared.network.client; -import dan200.computercraft.impl.Services; import dan200.computercraft.shared.command.text.TableBuilder; import dan200.computercraft.shared.computer.core.ComputerState; import dan200.computercraft.shared.computer.terminal.TerminalState; import dan200.computercraft.shared.computer.upload.UploadResult; import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; -import io.netty.buffer.ByteBuf; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; import javax.annotation.Nullable; +import java.nio.ByteBuffer; import java.util.UUID; /** * The context under which clientbound packets are evaluated. */ public interface ClientNetworkContext { - static ClientNetworkContext get() { - var instance = Instance.INSTANCE; - return instance == null ? Services.raise(ClientNetworkContext.class, Instance.ERROR) : instance; - } - void handleChatTable(TableBuilder table); void handleComputerTerminal(int containerId, TerminalState terminal); @@ -40,9 +34,7 @@ public interface ClientNetworkContext { void handlePocketComputerDeleted(int instanceId); - void handleSpeakerAudio(UUID source, SpeakerPosition.Message position, float volume); - - void handleSpeakerAudioPush(UUID source, ByteBuf buffer); + void handleSpeakerAudio(UUID source, SpeakerPosition.Message position, float volume, ByteBuffer audio); void handleSpeakerMove(UUID source, SpeakerPosition.Message position); @@ -51,18 +43,4 @@ public interface ClientNetworkContext { void handleSpeakerStop(UUID source); void handleUploadResult(int containerId, UploadResult result, @Nullable Component errorMessage); - - final class Instance { - static final @Nullable ClientNetworkContext INSTANCE; - static final @Nullable Throwable ERROR; - - static { - var helper = Services.tryLoad(ClientNetworkContext.class); - INSTANCE = helper.instance(); - ERROR = helper.error(); - } - - private Instance() { - } - } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/network/client/SpeakerAudioClientMessage.java b/projects/common/src/main/java/dan200/computercraft/shared/network/client/SpeakerAudioClientMessage.java index c98f4366a..6de8a0b57 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/network/client/SpeakerAudioClientMessage.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/network/client/SpeakerAudioClientMessage.java @@ -11,12 +11,9 @@ import dan200.computercraft.shared.peripheral.speaker.SpeakerBlockEntity; import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition; import net.minecraft.network.FriendlyByteBuf; -import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.UUID; -import static dan200.computercraft.core.util.Nullability.assertNonNull; - /** * Starts a sound on the client. *

@@ -27,7 +24,7 @@ import static dan200.computercraft.core.util.Nullability.assertNonNull; public class SpeakerAudioClientMessage implements NetworkMessage { private final UUID source; private final SpeakerPosition.Message pos; - private final @Nullable ByteBuffer content; + private final ByteBuffer content; private final float volume; public SpeakerAudioClientMessage(UUID source, SpeakerPosition pos, float volume, ByteBuffer content) { @@ -42,10 +39,9 @@ public class SpeakerAudioClientMessage implements NetworkMessage message, ServerPlayer player) { + player.connection.send(PlatformHelper.get().createPacket(message)); + } + + /** + * Send a message to a set of players. + * + * @param message The message to send. + * @param players The players to send it to. + */ + public static void sendToPlayers(NetworkMessage message, Collection players) { + if (players.isEmpty()) return; + var packet = PlatformHelper.get().createPacket(message); + for (var player : players) player.connection.send(packet); + } + + /** + * Send a message to all players. + * + * @param message The message to send. + * @param server The current server. + */ + public static void sendToAllPlayers(NetworkMessage message, MinecraftServer server) { + server.getPlayerList().broadcastAll(PlatformHelper.get().createPacket(message)); + } + + /** + * Send a message to all players around a point. + * + * @param message The message to send. + * @param level The level the point is in. + * @param pos The centre position. + * @param distance The distance to the centre players must be within. + */ + public static void sendToAllAround(NetworkMessage message, ServerLevel level, Vec3 pos, float distance) { + level.getServer().getPlayerList().broadcast(null, pos.x, pos.y, pos.z, distance, level.dimension(), PlatformHelper.get().createPacket(message)); + } + + /** + * Send a message to all players tracking a chunk. + * + * @param message The message to send. + * @param chunk The chunk players must be tracking. + */ + public static void sendToAllTracking(NetworkMessage message, LevelChunk chunk) { + var packet = PlatformHelper.get().createPacket(message); + for (var player : ((ServerChunkCache) chunk.getLevel().getChunkSource()).chunkMap.getPlayers(chunk.getPos(), false)) { + player.connection.send(packet); + } + } +} diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlockEntity.java index e8d1c75c6..0ea28530a 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlockEntity.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlockEntity.java @@ -11,7 +11,7 @@ import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.shared.common.AbstractContainerBlockEntity; import dan200.computercraft.shared.network.client.PlayRecordClientMessage; -import dan200.computercraft.shared.platform.PlatformHelper; +import dan200.computercraft.shared.network.server.ServerNetworking; import dan200.computercraft.shared.util.WorldUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -315,7 +315,7 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity { } private void sendMessage(PlayRecordClientMessage message) { - PlatformHelper.get().sendToAllAround(message, (ServerLevel) getLevel(), Vec3.atCenterOf(getBlockPos()), 64); + ServerNetworking.sendToAllAround(message, (ServerLevel) getLevel(), Vec3.atCenterOf(getBlockPos()), 64); } @Override diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java index bf3f56be5..499c2acf8 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java @@ -7,7 +7,7 @@ package dan200.computercraft.shared.peripheral.monitor; import dan200.computercraft.shared.computer.terminal.TerminalState; import dan200.computercraft.shared.config.Config; import dan200.computercraft.shared.network.client.MonitorClientMessage; -import dan200.computercraft.shared.platform.PlatformHelper; +import dan200.computercraft.shared.network.server.ServerNetworking; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.chunk.LevelChunk; @@ -40,7 +40,7 @@ public final class MonitorWatcher { if (serverMonitor == null || monitor.enqueued) continue; var state = getState(monitor, serverMonitor); - PlatformHelper.get().sendToPlayer(new MonitorClientMessage(monitor.getBlockPos(), state), player); + ServerNetworking.sendToPlayer(new MonitorClientMessage(monitor.getBlockPos(), state), player); } } @@ -66,7 +66,7 @@ public final class MonitorWatcher { } var state = getState(tile, monitor); - PlatformHelper.get().sendToAllTracking(new MonitorClientMessage(pos, state), chunk); + ServerNetworking.sendToAllTracking(new MonitorClientMessage(pos, state), chunk); limit -= state.size(); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlockEntity.java index edb3593b1..972f67be5 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlockEntity.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlockEntity.java @@ -7,7 +7,7 @@ package dan200.computercraft.shared.peripheral.speaker; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.core.util.Nullability; import dan200.computercraft.shared.network.client.SpeakerStopClientMessage; -import dan200.computercraft.shared.platform.PlatformHelper; +import dan200.computercraft.shared.network.server.ServerNetworking; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; @@ -32,7 +32,7 @@ public class SpeakerBlockEntity extends BlockEntity { public void setRemoved() { super.setRemoved(); if (level != null && !level.isClientSide) { - PlatformHelper.get().sendToAllPlayers(new SpeakerStopClientMessage(peripheral.getSource()), Nullability.assertNonNull(getLevel().getServer())); + ServerNetworking.sendToAllPlayers(new SpeakerStopClientMessage(peripheral.getSource()), Nullability.assertNonNull(getLevel().getServer())); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java index acda7fbe0..9791b9977 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java @@ -17,7 +17,7 @@ import dan200.computercraft.shared.network.client.SpeakerAudioClientMessage; import dan200.computercraft.shared.network.client.SpeakerMoveClientMessage; import dan200.computercraft.shared.network.client.SpeakerPlayClientMessage; import dan200.computercraft.shared.network.client.SpeakerStopClientMessage; -import dan200.computercraft.shared.platform.PlatformHelper; +import dan200.computercraft.shared.network.server.ServerNetworking; import dan200.computercraft.shared.util.PauseAwareTimer; import net.minecraft.ResourceLocationException; import net.minecraft.core.BlockPos; @@ -116,14 +116,14 @@ public abstract class SpeakerPeripheral implements IPeripheral { // Stop the speaker and nuke the position, so we don't update it again. if (shouldStop && lastPosition != null) { lastPosition = null; - PlatformHelper.get().sendToAllPlayers(new SpeakerStopClientMessage(getSource()), server); + ServerNetworking.sendToAllPlayers(new SpeakerStopClientMessage(getSource()), server); return; } var now = PauseAwareTimer.getTime(); if (sound != null) { lastPlayTime = clock; - PlatformHelper.get().sendToAllAround( + ServerNetworking.sendToAllAround( new SpeakerPlayClientMessage(getSource(), position, sound.sound, sound.volume, sound.pitch), (ServerLevel) level, pos, sound.volume * 16 ); @@ -131,7 +131,7 @@ public abstract class SpeakerPeripheral implements IPeripheral { } else if (dfpwmState != null && dfpwmState.shouldSendPending(now)) { // If clients need to receive another batch of audio, send it and then notify computers our internal buffer is // free again. - PlatformHelper.get().sendToAllTracking( + ServerNetworking.sendToAllTracking( new SpeakerAudioClientMessage(getSource(), position, dfpwmState.getVolume(), dfpwmState.pullPending(now)), level.getChunkAt(BlockPos.containing(pos)) ); @@ -150,7 +150,7 @@ public abstract class SpeakerPeripheral implements IPeripheral { // in the last second. if (lastPosition != null && (clock - lastPositionTime) >= 20 && !lastPosition.withinDistance(position, 0.1)) { // TODO: What to do when entities move away? How do we notify people left behind that they're gone. - PlatformHelper.get().sendToAllTracking( + ServerNetworking.sendToAllTracking( new SpeakerMoveClientMessage(getSource(), position), level.getChunkAt(BlockPos.containing(pos)) ); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/UpgradeSpeakerPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/UpgradeSpeakerPeripheral.java index 64b861de1..8fb3abb7d 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/UpgradeSpeakerPeripheral.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/UpgradeSpeakerPeripheral.java @@ -6,7 +6,7 @@ package dan200.computercraft.shared.peripheral.speaker; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.shared.network.client.SpeakerStopClientMessage; -import dan200.computercraft.shared.platform.PlatformHelper; +import dan200.computercraft.shared.network.server.ServerNetworking; /** @@ -25,6 +25,6 @@ public abstract class UpgradeSpeakerPeripheral extends SpeakerPeripheral { var server = level.getServer(); if (server == null || server.isStopped()) return; - PlatformHelper.get().sendToAllPlayers(new SpeakerStopClientMessage(getSource()), server); + ServerNetworking.sendToAllPlayers(new SpeakerStopClientMessage(getSource()), server); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java index b621a36b3..8ed71f6da 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java @@ -20,9 +20,10 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Registry; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayerGameMode; @@ -44,12 +45,10 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import javax.annotation.Nullable; -import java.util.Collection; import java.util.List; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -178,46 +177,12 @@ public interface PlatformHelper extends dan200.computercraft.impl.PlatformHelper > MessageType createMessageType(int id, ResourceLocation channel, Class klass, FriendlyByteBuf.Reader reader); /** - * Send a message to a specific player. + * Convert a clientbound {@link NetworkMessage} to a Minecraft {@link Packet}. * - * @param message The message to send. - * @param player The player to send it to. + * @param message The messsge to convert. + * @return The converted message. */ - void sendToPlayer(NetworkMessage message, ServerPlayer player); - - /** - * Send a message to a set of players. - * - * @param message The message to send. - * @param players The players to send it to. - */ - void sendToPlayers(NetworkMessage message, Collection players); - - /** - * Send a message to all players. - * - * @param message The message to send. - * @param server The current server. - */ - void sendToAllPlayers(NetworkMessage message, MinecraftServer server); - - /** - * Send a message to all players around a point. - * - * @param message The message to send. - * @param level The level the point is in. - * @param pos The centre position. - * @param distance The distance to the centre players must be within. - */ - void sendToAllAround(NetworkMessage message, ServerLevel level, Vec3 pos, float distance); - - /** - * Send a message to all players tracking a chunk. - * - * @param message The message to send. - * @param chunk The chunk players must be tracking. - */ - void sendToAllTracking(NetworkMessage message, LevelChunk chunk); + Packet createPacket(NetworkMessage message); /** * Create a {@link ComponentAccess} for surrounding peripherals. diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java index 35db4abdd..97a7f9c6a 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java @@ -15,7 +15,7 @@ import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.config.Config; import dan200.computercraft.shared.network.client.PocketComputerDataMessage; import dan200.computercraft.shared.network.client.PocketComputerDeletedClientMessage; -import dan200.computercraft.shared.platform.PlatformHelper; +import dan200.computercraft.shared.network.server.ServerNetworking; import dan200.computercraft.shared.pocket.items.PocketComputerItem; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; @@ -161,7 +161,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces if (sendState) { // Broadcast the state to all players tracking.addAll(getLevel().players()); - PlatformHelper.get().sendToPlayers(new PocketComputerDataMessage(this, false), tracking); + ServerNetworking.sendToPlayers(new PocketComputerDataMessage(this, false), tracking); } else { // Broadcast the state to new players. List added = new ArrayList<>(); @@ -169,7 +169,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces if (tracking.add(player)) added.add(player); } if (!added.isEmpty()) { - PlatformHelper.get().sendToPlayers(new PocketComputerDataMessage(this, false), added); + ServerNetworking.sendToPlayers(new PocketComputerDataMessage(this, false), added); } } } @@ -180,13 +180,13 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces if (entity instanceof ServerPlayer player && entity.isAlive()) { // Broadcast the terminal to the current player. - PlatformHelper.get().sendToPlayer(new PocketComputerDataMessage(this, true), player); + ServerNetworking.sendToPlayer(new PocketComputerDataMessage(this, true), player); } } @Override protected void onRemoved() { super.onRemoved(); - PlatformHelper.get().sendToAllPlayers(new PocketComputerDeletedClientMessage(getInstanceID()), getLevel().getServer()); + ServerNetworking.sendToAllPlayers(new PocketComputerDeletedClientMessage(getInstanceID()), getLevel().getServer()); } } diff --git a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java index dfc7382f5..815c716db 100644 --- a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java +++ b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java @@ -18,15 +18,18 @@ import dan200.computercraft.shared.network.NetworkMessage; import dan200.computercraft.shared.network.client.ClientNetworkContext; import dan200.computercraft.shared.network.container.ContainerData; import dan200.computercraft.shared.platform.*; +import io.netty.buffer.Unpooled; import net.minecraft.commands.synchronization.ArgumentTypeInfo; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.TagKey; @@ -47,12 +50,10 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import javax.annotation.Nullable; -import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.function.BiFunction; @@ -129,31 +130,6 @@ public class TestPlatformHelper extends AbstractComputerCraftAPI implements Plat throw new UnsupportedOperationException("Cannot register ArgumentTypeInfo inside tests"); } - @Override - public void sendToPlayer(NetworkMessage message, ServerPlayer player) { - throw new UnsupportedOperationException("Cannot send NetworkMessages inside tests"); - } - - @Override - public void sendToPlayers(NetworkMessage message, Collection players) { - throw new UnsupportedOperationException("Cannot send NetworkMessages inside tests"); - } - - @Override - public void sendToAllPlayers(NetworkMessage message, MinecraftServer server) { - throw new UnsupportedOperationException("Cannot send NetworkMessages inside tests"); - } - - @Override - public void sendToAllAround(NetworkMessage message, ServerLevel level, Vec3 pos, float distance) { - throw new UnsupportedOperationException("Cannot send NetworkMessages inside tests"); - } - - @Override - public void sendToAllTracking(NetworkMessage message, LevelChunk chunk) { - throw new UnsupportedOperationException("Cannot send NetworkMessages inside tests"); - } - @Override public List> getDyeTags() { throw new UnsupportedOperationException("Cannot query tags inside tests"); @@ -169,11 +145,21 @@ public class TestPlatformHelper extends AbstractComputerCraftAPI implements Plat throw new UnsupportedOperationException("Cannot open menu inside tests"); } + record TypeImpl>( + ResourceLocation id, Function reader + ) implements MessageType { + } + @Override public > MessageType createMessageType(int id, ResourceLocation channel, Class klass, FriendlyByteBuf.Reader reader) { - record TypeImpl>(Function reader) implements MessageType { - } - return new TypeImpl<>(reader); + return new TypeImpl<>(channel, reader); + } + + @Override + public Packet createPacket(NetworkMessage message) { + var buf = new FriendlyByteBuf(Unpooled.buffer()); + message.write(buf); + return new ClientboundCustomPayloadPacket(((TypeImpl) message.type()).id(), buf); } @Override diff --git a/projects/common/src/test/java/dan200/computercraft/client/sound/DfpwmStreamTest.java b/projects/common/src/test/java/dan200/computercraft/client/sound/DfpwmStreamTest.java index 2cb2f72b3..de1f89b8e 100644 --- a/projects/common/src/test/java/dan200/computercraft/client/sound/DfpwmStreamTest.java +++ b/projects/common/src/test/java/dan200/computercraft/client/sound/DfpwmStreamTest.java @@ -4,9 +4,10 @@ package dan200.computercraft.client.sound; -import io.netty.buffer.ByteBufAllocator; import org.junit.jupiter.api.Test; +import java.nio.ByteBuffer; + import static org.junit.jupiter.api.Assertions.assertEquals; public class DfpwmStreamTest { @@ -14,8 +15,7 @@ public class DfpwmStreamTest { public void testDecodesBytes() { var stream = new DfpwmStream(); - var input = ByteBufAllocator.DEFAULT.buffer(); - input.writeBytes(new byte[]{ 43, -31, 33, 44, 30, -16, -85, 23, -3, -55, 46, -70, 68, -67, 74, -96, -68, 16, 94, -87, -5, 87, 11, -16, 19, 92, 85, -71, 126, 5, -84, 64, 17, -6, 85, -11, -1, -87, -12, 1, 85, -56, 33, -80, 82, 104, -93, 17, 126, 23, 91, -30, 37, -32, 117, -72, -58, 11, -76, 19, -108, 86, -65, -10, -1, -68, -25, 10, -46, 85, 124, -54, 15, -24, 43, -94, 117, 63, -36, 15, -6, 88, 87, -26, -83, 106, 41, 13, -28, -113, -10, -66, 119, -87, -113, 68, -55, 40, -107, 62, 20, 72, 3, -96, 114, -87, -2, 39, -104, 30, 20, 42, 84, 24, 47, 64, 43, 61, -35, 95, -65, 42, 61, 42, -50, 4, -9, 81 }); + var input = ByteBuffer.wrap(new byte[]{ 43, -31, 33, 44, 30, -16, -85, 23, -3, -55, 46, -70, 68, -67, 74, -96, -68, 16, 94, -87, -5, 87, 11, -16, 19, 92, 85, -71, 126, 5, -84, 64, 17, -6, 85, -11, -1, -87, -12, 1, 85, -56, 33, -80, 82, 104, -93, 17, 126, 23, 91, -30, 37, -32, 117, -72, -58, 11, -76, 19, -108, 86, -65, -10, -1, -68, -25, 10, -46, 85, 124, -54, 15, -24, 43, -94, 117, 63, -36, 15, -6, 88, 87, -26, -83, 106, 41, 13, -28, -113, -10, -66, 119, -87, -113, 68, -55, 40, -107, 62, 20, 72, 3, -96, 114, -87, -2, 39, -104, 30, 20, 42, 84, 24, 47, 64, 43, 61, -35, 95, -65, 42, 61, 42, -50, 4, -9, 81 }); stream.push(input); var buffer = stream.read(1024 + 1); diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java b/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java index d882323cb..eb35b3208 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java @@ -6,6 +6,7 @@ package dan200.computercraft.client; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.client.model.CustomModelLoader; +import dan200.computercraft.impl.Services; import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.config.ConfigSpec; import dan200.computercraft.shared.network.NetworkMessages; @@ -31,9 +32,10 @@ import static dan200.computercraft.core.util.Nullability.assertNonNull; public class ComputerCraftClient { public static void init() { + var clientNetwork = Services.load(ClientNetworkContext.class); for (var type : NetworkMessages.getClientbound()) { ClientPlayNetworking.registerGlobalReceiver( - FabricMessageType.toFabricType(type), (packet, player, responseSender) -> packet.payload().handle(ClientNetworkContext.get()) + FabricMessageType.toFabricType(type), (packet, player, responseSender) -> packet.payload().handle(clientNetwork) ); } diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientNetworkHandlerImpl.java b/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientNetworkHandlerImpl.java deleted file mode 100644 index a16a007be..000000000 --- a/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientNetworkHandlerImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -package dan200.computercraft.client.platform; - -import com.google.auto.service.AutoService; -import dan200.computercraft.shared.network.client.ClientNetworkContext; -import net.minecraft.client.Minecraft; -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.sounds.SoundEvent; - -import javax.annotation.Nullable; - -@AutoService(ClientNetworkContext.class) -public class ClientNetworkHandlerImpl extends AbstractClientNetworkContext { - @Override - public void handlePlayRecord(BlockPos pos, @Nullable SoundEvent sound, @Nullable String name) { - var mc = Minecraft.getInstance(); - mc.levelRenderer.playStreamingMusic(sound, pos); - if (name != null) mc.gui.setNowPlaying(Component.literal(name)); - } -} diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java b/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java index ba3af63fa..8452d9e58 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java @@ -12,13 +12,19 @@ import dan200.computercraft.shared.network.NetworkMessage; import dan200.computercraft.shared.network.server.ServerNetworkContext; import dan200.computercraft.shared.platform.FabricMessageType; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.Sheets; import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelManager; +import net.minecraft.core.BlockPos; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ServerGamePacketListener; import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; import net.minecraft.util.RandomSource; import javax.annotation.Nullable; @@ -28,8 +34,10 @@ public class ClientPlatformHelperImpl implements ClientPlatformHelper { private static final RandomSource random = RandomSource.create(0); @Override - public void sendToServer(NetworkMessage message) { - ClientPlayNetworking.send(FabricMessageType.toFabricPacket(message)); + public Packet createPacket(NetworkMessage message) { + var buf = PacketByteBufs.create(); + message.write(buf); + return ClientPlayNetworking.createC2SPacket(FabricMessageType.toFabricType(message.type()).getId(), buf); } @Override @@ -55,4 +63,9 @@ public class ClientPlatformHelperImpl implements ClientPlatformHelper { ModelRenderer.renderQuads(transform, buffer, model.getQuads(null, face, random), lightmapCoord, overlayLight, tints); } } + + @Override + public void playStreamingMusic(BlockPos pos, @Nullable SoundEvent sound) { + Minecraft.getInstance().levelRenderer.playStreamingMusic(sound, pos); + } } diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java index 8181742f0..d0e6f2ab4 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java @@ -15,6 +15,7 @@ import dan200.computercraft.shared.config.ConfigSpec; import dan200.computercraft.shared.details.FluidDetails; import dan200.computercraft.shared.network.NetworkMessages; import dan200.computercraft.shared.network.client.UpgradesLoadedMessage; +import dan200.computercraft.shared.network.server.ServerNetworking; import dan200.computercraft.shared.peripheral.commandblock.CommandBlockPeripheral; import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods; import dan200.computercraft.shared.peripheral.modem.wired.CableBlockEntity; @@ -22,7 +23,6 @@ import dan200.computercraft.shared.peripheral.modem.wired.WiredModemFullBlockEnt import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemBlockEntity; import dan200.computercraft.shared.platform.FabricConfigFile; import dan200.computercraft.shared.platform.FabricMessageType; -import dan200.computercraft.shared.platform.PlatformHelper; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; @@ -92,7 +92,7 @@ public class ComputerCraft { CommonHooks.onServerStopped(); ((FabricConfigFile) ConfigSpec.serverSpec).unload(); }); - ServerLifecycleEvents.SYNC_DATA_PACK_CONTENTS.register((player, joined) -> PlatformHelper.get().sendToPlayer(new UpgradesLoadedMessage(), player)); + ServerLifecycleEvents.SYNC_DATA_PACK_CONTENTS.register((player, joined) -> ServerNetworking.sendToPlayer(new UpgradesLoadedMessage(), player)); ServerTickEvents.START_SERVER_TICK.register(CommonHooks::onServerTickStart); ServerTickEvents.START_SERVER_TICK.register(s -> CommonHooks.onServerTickEnd()); diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java index 06991e325..3ed6f52c0 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java @@ -51,8 +51,6 @@ import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.ItemTags; @@ -77,13 +75,15 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.Vec3; import javax.annotation.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; import java.util.function.*; @AutoService(dan200.computercraft.impl.PlatformHelper.class) @@ -177,42 +177,13 @@ public class PlatformHelperImpl implements PlatformHelper { return new FabricMessageType<>(channel, reader); } - private Packet encodeClientbound(NetworkMessage message) { + @Override + public Packet createPacket(NetworkMessage message) { var buf = PacketByteBufs.create(); message.write(buf); return ServerPlayNetworking.createS2CPacket(FabricMessageType.toFabricType(message.type()).getId(), buf); } - @Override - public void sendToPlayer(NetworkMessage message, ServerPlayer player) { - player.connection.send(encodeClientbound(message)); - } - - @Override - public void sendToPlayers(NetworkMessage message, Collection players) { - if (players.isEmpty()) return; - var packet = encodeClientbound(message); - for (var player : players) player.connection.send(packet); - } - - @Override - public void sendToAllPlayers(NetworkMessage message, MinecraftServer server) { - server.getPlayerList().broadcastAll(encodeClientbound(message)); - } - - @Override - public void sendToAllAround(NetworkMessage message, ServerLevel level, Vec3 pos, float distance) { - level.getServer().getPlayerList().broadcast(null, pos.x, pos.y, pos.z, distance, level.dimension(), encodeClientbound(message)); - } - - @Override - public void sendToAllTracking(NetworkMessage message, LevelChunk chunk) { - var packet = encodeClientbound(message); - for (var player : ((ServerChunkCache) chunk.getLevel().getChunkSource()).chunkMap.getPlayers(chunk.getPos(), false)) { - player.connection.send(packet); - } - } - @Override public ComponentAccess createPeripheralAccess(BlockEntity owner, Consumer invalidate) { return new PeripheralAccessImpl(owner, invalidate); diff --git a/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java b/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java deleted file mode 100644 index 79057e24b..000000000 --- a/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -package dan200.computercraft.client.platform; - -import com.google.auto.service.AutoService; -import dan200.computercraft.shared.network.client.ClientNetworkContext; -import net.minecraft.client.Minecraft; -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.sounds.SoundEvent; - -import javax.annotation.Nullable; - -@AutoService(ClientNetworkContext.class) -public class ClientNetworkContextImpl extends AbstractClientNetworkContext { - @Override - public void handlePlayRecord(BlockPos pos, @Nullable SoundEvent sound, @Nullable String name) { - var mc = Minecraft.getInstance(); - mc.levelRenderer.playStreamingMusic(sound, pos, null); - if (name != null) mc.gui.setNowPlaying(Component.literal(name)); - } -} diff --git a/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java b/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java index aaa41c4a4..612a79225 100644 --- a/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java +++ b/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java @@ -11,11 +11,16 @@ import dan200.computercraft.client.render.ModelRenderer; import dan200.computercraft.shared.network.NetworkMessage; import dan200.computercraft.shared.network.server.ServerNetworkContext; import dan200.computercraft.shared.platform.NetworkHandler; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelManager; +import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ServerGamePacketListener; import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; import net.minecraft.util.RandomSource; import net.minecraft.world.item.ItemStack; import net.minecraftforge.client.model.data.ModelData; @@ -39,8 +44,8 @@ public class ClientPlatformHelperImpl implements ClientPlatformHelper { } @Override - public void sendToServer(NetworkMessage message) { - NetworkHandler.sendToServer(message); + public Packet createPacket(NetworkMessage message) { + return NetworkHandler.createServerboundPacket(message); } @Override @@ -54,4 +59,9 @@ public class ClientPlatformHelperImpl implements ClientPlatformHelper { } } } + + @Override + public void playStreamingMusic(BlockPos pos, @Nullable SoundEvent sound) { + Minecraft.getInstance().levelRenderer.playStreamingMusic(sound, pos, null); + } } diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java b/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java index d5f1a4ed5..ed36e39c7 100644 --- a/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java +++ b/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java @@ -9,6 +9,7 @@ import dan200.computercraft.shared.command.CommandComputerCraft; import dan200.computercraft.shared.computer.blocks.ComputerBlockEntity; import dan200.computercraft.shared.config.Config; import dan200.computercraft.shared.network.client.UpgradesLoadedMessage; +import dan200.computercraft.shared.network.server.ServerNetworking; import dan200.computercraft.shared.peripheral.commandblock.CommandBlockPeripheral; import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveBlockEntity; import dan200.computercraft.shared.peripheral.modem.wired.CableBlockEntity; @@ -17,7 +18,6 @@ import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemBlockE import dan200.computercraft.shared.peripheral.monitor.MonitorBlockEntity; import dan200.computercraft.shared.peripheral.printer.PrinterBlockEntity; import dan200.computercraft.shared.peripheral.speaker.SpeakerBlockEntity; -import dan200.computercraft.shared.platform.PlatformHelper; import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity; import dan200.computercraft.shared.util.CapabilityProvider; import dan200.computercraft.shared.util.SidedCapabilityProvider; @@ -81,9 +81,9 @@ public class ForgeCommonHooks { public static void onDatapackSync(OnDatapackSyncEvent event) { var packet = new UpgradesLoadedMessage(); if (event.getPlayer() == null) { - PlatformHelper.get().sendToAllPlayers(packet, event.getPlayerList().getServer()); + ServerNetworking.sendToAllPlayers(packet, event.getPlayerList().getServer()); } else { - PlatformHelper.get().sendToPlayer(packet, event.getPlayer()); + ServerNetworking.sendToPlayer(packet, event.getPlayer()); } } diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/platform/NetworkHandler.java b/projects/forge/src/main/java/dan200/computercraft/shared/platform/NetworkHandler.java index c96e19a5e..1c07b3b24 100644 --- a/projects/forge/src/main/java/dan200/computercraft/shared/platform/NetworkHandler.java +++ b/projects/forge/src/main/java/dan200/computercraft/shared/platform/NetworkHandler.java @@ -5,26 +5,25 @@ package dan200.computercraft.shared.platform; import dan200.computercraft.api.ComputerCraftAPI; +import dan200.computercraft.impl.Services; import dan200.computercraft.shared.network.MessageType; import dan200.computercraft.shared.network.NetworkMessage; import dan200.computercraft.shared.network.NetworkMessages; import dan200.computercraft.shared.network.client.ClientNetworkContext; import dan200.computercraft.shared.network.server.ServerNetworkContext; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ServerGamePacketListener; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.phys.Vec3; import net.minecraftforge.network.NetworkDirection; import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.simple.SimpleChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Collection; +import javax.annotation.Nullable; import java.util.function.Function; import static dan200.computercraft.core.util.Nullability.assertNonNull; @@ -53,36 +52,18 @@ public final class NetworkHandler { for (var type : NetworkMessages.getClientbound()) { var forgeType = (MessageTypeImpl>) type; - registerMainThread(forgeType, NetworkDirection.PLAY_TO_CLIENT, x -> ClientNetworkContext.get()); + registerMainThread(forgeType, NetworkDirection.PLAY_TO_CLIENT, x -> ClientHolder.get()); } } - static void sendToPlayer(NetworkMessage packet, ServerPlayer player) { - network.sendTo(packet, player.connection.connection, NetworkDirection.PLAY_TO_CLIENT); + @SuppressWarnings("unchecked") + public static Packet createClientboundPacket(NetworkMessage packet) { + return (Packet) network.toVanillaPacket(packet, NetworkDirection.PLAY_TO_CLIENT); } - static void sendToPlayers(NetworkMessage packet, Collection players) { - if (players.isEmpty()) return; - - var vanillaPacket = network.toVanillaPacket(packet, NetworkDirection.PLAY_TO_CLIENT); - for (var player : players) player.connection.send(vanillaPacket); - } - - static void sendToAllPlayers(NetworkMessage packet) { - network.send(PacketDistributor.ALL.noArg(), packet); - } - - static void sendToAllAround(NetworkMessage packet, Level world, Vec3 pos, double range) { - var target = new PacketDistributor.TargetPoint(pos.x, pos.y, pos.z, range, world.dimension()); - network.send(PacketDistributor.NEAR.with(() -> target), packet); - } - - static void sendToAllTracking(NetworkMessage packet, LevelChunk chunk) { - network.send(PacketDistributor.TRACKING_CHUNK.with(() -> chunk), packet); - } - - public static void sendToServer(NetworkMessage packet) { - network.sendToServer(packet); + @SuppressWarnings("unchecked") + public static Packet createServerboundPacket(NetworkMessage packet) { + return (Packet) network.toVanillaPacket(packet, NetworkDirection.PLAY_TO_SERVER); } /** @@ -115,4 +96,24 @@ public final class NetworkHandler { int id, Class klass, Function reader ) implements MessageType { } + + /** + * This holds an instance of {@link ClientNetworkContext}. This is a separate class to ensure that the instance is + * lazily created when needed on the client. + */ + private static final class ClientHolder { + private static final @Nullable ClientNetworkContext INSTANCE; + private static final @Nullable Throwable ERROR; + + static { + var helper = Services.tryLoad(ClientNetworkContext.class); + INSTANCE = helper.instance(); + ERROR = helper.error(); + } + + static ClientNetworkContext get() { + var instance = INSTANCE; + return instance == null ? Services.raise(ClientNetworkContext.class, ERROR) : instance; + } + } } diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java index 3ce9832bd..63bc64304 100644 --- a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java +++ b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java @@ -28,9 +28,10 @@ import net.minecraft.core.Direction; import net.minecraft.core.Registry; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.TagKey; @@ -52,7 +53,6 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.ForgeHooks; @@ -164,28 +164,8 @@ public class PlatformHelperImpl implements PlatformHelper { } @Override - public void sendToPlayer(NetworkMessage message, ServerPlayer player) { - NetworkHandler.sendToPlayer(message, player); - } - - @Override - public void sendToPlayers(NetworkMessage message, Collection players) { - NetworkHandler.sendToPlayers(message, players); - } - - @Override - public void sendToAllPlayers(NetworkMessage message, MinecraftServer server) { - NetworkHandler.sendToAllPlayers(message); - } - - @Override - public void sendToAllAround(NetworkMessage message, ServerLevel level, Vec3 pos, float distance) { - NetworkHandler.sendToAllAround(message, level, pos, distance); - } - - @Override - public void sendToAllTracking(NetworkMessage message, LevelChunk chunk) { - NetworkHandler.sendToAllTracking(message, chunk); + public Packet createPacket(NetworkMessage message) { + return NetworkHandler.createClientboundPacket(message); } @Override