mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-23 01:47:38 +00:00
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!
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
@@ -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<ServerNetworkContext> message) {
|
||||
NetworkHandler.sendToServer(message);
|
||||
public Packet<ServerGamePacketListener> createPacket(NetworkMessage<ServerNetworkContext> 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);
|
||||
}
|
||||
}
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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<? extends NetworkMessage<ClientNetworkContext>>) type;
|
||||
registerMainThread(forgeType, NetworkDirection.PLAY_TO_CLIENT, x -> ClientNetworkContext.get());
|
||||
registerMainThread(forgeType, NetworkDirection.PLAY_TO_CLIENT, x -> ClientHolder.get());
|
||||
}
|
||||
}
|
||||
|
||||
static void sendToPlayer(NetworkMessage<ClientNetworkContext> packet, ServerPlayer player) {
|
||||
network.sendTo(packet, player.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Packet<ClientGamePacketListener> createClientboundPacket(NetworkMessage<ClientNetworkContext> packet) {
|
||||
return (Packet<ClientGamePacketListener>) network.toVanillaPacket(packet, NetworkDirection.PLAY_TO_CLIENT);
|
||||
}
|
||||
|
||||
static void sendToPlayers(NetworkMessage<ClientNetworkContext> packet, Collection<ServerPlayer> 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<ClientNetworkContext> packet) {
|
||||
network.send(PacketDistributor.ALL.noArg(), packet);
|
||||
}
|
||||
|
||||
static void sendToAllAround(NetworkMessage<ClientNetworkContext> 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<ClientNetworkContext> packet, LevelChunk chunk) {
|
||||
network.send(PacketDistributor.TRACKING_CHUNK.with(() -> chunk), packet);
|
||||
}
|
||||
|
||||
public static void sendToServer(NetworkMessage<ServerNetworkContext> packet) {
|
||||
network.sendToServer(packet);
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Packet<ServerGamePacketListener> createServerboundPacket(NetworkMessage<ServerNetworkContext> packet) {
|
||||
return (Packet<ServerGamePacketListener>) network.toVanillaPacket(packet, NetworkDirection.PLAY_TO_SERVER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,4 +96,24 @@ public final class NetworkHandler {
|
||||
int id, Class<T> klass, Function<FriendlyByteBuf, T> reader
|
||||
) implements MessageType<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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<ClientNetworkContext> message, ServerPlayer player) {
|
||||
NetworkHandler.sendToPlayer(message, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendToPlayers(NetworkMessage<ClientNetworkContext> message, Collection<ServerPlayer> players) {
|
||||
NetworkHandler.sendToPlayers(message, players);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendToAllPlayers(NetworkMessage<ClientNetworkContext> message, MinecraftServer server) {
|
||||
NetworkHandler.sendToAllPlayers(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendToAllAround(NetworkMessage<ClientNetworkContext> message, ServerLevel level, Vec3 pos, float distance) {
|
||||
NetworkHandler.sendToAllAround(message, level, pos, distance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendToAllTracking(NetworkMessage<ClientNetworkContext> message, LevelChunk chunk) {
|
||||
NetworkHandler.sendToAllTracking(message, chunk);
|
||||
public Packet<ClientGamePacketListener> createPacket(NetworkMessage<ClientNetworkContext> message) {
|
||||
return NetworkHandler.createClientboundPacket(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user