diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric.zip b/forge/src/main/java/com/seibel/lod/forge/fabric.zip new file mode 100644 index 000000000..44833cbb8 Binary files /dev/null and b/forge/src/main/java/com/seibel/lod/forge/fabric.zip differ diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/C2SPlayChannelEvents.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/C2SPlayChannelEvents.java deleted file mode 100644 index e2380f8de..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/C2SPlayChannelEvents.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.client.networking.v1; - -import java.util.List; -import com.seibel.lod.forge.fabric.api.event.Event; -import com.seibel.lod.forge.fabric.api.event.EventFactory; -import com.seibel.lod.forge.fabric.api.networking.v1.PacketSender; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.resources.ResourceLocation; - -/** - * Offers access to events related to the indication of a connected server's ability to receive packets in certain channels. - */ - -public final class C2SPlayChannelEvents { - /** - * An event for the client play network handler receiving an update indicating the connected server's ability to receive packets in certain channels. - * This event may be invoked at any time after login and up to disconnection. - */ - public static final Event REGISTER = EventFactory.createArrayBacked(Register.class, callbacks -> (handler, sender, client, channels) -> { - for (Register callback : callbacks) { - callback.onChannelRegister(handler, sender, client, channels); - } - }); - - /** - * An event for the client play network handler receiving an update indicating the connected server's lack of ability to receive packets in certain channels. - * This event may be invoked at any time after login and up to disconnection. - */ - public static final Event UNREGISTER = EventFactory.createArrayBacked(Unregister.class, callbacks -> (handler, sender, client, channels) -> { - for (Unregister callback : callbacks) { - callback.onChannelUnregister(handler, sender, client, channels); - } - }); - - private C2SPlayChannelEvents() { - } - - /** - * @see C2SPlayChannelEvents#REGISTER - */ - - @FunctionalInterface - public interface Register { - void onChannelRegister(ClientPacketListener handler, PacketSender sender, Minecraft client, List channels); - } - - /** - * @see C2SPlayChannelEvents#UNREGISTER - */ - - @FunctionalInterface - public interface Unregister { - void onChannelUnregister(ClientPacketListener handler, PacketSender sender, Minecraft client, List channels); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientLoginConnectionEvents.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientLoginConnectionEvents.java deleted file mode 100644 index e6dcfdc43..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientLoginConnectionEvents.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.client.networking.v1; - -import com.seibel.lod.forge.fabric.api.event.Event; -import com.seibel.lod.forge.fabric.api.event.EventFactory; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl; -import net.minecraft.resources.ResourceLocation; - -/** - * Offers access to events related to the connection to a server on the client while the server is processing the client's login request. - */ - -public final class ClientLoginConnectionEvents { - /** - * Event indicating a connection entered the LOGIN state, ready for registering query request handlers. - * This event may be used by mods to prepare their client side state. - * This event does not guarantee that a login attempt will be successful. - * - * @see ClientLoginNetworking#registerReceiver(ResourceLocation, ClientLoginNetworking.LoginQueryRequestHandler) - */ - public static final Event INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, client) -> { - for (Init callback : callbacks) { - callback.onLoginStart(handler, client); - } - }); - - /** - * An event for when the client has started receiving login queries. - * A client can only start receiving login queries when a server has sent the first login query. - * Vanilla servers will typically never make the client enter this login phase, but it is not a guarantee that the - * connected server is a vanilla server since a modded server or proxy may have no login queries to send to the client - * and therefore bypass the login query phase. - * If this event is fired then it is a sign that a server is not a vanilla server or the server is behind a proxy which - * is capable of handling login queries. - * - *

This event may be used to {@link ClientLoginNetworking.LoginQueryRequestHandler register login query handlers} - * which may be used to send a response to a server. - * - *

No packets should be sent when this event is invoked. - */ - public static final Event QUERY_START = EventFactory.createArrayBacked(QueryStart.class, callbacks -> (handler, client) -> { - for (QueryStart callback : callbacks) { - callback.onLoginQueryStart(handler, client); - } - }); - - /** - * An event for when the client's login process has ended due to disconnection. - * - *

No packets should be sent when this event is invoked. - */ - public static final Event DISCONNECT = EventFactory.createArrayBacked(Disconnect.class, callbacks -> (handler, client) -> { - for (Disconnect callback : callbacks) { - callback.onLoginDisconnect(handler, client); - } - }); - - private ClientLoginConnectionEvents() { - } - - /** - * @see ClientLoginConnectionEvents#INIT - */ - - @FunctionalInterface - public interface Init { - void onLoginStart(ClientHandshakePacketListenerImpl handler, Minecraft client); - } - - /** - * @see ClientLoginConnectionEvents#QUERY_START - */ - - @FunctionalInterface - public interface QueryStart { - void onLoginQueryStart(ClientHandshakePacketListenerImpl handler, Minecraft client); - } - - /** - * @see ClientLoginConnectionEvents#DISCONNECT - */ - - @FunctionalInterface - public interface Disconnect { - void onLoginDisconnect(ClientHandshakePacketListenerImpl handler, Minecraft client); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientLoginNetworking.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientLoginNetworking.java deleted file mode 100644 index ac80b1b27..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientLoginNetworking.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.client.networking.v1; - -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; - -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import org.jetbrains.annotations.Nullable; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerLoginNetworking; -import com.seibel.lod.forge.fabric.impl.networking.client.ClientNetworkingImpl; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl; -import net.minecraft.network.Connection; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.PacketListener; -import net.minecraft.resources.ResourceLocation; - -/** - * Offers access to login stage client-side networking functionalities. - * - *

The Minecraft login protocol only allows the client to respond to a server's request, but not initiate one of its own. - * - * @see ClientPlayNetworking - * @see ServerLoginNetworking - */ - -public final class ClientLoginNetworking { - /** - * Registers a handler to a query request channel. - * A global receiver is registered to all connections, in the present and future. - * - *

If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made. - * Use {@link #unregisterGlobalReceiver(ResourceLocation)} to unregister the existing handler. - * - * @param channelName the id of the channel - * @param queryHandler the handler - * @return false if a handler is already registered to the channel - * @see ClientLoginNetworking#unregisterGlobalReceiver(ResourceLocation) - * @see ClientLoginNetworking#registerReceiver(ResourceLocation, LoginQueryRequestHandler) - */ - public static boolean registerGlobalReceiver(ResourceLocation channelName, LoginQueryRequestHandler queryHandler) { - return ClientNetworkingImpl.LOGIN.registerGlobalReceiver(channelName, queryHandler); - } - - /** - * Removes the handler of a query request channel. - * A global receiver is registered to all connections, in the present and future. - * - *

The {@code channel} is guaranteed not to have a handler after this call. - * - * @param channelName the id of the channel - * @return the previous handler, or {@code null} if no handler was bound to the channel - * @see ClientLoginNetworking#registerGlobalReceiver(ResourceLocation, LoginQueryRequestHandler) - * @see ClientLoginNetworking#unregisterReceiver(ResourceLocation) - */ - @Nullable - public static ClientLoginNetworking.LoginQueryRequestHandler unregisterGlobalReceiver(ResourceLocation channelName) { - return ClientNetworkingImpl.LOGIN.unregisterGlobalReceiver(channelName); - } - - /** - * Gets all query request channel names which global receivers are registered for. - * A global receiver is registered to all connections, in the present and future. - * - * @return all channel names which global receivers are registered for. - */ - public static Set getGlobalReceivers() { - return ClientNetworkingImpl.LOGIN.getChannels(); - } - - /** - * Registers a handler to a query request channel. - * - *

If a handler is already registered to the {@code channelName}, this method will return {@code false}, and no change will be made. - * Use {@link #unregisterReceiver(ResourceLocation)} to unregister the existing handler. - * - * @param channelName the id of the channel - * @param queryHandler the handler - * @return false if a handler is already registered to the channel name - * @throws IllegalStateException if the client is not logging in - */ - public static boolean registerReceiver(ResourceLocation channelName, LoginQueryRequestHandler queryHandler) throws IllegalStateException { - final Connection connection = ClientNetworkingImpl.getLoginConnection(); - - if (connection != null) { - final PacketListener packetListener = connection.getPacketListener(); - - if (packetListener instanceof ClientHandshakePacketListenerImpl) { - return ClientNetworkingImpl.getAddon(((ClientHandshakePacketListenerImpl) packetListener)).registerChannel(channelName, queryHandler); - } - } - - throw new IllegalStateException("Cannot register receiver while client is not logging in!"); - } - - /** - * Removes the handler of a query request channel. - * - *

The {@code channelName} is guaranteed not to have a handler after this call. - * - * @param channelName the id of the channel - * @return the previous handler, or {@code null} if no handler was bound to the channel name - * @throws IllegalStateException if the client is not logging in - */ - @Nullable - public static LoginQueryRequestHandler unregisterReceiver(ResourceLocation channelName) throws IllegalStateException { - final Connection connection = ClientNetworkingImpl.getLoginConnection(); - - if (connection != null) { - final PacketListener packetListener = connection.getPacketListener(); - - if (packetListener instanceof ClientHandshakePacketListenerImpl) { - return ClientNetworkingImpl.getAddon(((ClientHandshakePacketListenerImpl) packetListener)).unregisterChannel(channelName); - } - } - - throw new IllegalStateException("Cannot unregister receiver while client is not logging in!"); - } - - private ClientLoginNetworking() { - } - - @FunctionalInterface - public interface LoginQueryRequestHandler { - /** - * Handles an incoming query request from a server. - * - *

This method is executed on {@linkplain io.netty.channel.EventLoop netty's event loops}. - * Modification to the game should be {@linkplain net.minecraft.util.thread.BlockableEventLoop#submit(Runnable) scheduled} using the provided Minecraft client instance. - * - *

The return value of this method is a completable future that may be used to delay the login process to the server until a task {@link CompletableFuture#isDone() is done}. - * The future should complete in reasonably time to prevent disconnection by the server. - * If your request processes instantly, you may use {@link CompletableFuture#completedFuture(Object)} to wrap your response for immediate sending. - * - * @param client the client - * @param handler the network handler that received this packet - * @param buf the payload of the packet - * @param listenerAdder listeners to be called when the response packet is sent to the server - * @return a completable future which contains the payload to respond to the server with. - * If the future contains {@code null}, then the server will be notified that the client did not understand the query. - */ - CompletableFuture<@Nullable FriendlyByteBuf> receive(Minecraft client, ClientHandshakePacketListenerImpl handler, FriendlyByteBuf buf, Consumer>> listenerAdder); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientPlayConnectionEvents.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientPlayConnectionEvents.java deleted file mode 100644 index ad4e16a33..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientPlayConnectionEvents.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.client.networking.v1; - -import com.seibel.lod.forge.fabric.api.event.Event; -import com.seibel.lod.forge.fabric.api.event.EventFactory; -import com.seibel.lod.forge.fabric.api.networking.v1.PacketSender; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.resources.ResourceLocation; - -/** - * Offers access to events related to the connection to a server on a logical client. - */ - -public final class ClientPlayConnectionEvents { - /** - * Event indicating a connection entered the PLAY state, ready for registering channel handlers. - * - * @see ClientPlayNetworking#registerReceiver(ResourceLocation, ClientPlayNetworking.PlayChannelHandler) - */ - public static final Event INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, client) -> { - for (Init callback : callbacks) { - callback.onPlayInit(handler, client); - } - }); - - /** - * An event for notification when the client play network handler is ready to send packets to the server. - * - *

At this stage, the network handler is ready to send packets to the server. - * Since the client's local state has been setup. - */ - public static final Event JOIN = EventFactory.createArrayBacked(Join.class, callbacks -> (handler, sender, client) -> { - for (Join callback : callbacks) { - callback.onPlayReady(handler, sender, client); - } - }); - - /** - * An event for the disconnection of the client play network handler. - * - *

No packets should be sent when this event is invoked. - */ - public static final Event DISCONNECT = EventFactory.createArrayBacked(Disconnect.class, callbacks -> (handler, client) -> { - for (Disconnect callback : callbacks) { - callback.onPlayDisconnect(handler, client); - } - }); - - private ClientPlayConnectionEvents() { - } - - - @FunctionalInterface - public interface Init { - void onPlayInit(ClientPacketListener handler, Minecraft client); - } - - - @FunctionalInterface - public interface Join { - void onPlayReady(ClientPacketListener handler, PacketSender sender, Minecraft client); - } - - - @FunctionalInterface - public interface Disconnect { - void onPlayDisconnect(ClientPacketListener handler, Minecraft client); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientPlayNetworking.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientPlayNetworking.java deleted file mode 100644 index 7ebcfe9c1..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/ClientPlayNetworking.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.client.networking.v1; - -import java.util.Objects; -import java.util.Set; - -import org.jetbrains.annotations.Nullable; -import com.seibel.lod.forge.fabric.api.networking.v1.PacketSender; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerPlayNetworking; -import com.seibel.lod.forge.fabric.impl.networking.client.ClientNetworkingImpl; -import com.seibel.lod.forge.fabric.impl.networking.client.ClientPlayNetworkAddon; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.Packet; -import net.minecraft.resources.ResourceLocation; - -/** - * Offers access to play stage client-side networking functionalities. - * - *

Client-side networking functionalities include receiving clientbound packets, - * sending serverbound packets, and events related to client-side network handlers. - * - *

This class should be only used on the physical client and for the logical client. - * - * @see ClientLoginNetworking - * @see ServerPlayNetworking - */ - -public final class ClientPlayNetworking { - /** - * Registers a handler to a channel. - * A global receiver is registered to all connections, in the present and future. - * - *

If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made. - * Use {@link #unregisterGlobalReceiver(ResourceLocation)} to unregister the existing handler. - * - * @param channelName the id of the channel - * @param channelHandler the handler - * @return false if a handler is already registered to the channel - * @see ClientPlayNetworking#unregisterGlobalReceiver(ResourceLocation) - * @see ClientPlayNetworking#registerReceiver(ResourceLocation, PlayChannelHandler) - */ - public static boolean registerGlobalReceiver(ResourceLocation channelName, PlayChannelHandler channelHandler) { - return ClientNetworkingImpl.PLAY.registerGlobalReceiver(channelName, channelHandler); - } - - /** - * Removes the handler of a channel. - * A global receiver is registered to all connections, in the present and future. - * - *

The {@code channel} is guaranteed not to have a handler after this call. - * - * @param channelName the id of the channel - * @return the previous handler, or {@code null} if no handler was bound to the channel - * @see ClientPlayNetworking#registerGlobalReceiver(ResourceLocation, PlayChannelHandler) - * @see ClientPlayNetworking#unregisterReceiver(ResourceLocation) - */ - @Nullable - public static PlayChannelHandler unregisterGlobalReceiver(ResourceLocation channelName) { - return ClientNetworkingImpl.PLAY.unregisterGlobalReceiver(channelName); - } - - /** - * Gets all channel names which global receivers are registered for. - * A global receiver is registered to all connections, in the present and future. - * - * @return all channel names which global receivers are registered for. - */ - public static Set getGlobalReceivers() { - return ClientNetworkingImpl.PLAY.getChannels(); - } - - /** - * Registers a handler to a channel. - * - *

If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made. - * Use {@link #unregisterReceiver(ResourceLocation)} to unregister the existing handler. - * - *

For example, if you only register a receiver using this method when a {@linkplain ClientLoginNetworking#registerGlobalReceiver(ResourceLocation, ClientLoginNetworking.LoginQueryRequestHandler)} - * login query has been received, you should use {@link ClientPlayConnectionEvents#INIT} to register the channel handler. - * - * @param channelName the id of the channel - * @return false if a handler is already registered to the channel - * @throws IllegalStateException if the client is not connected to a server - * @see ClientPlayConnectionEvents#INIT - */ - public static boolean registerReceiver(ResourceLocation channelName, PlayChannelHandler channelHandler) { - final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon(); - - if (addon != null) { - return addon.registerChannel(channelName, channelHandler); - } - - throw new IllegalStateException("Cannot register receiver while not in game!"); - } - - /** - * Removes the handler of a channel. - * - *

The {@code channelName} is guaranteed not to have a handler after this call. - * - * @param channelName the id of the channel - * @return the previous handler, or {@code null} if no handler was bound to the channel - * @throws IllegalStateException if the client is not connected to a server - */ - @Nullable - public static PlayChannelHandler unregisterReceiver(ResourceLocation channelName) throws IllegalStateException { - final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon(); - - if (addon != null) { - return addon.unregisterChannel(channelName); - } - - throw new IllegalStateException("Cannot unregister receiver while not in game!"); - } - - /** - * Gets all the channel names that the client can receive packets on. - * - * @return All the channel names that the client can receive packets on - * @throws IllegalStateException if the client is not connected to a server - */ - public static Set getReceived() throws IllegalStateException { - final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon(); - - if (addon != null) { - return addon.getReceivableChannels(); - } - - throw new IllegalStateException("Cannot get a list of channels the client can receive packets on while not in game!"); - } - - /** - * Gets all channel names that the connected server declared the ability to receive a packets on. - * - * @return All the channel names the connected server declared the ability to receive a packets on - * @throws IllegalStateException if the client is not connected to a server - */ - public static Set getSendable() throws IllegalStateException { - final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon(); - - if (addon != null) { - return addon.getSendableChannels(); - } - - throw new IllegalStateException("Cannot get a list of channels the server can receive packets on while not in game!"); - } - - /** - * Checks if the connected server declared the ability to receive a packet on a specified channel name. - * - * @param channelName the channel name - * @return True if the connected server has declared the ability to receive a packet on the specified channel. - * False if the client is not in game. - */ - public static boolean canSend(ResourceLocation channelName) throws IllegalArgumentException { - // You cant send without a client player, so this is fine - if (Minecraft.getInstance().getConnection() != null) { - return ClientNetworkingImpl.getAddon(Minecraft.getInstance().getConnection()).getSendableChannels().contains(channelName); - } - - return false; - } - - /** - * Creates a packet which may be sent to a the connected server. - * - * @param channelName the channel name - * @param buf the packet byte buf which represents the payload of the packet - * @return a new packet - */ - public static Packet createC2SPacket(ResourceLocation channelName, FriendlyByteBuf buf) { - Objects.requireNonNull(channelName, "Channel name cannot be null"); - Objects.requireNonNull(buf, "Buf cannot be null"); - - return ClientNetworkingImpl.createPlayC2SPacket(channelName, buf); - } - - /** - * Gets the packet sender which sends packets to the connected server. - * - * @return the client's packet sender - * @throws IllegalStateException if the client is not connected to a server - */ - public static PacketSender getSender() throws IllegalStateException { - // You cant send without a client player, so this is fine - if (Minecraft.getInstance().getConnection() != null) { - return ClientNetworkingImpl.getAddon(Minecraft.getInstance().getConnection()); - } - - throw new IllegalStateException("Cannot get packet sender when not in game!"); - } - - /** - * Sends a packet to the connected server. - * - * @param channelName the channel of the packet - * @param buf the payload of the packet - * @throws IllegalStateException if the client is not connected to a server - */ - public static void send(ResourceLocation channelName, FriendlyByteBuf buf) throws IllegalStateException { - // You cant send without a client player, so this is fine - if (Minecraft.getInstance().getConnection() != null) { - Minecraft.getInstance().getConnection().send(createC2SPacket(channelName, buf)); - return; - } - - throw new IllegalStateException("Cannot send packets when not in game!"); - } - - private ClientPlayNetworking() { - } - - @FunctionalInterface - public interface PlayChannelHandler { - /** - * Handles an incoming packet. - * - *

This method is executed on {@linkplain io.netty.channel.EventLoop netty's event loops}. - * Modification to the game should be {@linkplain net.minecraft.util.thread.BlockableEventLoop#submit(Runnable) scheduled} using the provided Minecraft client instance. - * - *

An example usage of this is to display an overlay message: - *

{@code
-		 * ClientPlayNetworking.registerReceiver(new Identifier("mymod", "overlay"), (client, handler, buf, responseSender) -&rt; {
-		 * 	String message = buf.readString(32767);
-		 *
-		 * 	// All operations on the server or world must be executed on the server thread
-		 * 	client.execute(() -&rt; {
-		 * 		client.inGameHud.setOverlayMessage(message, true);
-		 * 	});
-		 * });
-		 * }
- * @param client the client - * @param handler the network handler that received this packet - * @param buf the payload of the packet - * @param responseSender the packet sender - */ - void receive(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/package-info.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/package-info.java deleted file mode 100644 index 903beb181..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/client/networking/v1/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * The Networking API (client side), version 1. - * - *

For login stage networking see {@link net.fabricmc.fabric.api.client.networking.v1.ClientLoginNetworking}. - * For play stage networking see {@link net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking}. - * - *

For events related to connection to a server see {@link net.fabricmc.fabric.api.client.networking.v1.ClientLoginConnectionEvents} for login stage - * or {@link net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents} for play stage. - * - *

For events related to the ability of a server to receive packets on a channel of a specific name see {@link net.fabricmc.fabric.api.client.networking.v1.C2SPlayChannelEvents}. - */ - -package com.seibel.lod.forge.fabric.api.client.networking.v1; diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/event/AutoInvokingEvent.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/event/AutoInvokingEvent.java deleted file mode 100644 index c06415af8..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/event/AutoInvokingEvent.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.event; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Indicates that this {@link Event} is auto-invoking: - * it calls the event callback implemented by a context parameter type automatically and without registration. - * - *

This means that this event can be listened to in two ways: - *

    - *
  • If the consumer is the context parameter and it implements the callback, it will be automatically invoked, don't register manually. - *
  • Otherwise, there is no invocation and the listener needs manual registration as usual. - *
- * - *

Do note that there may be more than one context parameter. - * - *

A typical use case is feature augmentation, for example to expose raw clicks to slots. - * The event callback has a slot parameter - the context parameter - and the event itself is carrying this annotation. - * All the slot needs to receive slot clicks is to implement {@code SlotClickCallback} on itself. - * It shouldn't do any explicit event registration like {@code SLOT_CLICK_EVENT.register(this::onSlotClick)}, - * otherwise it will see extraneous callback invocations. - * - *

In general, an auto-invoking event bridges the gap between the flexibility of an event with global reach, - * and the convenience of implementing an interface that gets detected automatically. - * - *

This is a documentation-only annotation, the event factory has to implement the functionality explicitly by checking the parameter type and invoking it. - * On top of adding this annotation, the event field or method should document which parameters are context parameters, - * and under which circumstances they are invoked. - */ - -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD }) -public @interface AutoInvokingEvent { -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/event/Event.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/event/Event.java deleted file mode 100644 index bc6dc704d..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/event/Event.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.event; - -import org.jetbrains.annotations.ApiStatus; - -import net.minecraft.resources.ResourceLocation; - -/** - * Base class for Fabric's event implementations. - * - * @param The listener type. - * @see EventFactory - */ -@ApiStatus.NonExtendable // Should only be extended by fabric API. -public abstract class Event { - /** - * The invoker field. This should be updated by the implementation to - * always refer to an instance containing all code that should be - * executed upon event emission. - */ - protected volatile T invoker; - - /** - * Returns the invoker instance. - * - *

An "invoker" is an object which hides multiple registered - * listeners of type T under one instance of type T, executing - * them and leaving early as necessary. - * - * @return The invoker instance. - */ - public final T invoker() { - return invoker; - } - - /** - * Register a listener to the event, in the default phase. - * Have a look at {@link #addPhaseOrdering} for an explanation of event phases. - * - * @param listener The desired listener. - */ - public abstract void register(T listener); - - /** - * The ResourceLocation of the default phase. - * Have a look at {@link EventFactory#createWithPhases} for an explanation of event phases. - */ - public static final ResourceLocation DEFAULT_PHASE = new ResourceLocation("fabric", "default"); - - /** - * Register a listener to the event for the specified phase. - * Have a look at {@link EventFactory#createWithPhases} for an explanation of event phases. - * - * @param phase ResourceLocation of the phase this listener should be registered for. It will be created if it didn't exist yet. - * @param listener The desired listener. - */ - public void register(ResourceLocation phase, T listener) { - // This is done to keep compatibility with existing Event subclasses, but they should really not be subclassing Event. - register(listener); - } - - /** - * Request that listeners registered for one phase be executed before listeners registered for another phase. - * Relying on the default phases supplied to {@link EventFactory#createWithPhases} should be preferred over manually - * registering phase ordering dependencies. - * - *

Incompatible ordering constraints such as cycles will lead to inconsistent behavior: - * some constraints will be respected and some will be ignored. If this happens, a warning will be logged. - * - * @param firstPhase The ResourceLocation of the phase that should run before the other. It will be created if it didn't exist yet. - * @param secondPhase The ResourceLocation of the phase that should run after the other. It will be created if it didn't exist yet. - */ - public void addPhaseOrdering(ResourceLocation firstPhase, ResourceLocation secondPhase) { - // This is not abstract to avoid breaking existing Event subclasses, but they should really not be subclassing Event. - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/event/EventFactory.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/event/EventFactory.java deleted file mode 100644 index 97808e030..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/event/EventFactory.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.event; - -import java.util.function.Function; - -import net.minecraft.resources.ResourceLocation; - -import com.seibel.lod.forge.fabric.impl.base.event.EventFactoryImpl; - -/** - * Helper for creating {@link Event} classes. - */ -public final class EventFactory { - private static boolean profilingEnabled = true; - - private EventFactory() { } - - /** - * @return True if events are supposed to be profiled. - */ - public static boolean isProfilingEnabled() { - return profilingEnabled; - } - - /** - * Invalidate and re-create all existing "invoker" instances across - * events created by this EventFactory. Use this if, for instance, - * the profilingEnabled field changes. - */ - // TODO: Turn this into an event? - public static void invalidate() { - EventFactoryImpl.invalidate(); - } - - /** - * Create an "array-backed" Event instance. - * - *

If your factory simply delegates to the listeners without adding custom behavior, - * consider using {@linkplain #createArrayBacked(Class, Object, Function) the other overload} - * if performance of this event is critical. - * - * @param type The listener class type. - * @param invokerFactory The invoker factory, combining multiple listeners into one instance. - * @param The listener type. - * @return The Event instance. - */ - public static Event createArrayBacked(Class type, Function invokerFactory) { - return EventFactoryImpl.createArrayBacked(type, invokerFactory); - } - - /** - * Create an "array-backed" Event instance with a custom empty invoker, - * for an event whose {@code invokerFactory} only delegates to the listeners. - *

    - *
  • If there is no listener, the custom empty invoker will be used.
  • - *
  • If there is only one listener, that one will be used as the invoker - * and the factory will not be called.
  • - *
  • Only when there are at least two listeners will the factory be used.
  • - *
- * - *

Having a custom empty invoker (of type (...) -> {}) increases performance - * relative to iterating over an empty array; however, it only really matters - * if the event is executed thousands of times a second. - * - * @param type The listener class type. - * @param emptyInvoker The custom empty invoker. - * @param invokerFactory The invoker factory, combining multiple listeners into one instance. - * @param The listener type. - * @return The Event instance. - */ - public static Event createArrayBacked(Class type, T emptyInvoker, Function invokerFactory) { - return createArrayBacked(type, listeners -> { - if (listeners.length == 0) { - return emptyInvoker; - } else if (listeners.length == 1) { - return listeners[0]; - } else { - return invokerFactory.apply(listeners); - } - }); - } - - /** - * Create an array-backed event with a list of default phases that get invoked in order. - * Exposing the ResourceLocations of the default phases as {@code public static final} constants is encouraged. - * - *

An event phase is a named group of listeners, which may be ordered before or after other groups of listeners. - * This allows some listeners to take priority over other listeners. - * Adding separate events should be considered before making use of multiple event phases. - * - *

Phases may be freely added to events created with any of the factory functions, - * however using this function is preferred for widely used event phases. - * If more phases are necessary, discussion with the author of the Event is encouraged. - * - *

Refer to {@link Event#addPhaseOrdering} for an explanation of event phases. - * - * @param type The listener class type. - * @param invokerFactory The invoker factory, combining multiple listeners into one instance. - * @param defaultPhases The default phases of this event, in the correct order. Must contain {@link Event#DEFAULT_PHASE}. - * @param The listener type. - * @return The Event instance. - */ - public static Event createWithPhases(Class type, Function invokerFactory, ResourceLocation... defaultPhases) { - EventFactoryImpl.ensureContainsDefault(defaultPhases); - EventFactoryImpl.ensureNoDuplicates(defaultPhases); - - Event event = createArrayBacked(type, invokerFactory); - - for (int i = 1; i < defaultPhases.length; ++i) { - event.addPhaseOrdering(defaultPhases[i-1], defaultPhases[i]); - } - - return event; - } - - /** - * Get the listener object name. This can be used in debugging/profiling - * scenarios. - * - * @param handler The listener object. - * @return The listener name. - */ - public static String getHandlerName(Object handler) { - return handler.getClass().getName(); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/EntityTrackingEvents.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/EntityTrackingEvents.java deleted file mode 100644 index c369b64d8..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/EntityTrackingEvents.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; - -import com.seibel.lod.forge.fabric.api.event.Event; -import com.seibel.lod.forge.fabric.api.event.EventFactory; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.Entity; - -/** - * Events related to a tracking entities within a player's view distance. - */ -public final class EntityTrackingEvents { - /** - * An event that is called before player starts tracking an entity. - * Typically this occurs when an entity enters a client's view distance. - * This event is called before the player's client is sent the entity's {@link Entity#getAddEntityPacket() spawn packet}. - */ - public static final Event START_TRACKING = EventFactory.createArrayBacked(StartTracking.class, callbacks -> (trackedEntity, player) -> { - for (StartTracking callback : callbacks) { - callback.onStartTracking(trackedEntity, player); - } - }); - - /** - * An event that is called after a player has stopped tracking an entity. - * The client at this point was sent a packet to {@link net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket destroy} the entity on the client. - * The entity still exists on the server. - */ - public static final Event STOP_TRACKING = EventFactory.createArrayBacked(StopTracking.class, callbacks -> (trackedEntity, player) -> { - for (StopTracking callback : callbacks) { - callback.onStopTracking(trackedEntity, player); - } - }); - - @FunctionalInterface - public interface StartTracking { - /** - * Called before an entity starts getting tracked by a player. - * - * @param trackedEntity the entity that will be tracked - * @param player the player that will track the entity - */ - void onStartTracking(Entity trackedEntity, ServerPlayer player); - } - - @FunctionalInterface - public interface StopTracking { - /** - * Called after an entity stops getting tracked by a player. - * - * @param trackedEntity the entity that is no longer being tracked - * @param player the player that is no longer tracking the entity - */ - void onStopTracking(Entity trackedEntity, ServerPlayer player); - } - - private EntityTrackingEvents() { - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/FutureListeners.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/FutureListeners.java deleted file mode 100644 index 88fee7bd1..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/FutureListeners.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; - -import java.util.Objects; -import net.minecraft.network.FriendlyByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.local.LocalChannel; -import io.netty.channel.local.LocalServerChannel; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.GenericFutureListener; - -/** - * Utilities for working with netty's future listeners. - * @see FutureListener - * @see ChannelFutureListener - */ -public final class FutureListeners { - /** - * Returns a future listener that releases a packet byte buf when the buffer has been sent to a remote connection. - * - * @param buf the buffer - * @return the future listener - */ - public static ChannelFutureListener free(FriendlyByteBuf buf) { - Objects.requireNonNull(buf, "PacketByteBuf cannot be null"); - - return (future) -> { - if (!isLocalChannel(future.channel())) { - buf.release(); - } - }; - } - - /** - * Returns whether a netty channel performs local transportation, or if the message objects in the channel are directly passed than written to and read from a byte buf. - * - * @param channel the channel to check - * @return whether the channel is local - */ - public static boolean isLocalChannel(Channel channel) { - return channel instanceof LocalServerChannel || channel instanceof LocalChannel; - } - - /** - * Combines two future listeners. - * - * @param first the first future listener - * @param second the second future listener - * @param the future type of the first listener, used for casting - * @param the future type of the second listener, used for casting - * @return the combined future listener. - */ - // A, B exist just to allow casting - @SuppressWarnings("unchecked") - public static , B extends Future> GenericFutureListener> union(GenericFutureListener first, GenericFutureListener second) { - // Return an empty future listener in the case of both parameters somehow being null - if (first == null && second == null) { - return future -> { }; - } - - if (first == null) { - return second; - } - - if (second == null) { - return first; - } - - return future -> { - first.operationComplete((A) future); - second.operationComplete((B) future); - }; - } - - private FutureListeners() { - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/PacketByteBufs.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/PacketByteBufs.java deleted file mode 100644 index dcec0210e..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/PacketByteBufs.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; - -import java.util.Objects; -import net.minecraft.network.FriendlyByteBuf; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - -/** - * Helper methods for working with and creating {@link FriendlyByteBuf}s. - */ -public final class PacketByteBufs { - private static final FriendlyByteBuf EMPTY_PACKET_BYTE_BUF = new FriendlyByteBuf(Unpooled.EMPTY_BUFFER); - - /** - * Returns an empty instance of packet byte buf. - * - * @return an empty buf - */ - public static FriendlyByteBuf empty() { - return EMPTY_PACKET_BYTE_BUF; - } - - /** - * Returns a new heap memory-backed instance of packet byte buf. - * - * @return a new buf - */ - public static FriendlyByteBuf create() { - return new FriendlyByteBuf(Unpooled.buffer()); - } - - // Convenience methods for byte buf methods that return a new byte buf - - /** - * Wraps the newly created buf from {@code buf.readBytes} in a packet byte buf. - * - * @param buf the original buf - * @param length the number of bytes to transfer - * @return the transferred bytes - * @see ByteBuf#readBytes(int) - */ - public static FriendlyByteBuf readBytes(ByteBuf buf, int length) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.readBytes(length)); - } - - /** - * Wraps the newly created buf from {@code buf.readSlice} in a packet byte buf. - * - * @param buf the original buf - * @param length the size of the new slice - * @return the newly created slice - * @see ByteBuf#readSlice(int) - */ - public static FriendlyByteBuf readSlice(ByteBuf buf, int length) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.readSlice(length)); - } - - /** - * Wraps the newly created buf from {@code buf.readRetainedSlice} in a packet byte buf. - * - * @param buf the original buf - * @param length the size of the new slice - * @return the newly created slice - * @see ByteBuf#readRetainedSlice(int) - */ - public static FriendlyByteBuf readRetainedSlice(ByteBuf buf, int length) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.readRetainedSlice(length)); - } - - /** - * Wraps the newly created buf from {@code buf.copy} in a packet byte buf. - * - * @param buf the original buf - * @return a copy of the buf - * @see ByteBuf#copy() - */ - public static FriendlyByteBuf copy(ByteBuf buf) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.copy()); - } - - /** - * Wraps the newly created buf from {@code buf.copy} in a packet byte buf. - * - * @param buf the original buf - * @param index the starting index - * @param length the size of the copy - * @return a copy of the buf - * @see ByteBuf#copy(int, int) - */ - public static FriendlyByteBuf copy(ByteBuf buf, int index, int length) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.copy(index, length)); - } - - /** - * Wraps the newly created buf from {@code buf.slice} in a packet byte buf. - * - * @param buf the original buf - * @return a slice of the buf - * @see ByteBuf#slice() - */ - public static FriendlyByteBuf slice(ByteBuf buf) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.slice()); - } - - /** - * Wraps the newly created buf from {@code buf.retainedSlice} in a packet byte buf. - * - * @param buf the original buf - * @return a slice of the buf - * @see ByteBuf#retainedSlice() - */ - public static FriendlyByteBuf retainedSlice(ByteBuf buf) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.retainedSlice()); - } - - /** - * Wraps the newly created buf from {@code buf.slice} in a packet byte buf. - * - * @param buf the original buf - * @param index the starting index - * @param length the size of the copy - * @return a slice of the buf - * @see ByteBuf#slice(int, int) - */ - public static FriendlyByteBuf slice(ByteBuf buf, int index, int length) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.slice(index, length)); - } - - /** - * Wraps the newly created buf from {@code buf.retainedSlice} in a packet byte buf. - * - * @param buf the original buf - * @param index the starting index - * @param length the size of the copy - * @return a slice of the buf - * @see ByteBuf#retainedSlice(int, int) - */ - public static FriendlyByteBuf retainedSlice(ByteBuf buf, int index, int length) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.retainedSlice(index, length)); - } - - /** - * Wraps the newly created buf from {@code buf.duplicate} in a packet byte buf. - * - * @param buf the original buf - * @return a duplicate of the buf - * @see ByteBuf#duplicate() - */ - public static FriendlyByteBuf duplicate(ByteBuf buf) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.duplicate()); - } - - /** - * Wraps the newly created buf from {@code buf.retainedDuplicate} in a packet byte buf. - * - * @param buf the original buf - * @return a duplicate of the buf - * @see ByteBuf#retainedDuplicate() - */ - public static FriendlyByteBuf retainedDuplicate(ByteBuf buf) { - Objects.requireNonNull(buf, "ByteBuf cannot be null"); - - return new FriendlyByteBuf(buf.retainedDuplicate()); - } - - private PacketByteBufs() { - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/PacketSender.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/PacketSender.java deleted file mode 100644 index 28b23c1d5..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/PacketSender.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; - -import java.util.Objects; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.Packet; -import net.minecraft.resources.ResourceLocation; -import io.netty.channel.ChannelFutureListener; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import org.jetbrains.annotations.Nullable; - -/** - * Represents something that supports sending packets to channels. - * @see PacketByteBufs - */ -public interface PacketSender { - /** - * Makes a packet for a channel. - * - * @param channelName the id of the channel - * @param buf the content of the packet - */ - Packet createPacket(ResourceLocation channelName, FriendlyByteBuf buf); - - /** - * Sends a packet. - * - * @param packet the packet - */ - void sendPacket(Packet packet); - - /** - * Sends a packet. - * - * @param packet the packet - * @param callback an optional callback to execute after the packet is sent, may be {@code null}. The callback may also accept a {@link ChannelFutureListener}. - */ - void sendPacket(Packet packet, @Nullable GenericFutureListener> callback); - - /** - * Sends a packet to a channel. - * - * @param channel the id of the channel - * @param buf the content of the packet - */ - default void sendPacket(ResourceLocation channel, FriendlyByteBuf buf) { - Objects.requireNonNull(channel, "Channel cannot be null"); - Objects.requireNonNull(buf, "Payload cannot be null"); - - this.sendPacket(this.createPacket(channel, buf)); - } - - /** - * Sends a packet to a channel. - * - * @param channel the id of the channel - * @param buf the content of the packet - * @param callback an optional callback to execute after the packet is sent, may be {@code null} - */ - // the generic future listener can accept ChannelFutureListener - default void sendPacket(ResourceLocation channel, FriendlyByteBuf buf, @Nullable GenericFutureListener> callback) { - Objects.requireNonNull(channel, "Channel cannot be null"); - Objects.requireNonNull(buf, "Payload cannot be null"); - - this.sendPacket(this.createPacket(channel, buf), callback); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/PlayerLookup.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/PlayerLookup.java deleted file mode 100644 index 891351ed5..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/PlayerLookup.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Vec3i; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.ServerPlayerConnection; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.ChunkSource; -import net.minecraft.world.phys.Vec3; -import com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor.EntityTrackerAccessor; -import com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor.ThreadedAnvilChunkStorageAccessor; - -/** - * For example, a block entity may use the methods in this class to send a packet to all clients which can see the block entity in order notify clients about a change. - * - *

The word "tracking" means that an entity/chunk on the server is known to a player's client (within in view distance) and the (block) entity should notify tracking clients of changes. - * - *

These methods should only be called on the server thread and only be used on logical a server. - */ -public final class PlayerLookup { - /** - * Gets all the players on the minecraft server. - * - *

The returned collection is immutable. - * - * @param server the server - * @return all players on the server - */ - public static Collection all(MinecraftServer server) { - Objects.requireNonNull(server, "The server cannot be null"); - - // return an immutable collection to guard against accidental removals. - if (server.getPlayerList() != null) { - return Collections.unmodifiableCollection(server.getPlayerList().getPlayers()); - } - - return Collections.emptyList(); - } - - /** - * Gets all the players in a server world. - * - *

The returned collection is immutable. - * - * @param world the server world - * @return the players in the server world - */ - public static Collection world(ServerLevel world) { - Objects.requireNonNull(world, "The world cannot be null"); - - // return an immutable collection to guard against accidental removals. - return Collections.unmodifiableCollection(world.players()); - } - - /** - * Gets all players tracking a chunk in a server world. - * - * @param world the server world - * @param pos the chunk in question - * @return the players tracking the chunk - */ - public static Collection tracking(ServerLevel world, ChunkPos pos) { - Objects.requireNonNull(world, "The world cannot be null"); - Objects.requireNonNull(pos, "The chunk pos cannot be null"); - #if MC_VERSION_1_18_1 || MC_VERSION_1_18_2 - return world.getChunkSource().chunkMap.getPlayers(pos, false); - #else - return world.getChunkSource().chunkMap.getPlayers(pos, false).toList(); - #endif - } - - /** - * Gets all players tracking an entity in a server world. - * - *

The returned collection is immutable. - * - *

Warning: If the provided entity is a player, it is not - * guaranteed by the contract that said player is included in the - * resulting stream. - * - * @param entity the entity being tracked - * @return the players tracking the entity - * @throws IllegalArgumentException if the entity is not in a server world - */ - public static Collection tracking(Entity entity) { - Objects.requireNonNull(entity, "Entity cannot be null"); - ChunkSource manager = entity.level.getChunkSource(); - - if (manager instanceof ServerChunkCache) { - ChunkMap storage = ((ServerChunkCache) manager).chunkMap; - EntityTrackerAccessor tracker = ((ThreadedAnvilChunkStorageAccessor) storage).getEntityMap().get(entity.getId()); - - // return an immutable collection to guard against accidental removals. - if (tracker != null) { - return Collections.unmodifiableCollection(tracker.getPlayersTracking() - .stream().map(ServerPlayerConnection::getPlayer).collect(Collectors.toSet())); - } - - return Collections.emptySet(); - } - - throw new IllegalArgumentException("Only supported on server worlds!"); - } - - /** - * Gets all players tracking a block entity in a server world. - * - * @param blockEntity the block entity - * @return the players tracking the block position - * @throws IllegalArgumentException if the block entity is not in a server world - */ - public static Collection tracking(BlockEntity blockEntity) { - Objects.requireNonNull(blockEntity, "BlockEntity cannot be null"); - - //noinspection ConstantConditions - IJ intrinsics don't know hasWorld == true will result in no null - if (!blockEntity.hasLevel() || blockEntity.getLevel().isClientSide()) { - throw new IllegalArgumentException("Only supported on server worlds!"); - } - - return tracking((ServerLevel) blockEntity.getLevel(), blockEntity.getBlockPos()); - } - - /** - * Gets all players tracking a block position in a server world. - * - * @param world the server world - * @param pos the block position - * @return the players tracking the block position - */ - public static Collection tracking(ServerLevel world, BlockPos pos) { - Objects.requireNonNull(pos, "BlockPos cannot be null"); - - return tracking(world, new ChunkPos(pos)); - } - - /** - * Gets all players around a position in a world. - * - *

The distance check is done in the three-dimensional space instead of in the horizontal plane. - * - * @param world the world - * @param pos the position - * @param radius the maximum distance from the position in blocks - * @return the players around the position - */ - public static Collection around(ServerLevel world, Vec3 pos, double radius) { - double radiusSq = radius * radius; - - return world(world) - .stream() - .filter((p) -> p.distanceToSqr(pos) <= radiusSq) - .collect(Collectors.toList()); - } - - /** - * Gets all players around a position in a world. - * - *

The distance check is done in the three-dimensional space instead of in the horizontal plane. - * - * @param world the world - * @param pos the position (can be a block pos) - * @param radius the maximum distance from the position in blocks - * @return the players around the position - */ - public static Collection around(ServerLevel world, Vec3i pos, double radius) { - double radiusSq = radius * radius; - - return world(world) - .stream() - .filter((p) -> p.distanceToSqr(pos.getX(), pos.getY(), pos.getZ()) <= radiusSq) - .collect(Collectors.toList()); - } - - private PlayerLookup() { - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/S2CPlayChannelEvents.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/S2CPlayChannelEvents.java deleted file mode 100644 index 9d17c21cb..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/S2CPlayChannelEvents.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; - -import java.util.List; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import com.seibel.lod.forge.fabric.api.event.Event; -import com.seibel.lod.forge.fabric.api.event.EventFactory; - -/** - * Offers access to events related to the indication of a connected client's ability to receive packets in certain channels. - */ -public final class S2CPlayChannelEvents { - /** - * An event for the server play network handler receiving an update indicating the connected client's ability to receive packets in certain channels. - * This event may be invoked at any time after login and up to disconnection. - */ - public static final Event REGISTER = EventFactory.createArrayBacked(Register.class, callbacks -> (handler, sender, server, channels) -> { - for (Register callback : callbacks) { - callback.onChannelRegister(handler, sender, server, channels); - } - }); - - /** - * An event for the server play network handler receiving an update indicating the connected client's lack of ability to receive packets in certain channels. - * This event may be invoked at any time after login and up to disconnection. - */ - public static final Event UNREGISTER = EventFactory.createArrayBacked(Unregister.class, callbacks -> (handler, sender, server, channels) -> { - for (Unregister callback : callbacks) { - callback.onChannelUnregister(handler, sender, server, channels); - } - }); - - private S2CPlayChannelEvents() { - } - - /** - * @see S2CPlayChannelEvents#REGISTER - */ - @FunctionalInterface - public interface Register { - void onChannelRegister(ServerGamePacketListenerImpl handler, PacketSender sender, MinecraftServer server, List channels); - } - - /** - * @see S2CPlayChannelEvents#UNREGISTER - */ - @FunctionalInterface - public interface Unregister { - void onChannelUnregister(ServerGamePacketListenerImpl handler, PacketSender sender, MinecraftServer server, List channels); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerLoginConnectionEvents.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerLoginConnectionEvents.java deleted file mode 100644 index 20683c8fa..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerLoginConnectionEvents.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerLoginPacketListenerImpl; -import com.seibel.lod.forge.fabric.api.event.Event; -import com.seibel.lod.forge.fabric.api.event.EventFactory; - -/** - * Offers access to events related to the connection to a client on a logical server while a client is logging in. - */ -public final class ServerLoginConnectionEvents { - /** - * Event indicating a connection entered the LOGIN state, ready for registering query response handlers. - * - * @see ServerLoginNetworking#registerReceiver(ServerLoginPacketListenerImpl, ResourceLocation, ServerLoginNetworking.LoginQueryResponseHandler) - */ - public static final Event INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, server) -> { - for (Init callback : callbacks) { - callback.onLoginInit(handler, server); - } - }); - - /** - * An event for the start of login queries of the server login network handler. - * This event may be used to register {@link ServerLoginNetworking.LoginQueryResponseHandler login query response handlers} - * using {@link ServerLoginNetworking#registerReceiver(ServerLoginPacketListenerImpl, ResourceLocation, ServerLoginNetworking.LoginQueryResponseHandler)} - * since this event is fired just before the first login query response is processed. - * - *

You may send login queries to the connected client using the provided {@link PacketSender}. - */ - public static final Event QUERY_START = EventFactory.createArrayBacked(QueryStart.class, callbacks -> (handler, server, sender, synchronizer) -> { - for (QueryStart callback : callbacks) { - callback.onLoginStart(handler, server, sender, synchronizer); - } - }); - - /** - * An event for the disconnection of the server login network handler. - * - *

No packets should be sent when this event is invoked. - */ - public static final Event DISCONNECT = EventFactory.createArrayBacked(Disconnect.class, callbacks -> (handler, server) -> { - for (Disconnect callback : callbacks) { - callback.onLoginDisconnect(handler, server); - } - }); - - private ServerLoginConnectionEvents() { - } - - /** - * @see ServerLoginConnectionEvents#INIT - */ - @FunctionalInterface - public interface Init { - void onLoginInit(ServerLoginPacketListenerImpl handler, MinecraftServer server); - } - - /** - * @see ServerLoginConnectionEvents#QUERY_START - */ - @FunctionalInterface - public interface QueryStart { - void onLoginStart(ServerLoginPacketListenerImpl handler, MinecraftServer server, PacketSender sender, ServerLoginNetworking.LoginSynchronizer synchronizer); - } - - /** - * @see ServerLoginConnectionEvents#DISCONNECT - */ - @FunctionalInterface - public interface Disconnect { - void onLoginDisconnect(ServerLoginPacketListenerImpl handler, MinecraftServer server); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerLoginNetworking.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerLoginNetworking.java deleted file mode 100644 index 8ca4a24ed..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerLoginNetworking.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; - -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.Future; - -import org.jetbrains.annotations.Nullable; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerLoginPacketListenerImpl; -import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientLoginNetworking; -import com.seibel.lod.forge.fabric.impl.networking.server.ServerNetworkingImpl; -import com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor.ServerLoginNetworkHandlerAccessor; - -/** - * Offers access to login stage server-side networking functionalities. - * - *

Server-side networking functionalities include receiving serverbound query responses and sending clientbound query requests. - * - * @see ServerPlayNetworking - * @see ClientLoginNetworking - */ -public final class ServerLoginNetworking { - /** - * Registers a handler to a query response channel. - * A global receiver is registered to all connections, in the present and future. - * - *

If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made. - * Use {@link #unregisterGlobalReceiver(ResourceLocation)} to unregister the existing handler. - * - * @param channelName the id of the channel - * @param channelHandler the handler - * @return false if a handler is already registered to the channel - * @see ServerLoginNetworking#unregisterGlobalReceiver(ResourceLocation) - * @see ServerLoginNetworking#registerReceiver(ServerLoginPacketListenerImpl, ResourceLocation, LoginQueryResponseHandler) - */ - public static boolean registerGlobalReceiver(ResourceLocation channelName, LoginQueryResponseHandler channelHandler) { - return ServerNetworkingImpl.LOGIN.registerGlobalReceiver(channelName, channelHandler); - } - - /** - * Removes the handler of a query response channel. - * A global receiver is registered to all connections, in the present and future. - * - *

The {@code channel} is guaranteed not to have a handler after this call. - * - * @param channelName the id of the channel - * @return the previous handler, or {@code null} if no handler was bound to the channel - * @see ServerLoginNetworking#registerGlobalReceiver(ResourceLocation, LoginQueryResponseHandler) - * @see ServerLoginNetworking#unregisterReceiver(ServerLoginPacketListenerImpl, ResourceLocation) - */ - @Nullable - public static ServerLoginNetworking.LoginQueryResponseHandler unregisterGlobalReceiver(ResourceLocation channelName) { - return ServerNetworkingImpl.LOGIN.unregisterGlobalReceiver(channelName); - } - - /** - * Gets all channel names which global receivers are registered for. - * A global receiver is registered to all connections, in the present and future. - * - * @return all channel names which global receivers are registered for. - */ - public static Set getGlobalReceivers() { - return ServerNetworkingImpl.LOGIN.getChannels(); - } - - /** - * Registers a handler to a query response channel. - * - *

If a handler is already registered to the {@code channelName}, this method will return {@code false}, and no change will be made. - * Use {@link #unregisterReceiver(ServerLoginPacketListenerImpl, ResourceLocation)} to unregister the existing handler. - * - * @param networkHandler the handler - * @param channelName the id of the channel - * @param responseHandler the handler - * @return false if a handler is already registered to the channel name - */ - public static boolean registerReceiver(ServerLoginPacketListenerImpl networkHandler, ResourceLocation channelName, LoginQueryResponseHandler responseHandler) { - Objects.requireNonNull(networkHandler, "Network handler cannot be null"); - - return ServerNetworkingImpl.getAddon(networkHandler).registerChannel(channelName, responseHandler); - } - - /** - * Removes the handler of a query response channel. - * - *

The {@code channelName} is guaranteed not to have a handler after this call. - * - * @param channelName the id of the channel - * @return the previous handler, or {@code null} if no handler was bound to the channel name - */ - @Nullable - public static ServerLoginNetworking.LoginQueryResponseHandler unregisterReceiver(ServerLoginPacketListenerImpl networkHandler, ResourceLocation channelName) { - Objects.requireNonNull(networkHandler, "Network handler cannot be null"); - - return ServerNetworkingImpl.getAddon(networkHandler).unregisterChannel(channelName); - } - - // Helper methods - - /** - * Returns the Minecraft Server of a server login network handler. - * - * @param handler the server login network handler - */ - public static MinecraftServer getServer(ServerLoginPacketListenerImpl handler) { - Objects.requireNonNull(handler, "Network handler cannot be null"); - - return ((ServerLoginNetworkHandlerAccessor) handler).getServer(); - } - - private ServerLoginNetworking() { - } - - @FunctionalInterface - public interface LoginQueryResponseHandler { - /** - * Handles an incoming query response from a client. - * - *

This method is executed on {@linkplain io.netty.channel.EventLoop netty's event loops}. - * Modification to the game should be {@linkplain net.minecraft.util.thread.BlockableEventLoop#submit(Runnable) scheduled} using the provided Minecraft client instance. - * - *

Whether the client understood the query should be checked before reading from the payload of the packet. - * @param server the server - * @param handler the network handler that received this packet, representing the player/client who sent the response - * @param understood whether the client understood the packet - * @param buf the payload of the packet - * @param synchronizer the synchronizer which may be used to delay log-in till a {@link Future} is completed. - * @param responseSender the packet sender - */ - void receive(MinecraftServer server, ServerLoginPacketListenerImpl handler, boolean understood, FriendlyByteBuf buf, LoginSynchronizer synchronizer, PacketSender responseSender); - } - - /** - * Allows blocking client log-in until all all futures passed into {@link LoginSynchronizer#waitFor(Future)} are completed. - * - * @apiNote this interface is not intended to be implemented by users of api. - */ - @FunctionalInterface - public interface LoginSynchronizer { - /** - * Allows blocking client log-in until the {@code future} is {@link Future#isDone() done}. - * - *

Since packet reception happens on netty's event loops, this allows handlers to - * perform logic on the Server Thread, etc. For instance, a handler can prepare an - * upcoming query request or check necessary login data on the server thread.

- * - *

Here is an example where the player log-in is blocked so that a credential check and - * building of a followup query request can be performed properly on the logical server - * thread before the player successfully logs in: - *

{@code
-		 * ServerLoginNetworking.registerGlobalReceiver(CHECK_CHANNEL, (server, handler, understood, buf, synchronizer, responseSender) -> {
-		 * 	if (!understood) {
-		 * 		handler.disconnect(new LiteralText("Only accept clients that can check!"));
-		 * 		return;
-		 * 	}
-		 *
-		 * 	String checkMessage = buf.readString(32767);
-		 *
-		 * 	// Just send the CompletableFuture returned by the server's submit method
-		 * 	synchronizer.waitFor(server.submit(() -> {
-		 * 		LoginInfoChecker checker = LoginInfoChecker.get(server);
-		 *
-		 * 		if (!checker.check(handler.getConnectionInfo(), checkMessage)) {
-		 * 			handler.disconnect(new LiteralText("Invalid credentials!"));
-		 * 			return;
-		 * 		}
-		 *
-		 * 		responseSender.send(UPCOMING_CHECK, checker.buildSecondQueryPacket(handler, checkMessage));
-		 * 	}));
-		 * });
-		 * }
- * Usually it is enough to pass the return value for {@link net.minecraft.util.thread.BlockableEventLoop#submit(Runnable)} for {@code future}.

- * - * @param future the future that must be done before the player can log in - */ - void waitFor(Future future); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerPlayConnectionEvents.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerPlayConnectionEvents.java deleted file mode 100644 index ad2134761..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerPlayConnectionEvents.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import com.seibel.lod.forge.fabric.api.event.Event; -import com.seibel.lod.forge.fabric.api.event.EventFactory; - -/** - * Offers access to events related to the connection to a client on a logical server while a client is in game. - */ -public final class ServerPlayConnectionEvents { - /** - * Event indicating a connection entered the PLAY state, ready for registering channel handlers. - * - * @see ServerPlayNetworking#registerReceiver(ServerGamePacketListenerImpl, ResourceLocation, ServerPlayNetworking.PlayChannelHandler) - */ - public static final Event INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, server) -> { - for (Init callback : callbacks) { - callback.onPlayInit(handler, server); - } - }); - - /** - * An event for notification when the server play network handler is ready to send packets to the client. - * - *

At this stage, the network handler is ready to send packets to the client. - */ - public static final Event JOIN = EventFactory.createArrayBacked(Join.class, callbacks -> (handler, sender, server) -> { - for (Join callback : callbacks) { - callback.onPlayReady(handler, sender, server); - } - }); - - /** - * An event for the disconnection of the server play network handler. - * - *

No packets should be sent when this event is invoked. - */ - public static final Event DISCONNECT = EventFactory.createArrayBacked(Disconnect.class, callbacks -> (handler, server) -> { - for (Disconnect callback : callbacks) { - callback.onPlayDisconnect(handler, server); - } - }); - - private ServerPlayConnectionEvents() { - } - - @FunctionalInterface - public interface Init { - void onPlayInit(ServerGamePacketListenerImpl handler, MinecraftServer server); - } - - @FunctionalInterface - public interface Join { - void onPlayReady(ServerGamePacketListenerImpl handler, PacketSender sender, MinecraftServer server); - } - - @FunctionalInterface - public interface Disconnect { - void onPlayDisconnect(ServerGamePacketListenerImpl handler, MinecraftServer server); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerPlayNetworking.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerPlayNetworking.java deleted file mode 100644 index 5e27f260d..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/ServerPlayNetworking.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; - -import java.util.Objects; -import java.util.Set; - -import org.jetbrains.annotations.Nullable; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.Packet; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientPlayNetworking; -import com.seibel.lod.forge.fabric.impl.networking.server.ServerNetworkingImpl; - -/** - * Offers access to play stage server-side networking functionalities. - * - *

Server-side networking functionalities include receiving serverbound packets, sending clientbound packets, and events related to server-side network handlers. - * - *

This class should be only used for the logical server. - * - * @see ServerLoginNetworking - * @see ClientPlayNetworking - */ -public final class ServerPlayNetworking { - /** - * Registers a handler to a channel. - * A global receiver is registered to all connections, in the present and future. - * - *

If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made. - * Use {@link #unregisterReceiver(ServerGamePacketListenerImpl, ResourceLocation)} to unregister the existing handler. - * - * @param channelName the id of the channel - * @param channelHandler the handler - * @return false if a handler is already registered to the channel - * @see ServerPlayNetworking#unregisterGlobalReceiver(ResourceLocation) - * @see ServerPlayNetworking#registerReceiver(ServerGamePacketListenerImpl, ResourceLocation, PlayChannelHandler) - */ - public static boolean registerGlobalReceiver(ResourceLocation channelName, PlayChannelHandler channelHandler) { - return ServerNetworkingImpl.PLAY.registerGlobalReceiver(channelName, channelHandler); - } - - /** - * Removes the handler of a channel. - * A global receiver is registered to all connections, in the present and future. - * - *

The {@code channel} is guaranteed not to have a handler after this call. - * - * @param channelName the id of the channel - * @return the previous handler, or {@code null} if no handler was bound to the channel - * @see ServerPlayNetworking#registerGlobalReceiver(ResourceLocation, PlayChannelHandler) - * @see ServerPlayNetworking#unregisterReceiver(ServerGamePacketListenerImpl, ResourceLocation) - */ - @Nullable - public static PlayChannelHandler unregisterGlobalReceiver(ResourceLocation channelName) { - return ServerNetworkingImpl.PLAY.unregisterGlobalReceiver(channelName); - } - - /** - * Gets all channel names which global receivers are registered for. - * A global receiver is registered to all connections, in the present and future. - * - * @return all channel names which global receivers are registered for. - */ - public static Set getGlobalReceivers() { - return ServerNetworkingImpl.PLAY.getChannels(); - } - - /** - * Registers a handler to a channel. - * This method differs from {@link ServerPlayNetworking#registerGlobalReceiver(ResourceLocation, PlayChannelHandler)} since - * the channel handler will only be applied to the player represented by the {@link ServerGamePacketListenerImpl}. - * - *

For example, if you only register a receiver using this method when a {@linkplain ServerLoginNetworking#registerGlobalReceiver(ResourceLocation, ServerLoginNetworking.LoginQueryResponseHandler)} - * login response has been received, you should use {@link ServerPlayConnectionEvents#INIT} to register the channel handler. - * - *

If a handler is already registered to the {@code channelName}, this method will return {@code false}, and no change will be made. - * Use {@link #unregisterReceiver(ServerGamePacketListenerImpl, ResourceLocation)} to unregister the existing handler. - * - * @param networkHandler the handler - * @param channelName the id of the channel - * @param channelHandler the handler - * @return false if a handler is already registered to the channel name - * @see ServerPlayConnectionEvents#INIT - */ - public static boolean registerReceiver(ServerGamePacketListenerImpl networkHandler, ResourceLocation channelName, PlayChannelHandler channelHandler) { - Objects.requireNonNull(networkHandler, "Network handler cannot be null"); - - return ServerNetworkingImpl.getAddon(networkHandler).registerChannel(channelName, channelHandler); - } - - /** - * Removes the handler of a channel. - * - *

The {@code channelName} is guaranteed not to have a handler after this call. - * - * @param channelName the id of the channel - * @return the previous handler, or {@code null} if no handler was bound to the channel name - */ - @Nullable - public static PlayChannelHandler unregisterReceiver(ServerGamePacketListenerImpl networkHandler, ResourceLocation channelName) { - Objects.requireNonNull(networkHandler, "Network handler cannot be null"); - - return ServerNetworkingImpl.getAddon(networkHandler).unregisterChannel(channelName); - } - - /** - * Gets all the channel names that the server can receive packets on. - * - * @param player the player - * @return All the channel names that the server can receive packets on - */ - public static Set getReceived(ServerPlayer player) { - Objects.requireNonNull(player, "Server player entity cannot be null"); - - return getReceived(player.connection); - } - - /** - * Gets all the channel names that the server can receive packets on. - * - * @param handler the network handler - * @return All the channel names that the server can receive packets on - */ - public static Set getReceived(ServerGamePacketListenerImpl handler) { - Objects.requireNonNull(handler, "Server play network handler cannot be null"); - - return ServerNetworkingImpl.getAddon(handler).getReceivableChannels(); - } - - /** - * Gets all channel names that the connected client declared the ability to receive a packets on. - * - * @param player the player - * @return All the channel names the connected client declared the ability to receive a packets on - */ - public static Set getSendable(ServerPlayer player) { - Objects.requireNonNull(player, "Server player entity cannot be null"); - - return getSendable(player.connection); - } - - /** - * Gets all channel names that a the connected client declared the ability to receive a packets on. - * - * @param handler the network handler - * @return True if the connected client has declared the ability to receive a packet on the specified channel - */ - public static Set getSendable(ServerGamePacketListenerImpl handler) { - Objects.requireNonNull(handler, "Server play network handler cannot be null"); - - return ServerNetworkingImpl.getAddon(handler).getSendableChannels(); - } - - /** - * Checks if the connected client declared the ability to receive a packet on a specified channel name. - * - * @param player the player - * @param channelName the channel name - * @return True if the connected client has declared the ability to receive a packet on the specified channel - */ - public static boolean canSend(ServerPlayer player, ResourceLocation channelName) { - Objects.requireNonNull(player, "Server player entity cannot be null"); - - return canSend(player.connection, channelName); - } - - /** - * Checks if the connected client declared the ability to receive a packet on a specified channel name. - * - * @param handler the network handler - * @param channelName the channel name - * @return True if the connected client has declared the ability to receive a packet on the specified channel - */ - public static boolean canSend(ServerGamePacketListenerImpl handler, ResourceLocation channelName) { - Objects.requireNonNull(handler, "Server play network handler cannot be null"); - Objects.requireNonNull(channelName, "Channel name cannot be null"); - - return ServerNetworkingImpl.getAddon(handler).getSendableChannels().contains(channelName); - } - - /** - * Creates a packet which may be sent to a the connected client. - * - * @param channelName the channel name - * @param buf the packet byte buf which represents the payload of the packet - * @return a new packet - */ - public static Packet createS2CPacket(ResourceLocation channelName, FriendlyByteBuf buf) { - Objects.requireNonNull(channelName, "Channel cannot be null"); - Objects.requireNonNull(buf, "Buf cannot be null"); - - return ServerNetworkingImpl.createPlayC2SPacket(channelName, buf); - } - - /** - * Gets the packet sender which sends packets to the connected client. - * - * @param player the player - * @return the packet sender - */ - public static PacketSender getSender(ServerPlayer player) { - Objects.requireNonNull(player, "Server player entity cannot be null"); - - return getSender(player.connection); - } - - /** - * Gets the packet sender which sends packets to the connected client. - * - * @param handler the network handler, representing the connection to the player/client - * @return the packet sender - */ - public static PacketSender getSender(ServerGamePacketListenerImpl handler) { - Objects.requireNonNull(handler, "Server play network handler cannot be null"); - - return ServerNetworkingImpl.getAddon(handler); - } - - /** - * Sends a packet to a player. - * - * @param player the player to send the packet to - * @param channelName the channel of the packet - * @param buf the payload of the packet. - */ - public static void send(ServerPlayer player, ResourceLocation channelName, FriendlyByteBuf buf) { - Objects.requireNonNull(player, "Server player entity cannot be null"); - Objects.requireNonNull(channelName, "Channel name cannot be null"); - Objects.requireNonNull(buf, "Packet byte buf cannot be null"); - - player.connection.send(createS2CPacket(channelName, buf)); - } - - // Helper methods - - /** - * Returns the Minecraft Server of a server play network handler. - * - * @param handler the server play network handler - */ - public static MinecraftServer getServer(ServerGamePacketListenerImpl handler) { - Objects.requireNonNull(handler, "Network handler cannot be null"); - - return handler.player.server; - } - - private ServerPlayNetworking() { - } - - @FunctionalInterface - public interface PlayChannelHandler { - /** - * Handles an incoming packet. - * - *

This method is executed on {@linkplain io.netty.channel.EventLoop netty's event loops}. - * Modification to the game should be {@linkplain net.minecraft.util.thread.BlockableEventLoop#submit(Runnable) scheduled} using the provided Minecraft server instance. - * - *

An example usage of this is to create an explosion where the player is looking: - *

{@code
-		 * ServerPlayNetworking.registerReceiver(new Identifier("mymod", "boom"), (server, player, handler, buf, responseSender) -&rt; {
-		 * 	boolean fire = buf.readBoolean();
-		 *
-		 * 	// All operations on the server or world must be executed on the server thread
-		 * 	server.execute(() -&rt; {
-		 * 		ModPacketHandler.createExplosion(player, fire);
-		 * 	});
-		 * });
-		 * }
- * @param server the server - * @param player the player - * @param handler the network handler that received this packet, representing the player/client who sent the packet - * @param buf the payload of the packet - * @param responseSender the packet sender - */ - void receive(MinecraftServer server, ServerPlayer player, ServerGamePacketListenerImpl handler, FriendlyByteBuf buf, PacketSender responseSender); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/package-info.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/package-info.java deleted file mode 100644 index 1746b78ca..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/networking/v1/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * The Networking API, version 1. - * - *

For login stage networking see {@link net.fabricmc.fabric.api.networking.v1.ServerLoginNetworking}. - * For play stage networking see {@link net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking}. - * - *

For events related to the connection to a client see {@link net.fabricmc.fabric.api.networking.v1.ServerLoginConnectionEvents} for login stage - * or {@link net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents} for play stage. - * - *

For events related to the ability of a client to receive packets on a channel of a specific name see {@link net.fabricmc.fabric.api.networking.v1.S2CPlayChannelEvents}. - */ - -package com.seibel.lod.forge.fabric.api.networking.v1; diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/util/BooleanFunction.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/util/BooleanFunction.java deleted file mode 100644 index 8e5ebf2d5..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/util/BooleanFunction.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.util; - -/** - * Represents a function that accepts an boolean-valued argument and produces a result. - * - *

This is the {@code boolean}-consuming primitive specialization for {@link java.util.function.Function}. - */ -@FunctionalInterface -public interface BooleanFunction { - /** - * Applies this function to the given argument. - * - * @param value the function argument - * @return the function result - */ - R apply(boolean value); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/util/NbtType.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/util/NbtType.java deleted file mode 100644 index f4a61fb75..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/util/NbtType.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.util; - -/** - * NBT type ID constants. Useful for filtering by value type in a few cases. - * - *

For the current list of types, check with {@link NbtElement#TYPES}. - * - * @see NbtCompound#contains(String, int) - * @see net.minecraft.nbt.NbtTypes#byId(int) - */ -public final class NbtType { - public static final int END = 0; - public static final int BYTE = 1; - public static final int SHORT = 2; - public static final int INT = 3; - public static final int LONG = 4; - public static final int FLOAT = 5; - public static final int DOUBLE = 6; - public static final int BYTE_ARRAY = 7; - public static final int STRING = 8; - public static final int LIST = 9; - public static final int COMPOUND = 10; - public static final int INT_ARRAY = 11; - public static final int LONG_ARRAY = 12; - - /** - * Any numeric value: byte, short, int, long, float, double. - * - * @see NbtCompound#contains(String, int) - */ - public static final int NUMBER = 99; - - private NbtType() { } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/api/util/TriState.java b/forge/src/main/java/com/seibel/lod/forge/fabric/api/util/TriState.java deleted file mode 100644 index 4a24f30ea..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/api/util/TriState.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.api.util; - -import java.util.Objects; -import java.util.Optional; -import java.util.function.BooleanSupplier; -import java.util.function.Supplier; - -import org.jetbrains.annotations.Nullable; - -/** - * Represents a boolean value which can be true, false or refer to a default value. - */ -public enum TriState { - /** - * Represents the boolean value of {@code false}. - */ - FALSE, - /** - * Represents a value that refers to a "default" value, often as a fallback. - */ - DEFAULT, - /** - * Represents the boolean value of {@code true}. - */ - TRUE; - - /** - * Gets the corresponding tri-state from a boolean value. - * - * @param bool the boolean value - * @return {@link TriState#TRUE} or {@link TriState#FALSE} depending on the value of the boolean. - */ - public static TriState of(boolean bool) { - return bool ? TRUE : FALSE; - } - - /** - * Gets a tri-state from a nullable boxed boolean. - * - * @param bool the boolean value - * @return {@link TriState#DEFAULT} if {@code null}. - * Otherwise {@link TriState#TRUE} or {@link TriState#FALSE} depending on the value of the boolean. - */ - public static TriState of(@Nullable Boolean bool) { - return bool == null ? DEFAULT : of(bool.booleanValue()); - } - - /** - * Gets the value of the tri-state. - * - * @return true if the tri-state is {@link TriState#TRUE}. - * Otherwise false. - */ - public boolean get() { - return this == TRUE; - } - - /** - * Gets the value of the tri-state as a boxed, nullable boolean. - * - * @return {@code null} if {@link TriState#DEFAULT}. - * Otherwise {@code true} if {@link TriState#TRUE} or {@code false} if {@link TriState#FALSE}. - */ - @Nullable - public Boolean getBoxed() { - return this == DEFAULT ? null : this.get(); - } - - /** - * Gets the value of this tri-state. - * If the value is {@link TriState#DEFAULT} then use the supplied value. - * - * @param value the value to fallback to - * @return the value of the tri-state or the supplied value if {@link TriState#DEFAULT}. - */ - public boolean orElse(boolean value) { - return this == DEFAULT ? value : this.get(); - } - - /** - * Gets the value of this tri-state. - * If the value is {@link TriState#DEFAULT} then use the supplied value. - * - * @param supplier the supplier used to get the value to fallback to - * @return the value of the tri-state or the value of the supplier if the tri-state is {@link TriState#DEFAULT}. - */ - public boolean orElseGet(BooleanSupplier supplier) { - return this == DEFAULT ? supplier.getAsBoolean() : this.get(); - } - - /** - * Maps the boolean value of this tri-state if it is {@link TriState#TRUE} or {@link TriState#FALSE}. - * - * @param mapper the mapper to use - * @param the type of object being supplier by the mapper - * @return an optional containing the mapped value; {@link Optional#empty()} if the tri-state is {@link TriState#DEFAULT} or the value provided by the mapper is {@code null}. - */ - public Optional map(BooleanFunction<@Nullable ? extends T> mapper) { - Objects.requireNonNull(mapper, "Mapper function cannot be null"); - - if (this == DEFAULT) { - return Optional.empty(); - } - - return Optional.ofNullable(mapper.apply(this.get())); - } - - /** - * Gets the value of this tri-state, or throws an exception if this tri-state's value is {@link TriState#DEFAULT}. - * - * @param exceptionSupplier the supplying function that produces an exception to be thrown - * @param Type of the exception to be thrown - * @return the value - * @throws X if the value is {@link TriState#DEFAULT} - */ - public boolean orElseThrow(Supplier exceptionSupplier) throws X { - if (this != DEFAULT) { - return this.get(); - } - - throw exceptionSupplier.get(); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/ArrayBackedEvent.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/ArrayBackedEvent.java deleted file mode 100644 index 276112496..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/ArrayBackedEvent.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.base.event; - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; - -import org.slf4j.LoggerFactory; -import org.slf4j.Logger; - -import net.minecraft.resources.ResourceLocation; - -import com.seibel.lod.forge.fabric.api.event.Event; - -class ArrayBackedEvent extends Event { - static final Logger LOGGER = LoggerFactory.getLogger("fabric-api-base"); - - private final Function invokerFactory; - private final Object lock = new Object(); - private T[] handlers; - /** - * Registered event phases. - */ - private final Map> phases = new LinkedHashMap<>(); - /** - * Phases sorted in the correct dependency order. - */ - private final List> sortedPhases = new ArrayList<>(); - - @SuppressWarnings("unchecked") - ArrayBackedEvent(Class type, Function invokerFactory) { - this.invokerFactory = invokerFactory; - this.handlers = (T[]) Array.newInstance(type, 0); - update(); - } - - void update() { - this.invoker = invokerFactory.apply(handlers); - } - - @Override - public void register(T listener) { - register(DEFAULT_PHASE, listener); - } - - @Override - public void register(ResourceLocation phaseResourceLocation, T listener) { - Objects.requireNonNull(phaseResourceLocation, "Tried to register a listener for a null phase!"); - Objects.requireNonNull(listener, "Tried to register a null listener!"); - - synchronized (lock) { - getOrCreatePhase(phaseResourceLocation, true).addListener(listener); - rebuildInvoker(handlers.length + 1); - } - } - - private EventPhaseData getOrCreatePhase(ResourceLocation id, boolean sortIfCreate) { - EventPhaseData phase = phases.get(id); - - if (phase == null) { - phase = new EventPhaseData<>(id, handlers.getClass().getComponentType()); - phases.put(id, phase); - sortedPhases.add(phase); - - if (sortIfCreate) { - PhaseSorting.sortPhases(sortedPhases); - } - } - - return phase; - } - - private void rebuildInvoker(int newLength) { - // Rebuild handlers. - if (sortedPhases.size() == 1) { - // Special case with a single phase: use the array of the phase directly. - handlers = sortedPhases.get(0).listeners; - } else { - @SuppressWarnings("unchecked") - T[] newHandlers = (T[]) Array.newInstance(handlers.getClass().getComponentType(), newLength); - int newHandlersIndex = 0; - - for (EventPhaseData existingPhase : sortedPhases) { - int length = existingPhase.listeners.length; - System.arraycopy(existingPhase.listeners, 0, newHandlers, newHandlersIndex, length); - newHandlersIndex += length; - } - - handlers = newHandlers; - } - - // Rebuild invoker. - update(); - } - - @Override - public void addPhaseOrdering(ResourceLocation firstPhase, ResourceLocation secondPhase) { - Objects.requireNonNull(firstPhase, "Tried to add an ordering for a null phase."); - Objects.requireNonNull(secondPhase, "Tried to add an ordering for a null phase."); - if (firstPhase.equals(secondPhase)) throw new IllegalArgumentException("Tried to add a phase that depends on itself."); - - synchronized (lock) { - EventPhaseData first = getOrCreatePhase(firstPhase, false); - EventPhaseData second = getOrCreatePhase(secondPhase, false); - first.subsequentPhases.add(second); - second.previousPhases.add(first); - PhaseSorting.sortPhases(this.sortedPhases); - rebuildInvoker(handlers.length); - } - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/EventFactoryImpl.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/EventFactoryImpl.java deleted file mode 100644 index cfe5c86ba..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/EventFactoryImpl.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.base.event; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Proxy; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - -import net.minecraft.resources.ResourceLocation; - -import com.seibel.lod.forge.fabric.api.event.Event; - -public final class EventFactoryImpl { - private static final List> ARRAY_BACKED_EVENTS = new ArrayList<>(); - - private EventFactoryImpl() { } - - public static void invalidate() { - ARRAY_BACKED_EVENTS.forEach(ArrayBackedEvent::update); - } - - public static Event createArrayBacked(Class type, Function invokerFactory) { - ArrayBackedEvent event = new ArrayBackedEvent<>(type, invokerFactory); - ARRAY_BACKED_EVENTS.add(event); - return event; - } - - public static void ensureContainsDefault(ResourceLocation[] defaultPhases) { - for (ResourceLocation id : defaultPhases) { - if (id.equals(Event.DEFAULT_PHASE)) { - return; - } - } - - throw new IllegalArgumentException("The event phases must contain Event.DEFAULT_PHASE."); - } - - public static void ensureNoDuplicates(ResourceLocation[] defaultPhases) { - for (int i = 0; i < defaultPhases.length; ++i) { - for (int j = i+1; j < defaultPhases.length; ++j) { - if (defaultPhases[i].equals(defaultPhases[j])) { - throw new IllegalArgumentException("Duplicate event phase: " + defaultPhases[i]); - } - } - } - } - - // Code originally by sfPlayer1. - // Unfortunately, it's slightly slower than just passing an empty array in the first place. - private static T buildEmptyInvoker(Class handlerClass, Function invokerSetup) { - // find the functional interface method - Method funcIfMethod = null; - - for (Method m : handlerClass.getMethods()) { - if ((m.getModifiers() & (Modifier.STRICT | Modifier.PRIVATE)) == 0) { - if (funcIfMethod != null) { - throw new IllegalStateException("Multiple virtual methods in " + handlerClass + "; cannot build empty invoker!"); - } - - funcIfMethod = m; - } - } - - if (funcIfMethod == null) { - throw new IllegalStateException("No virtual methods in " + handlerClass + "; cannot build empty invoker!"); - } - - Object defValue = null; - - try { - // concert to mh, determine its type without the "this" reference - MethodHandle target = MethodHandles.lookup().unreflect(funcIfMethod); - MethodType type = target.type().dropParameterTypes(0, 1); - - if (type.returnType() != void.class) { - // determine default return value by invoking invokerSetup.apply(T[0]) with all-jvm-default args (null for refs, false for boolean, etc.) - // explicitCastArguments is being used to cast Object=null to the jvm default value for the correct type - - // construct method desc (TLjava/lang/Object;Ljava/lang/Object;...)R where T = invoker ref ("this"), R = invoker ret type and args 1+ are Object for each non-"this" invoker arg - MethodType objTargetType = MethodType.genericMethodType(type.parameterCount()).changeReturnType(type.returnType()).insertParameterTypes(0, target.type().parameterType(0)); - // explicit cast to translate to the invoker args from Object to their real type, inferring jvm default values - MethodHandle objTarget = MethodHandles.explicitCastArguments(target, objTargetType); - - // build invocation args with 0 = "this", 1+ = null - Object[] args = new Object[target.type().parameterCount()]; - //noinspection unchecked - args[0] = invokerSetup.apply((T[]) Array.newInstance(handlerClass, 0)); - - // retrieve default by invoking invokerSetup.apply(T[0]).targetName(def,def,...) - defValue = objTarget.invokeWithArguments(args); - } - } catch (Throwable t) { - throw new RuntimeException(t); - } - - final Object returnValue = defValue; - //noinspection unchecked - return (T) Proxy.newProxyInstance(EventFactoryImpl.class.getClassLoader(), new Class[]{handlerClass}, - (proxy, method, args) -> returnValue); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/EventPhaseData.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/EventPhaseData.java deleted file mode 100644 index 5c2eeeec7..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/EventPhaseData.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.base.event; - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import net.minecraft.resources.ResourceLocation; - -/** - * Data of an {@link ArrayBackedEvent} phase. - */ -class EventPhaseData { - final ResourceLocation id; - T[] listeners; - final List> subsequentPhases = new ArrayList<>(); - final List> previousPhases = new ArrayList<>(); - int visitStatus = 0; // 0: not visited, 1: visiting, 2: visited - - @SuppressWarnings("unchecked") - EventPhaseData(ResourceLocation id, Class listenerClass) { - this.id = id; - this.listeners = (T[]) Array.newInstance(listenerClass, 0); - } - - void addListener(T listener) { - int oldLength = listeners.length; - listeners = Arrays.copyOf(listeners, oldLength + 1); - listeners[oldLength] = listener; - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/PhaseSorting.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/PhaseSorting.java deleted file mode 100644 index 8cb24fa68..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/base/event/PhaseSorting.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.base.event; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.PriorityQueue; - -import com.google.common.annotations.VisibleForTesting; -import org.jetbrains.annotations.ApiStatus; - -/** - * Contains phase-sorting logic for {@link ArrayBackedEvent}. - */ -@ApiStatus.Internal -public class PhaseSorting { - @VisibleForTesting - public static boolean ENABLE_CYCLE_WARNING = true; - - /** - * Deterministically sort a list of phases. - * 1) Compute phase SCCs (i.e. cycles). - * 2) Sort phases by id within SCCs. - * 3) Sort SCCs with respect to each other by respecting constraints, and by id in case of a tie. - */ - static void sortPhases(List> sortedPhases) { - // FIRST KOSARAJU SCC VISIT - List> toposort = new ArrayList<>(sortedPhases.size()); - - for (EventPhaseData phase : sortedPhases) { - forwardVisit(phase, null, toposort); - } - - clearStatus(toposort); - Collections.reverse(toposort); - - // SECOND KOSARAJU SCC VISIT - Map, PhaseScc> phaseToScc = new IdentityHashMap<>(); - - for (EventPhaseData phase : toposort) { - if (phase.visitStatus == 0) { - List> sccPhases = new ArrayList<>(); - // Collect phases in SCC. - backwardVisit(phase, sccPhases); - // Sort phases by id. - sccPhases.sort(Comparator.comparing(p -> p.id)); - // Mark phases as belonging to this SCC. - PhaseScc scc = new PhaseScc<>(sccPhases); - - for (EventPhaseData phaseInScc : sccPhases) { - phaseToScc.put(phaseInScc, scc); - } - } - } - - clearStatus(toposort); - - // Build SCC graph - for (PhaseScc scc : phaseToScc.values()) { - for (EventPhaseData phase : scc.phases) { - for (EventPhaseData subsequentPhase : phase.subsequentPhases) { - PhaseScc subsequentScc = phaseToScc.get(subsequentPhase); - - if (subsequentScc != scc) { - scc.subsequentSccs.add(subsequentScc); - subsequentScc.inDegree++; - } - } - } - } - - // Order SCCs according to priorities. When there is a choice, use the SCC with the lowest id. - // The priority queue contains all SCCs that currently have 0 in-degree. - PriorityQueue> pq = new PriorityQueue<>(Comparator.comparing(scc -> scc.phases.get(0).id)); - sortedPhases.clear(); - - for (PhaseScc scc : phaseToScc.values()) { - if (scc.inDegree == 0) { - pq.add(scc); - // Prevent adding the same SCC multiple times, as phaseToScc may contain the same value multiple times. - scc.inDegree = -1; - } - } - - while (!pq.isEmpty()) { - PhaseScc scc = pq.poll(); - sortedPhases.addAll(scc.phases); - - for (PhaseScc subsequentScc : scc.subsequentSccs) { - subsequentScc.inDegree--; - - if (subsequentScc.inDegree == 0) { - pq.add(subsequentScc); - } - } - } - } - - private static void forwardVisit(EventPhaseData phase, EventPhaseData parent, List> toposort) { - if (phase.visitStatus == 0) { - // Not yet visited. - phase.visitStatus = 1; - - for (EventPhaseData data : phase.subsequentPhases) { - forwardVisit(data, phase, toposort); - } - - toposort.add(phase); - phase.visitStatus = 2; - } else if (phase.visitStatus == 1 && ENABLE_CYCLE_WARNING) { - // Already visiting, so we have found a cycle. - ArrayBackedEvent.LOGGER.warn(String.format( - "Event phase ordering conflict detected.%nEvent phase %s is ordered both before and after event phase %s.", - phase.id, - parent.id - )); - } - } - - private static void clearStatus(List> phases) { - for (EventPhaseData phase : phases) { - phase.visitStatus = 0; - } - } - - private static void backwardVisit(EventPhaseData phase, List> sccPhases) { - if (phase.visitStatus == 0) { - phase.visitStatus = 1; - sccPhases.add(phase); - - for (EventPhaseData data : phase.previousPhases) { - backwardVisit(data, sccPhases); - } - } - } - - private static class PhaseScc { - final List> phases; - final List> subsequentSccs = new ArrayList<>(); - int inDegree = 0; - - private PhaseScc(List> phases) { - this.phases = phases; - } - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/AbstractChanneledNetworkAddon.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/AbstractChanneledNetworkAddon.java deleted file mode 100644 index 9c3ba39f7..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/AbstractChanneledNetworkAddon.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking; - -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import io.netty.util.AsciiString; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import org.jetbrains.annotations.Nullable; -import com.seibel.lod.forge.fabric.api.networking.v1.PacketByteBufs; -import com.seibel.lod.forge.fabric.api.networking.v1.PacketSender; -import net.minecraft.ResourceLocationException; -import net.minecraft.network.Connection; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.Packet; -import net.minecraft.resources.ResourceLocation; - -/** - * A network addon which is aware of the channels the other side may receive. - * - * @param the channel handler type - */ -public abstract class AbstractChanneledNetworkAddon extends AbstractNetworkAddon implements PacketSender { - protected final Connection connection; - protected final GlobalReceiverRegistry receiver; - protected final Set sendableChannels; - protected final Set sendableChannelsView; - - protected AbstractChanneledNetworkAddon(GlobalReceiverRegistry receiver, Connection connection, String description) { - this(receiver, connection, new HashSet<>(), description); - } - - protected AbstractChanneledNetworkAddon(GlobalReceiverRegistry receiver, Connection connection, Set sendableChannels, String description) { - super(receiver, description); - this.connection = connection; - this.receiver = receiver; - this.sendableChannels = sendableChannels; - this.sendableChannelsView = Collections.unmodifiableSet(sendableChannels); - } - - public abstract void lateInit(); - - protected void registerPendingChannels(ChannelInfoHolder holder) { - final Collection pending = holder.getPendingChannelsNames(); - - if (!pending.isEmpty()) { - register(new ArrayList<>(pending)); - pending.clear(); - } - } - - // always supposed to handle async! - protected boolean handle(ResourceLocation channelName, FriendlyByteBuf originalBuf) { - this.logger.debug("Handling inbound packet from channel with name \"{}\"", channelName); - - // Handle reserved packets - if (NetworkingImpl.REGISTER_CHANNEL.equals(channelName)) { - this.receiveRegistration(true, PacketByteBufs.slice(originalBuf)); - return true; - } - - if (NetworkingImpl.UNREGISTER_CHANNEL.equals(channelName)) { - this.receiveRegistration(false, PacketByteBufs.slice(originalBuf)); - return true; - } - - @Nullable H handler = this.getHandler(channelName); - - if (handler == null) { - return false; - } - - FriendlyByteBuf buf = PacketByteBufs.slice(originalBuf); - - try { - this.receive(handler, buf); - } catch (Throwable ex) { - this.logger.error("Encountered exception while handling in channel with name \"{}\"", channelName, ex); - throw ex; - } - - return true; - } - - protected abstract void receive(H handler, FriendlyByteBuf buf); - - protected void sendInitialChannelRegistrationPacket() { - final FriendlyByteBuf buf = this.createRegistrationPacket(this.getReceivableChannels()); - - if (buf != null) { - this.sendPacket(NetworkingImpl.REGISTER_CHANNEL, buf); - } - } - - @Nullable - protected FriendlyByteBuf createRegistrationPacket(Collection channels) { - if (channels.isEmpty()) { - return null; - } - - FriendlyByteBuf buf = PacketByteBufs.create(); - boolean first = true; - - for (ResourceLocation channel : channels) { - if (first) { - first = false; - } else { - buf.writeByte(0); - } - - buf.writeBytes(channel.toString().getBytes(StandardCharsets.US_ASCII)); - } - - return buf; - } - - // wrap in try with res (buf) - protected void receiveRegistration(boolean register, FriendlyByteBuf buf) { - List ids = new ArrayList<>(); - StringBuilder active = new StringBuilder(); - - while (buf.isReadable()) { - byte b = buf.readByte(); - - if (b != 0) { - active.append(AsciiString.b2c(b)); - } else { - this.addId(ids, active); - active = new StringBuilder(); - } - } - - this.addId(ids, active); - this.schedule(register ? () -> register(ids) : () -> unregister(ids)); - } - - void register(List ids) { - this.sendableChannels.addAll(ids); - this.invokeRegisterEvent(ids); - } - - void unregister(List ids) { - this.sendableChannels.removeAll(ids); - this.invokeUnregisterEvent(ids); - } - - @Override - public void sendPacket(Packet packet) { - Objects.requireNonNull(packet, "Packet cannot be null"); - - this.connection.send(packet); - } - - @Override - public void sendPacket(Packet packet, GenericFutureListener> callback) { - Objects.requireNonNull(packet, "Packet cannot be null"); - - this.connection.send(packet, callback); - } - - /** - * Schedules a task to run on the main thread. - */ - protected abstract void schedule(Runnable task); - - protected abstract void invokeRegisterEvent(List ids); - - protected abstract void invokeUnregisterEvent(List ids); - - private void addId(List ids, StringBuilder sb) { - String literal = sb.toString(); - - try { - ids.add(new ResourceLocation(literal)); - } catch (ResourceLocationException ex) { - this.logger.warn("Received invalid channel identifier \"{}\" from connection {}", literal, this.connection); - } - } - - public Set getSendableChannels() { - return this.sendableChannelsView; - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/AbstractNetworkAddon.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/AbstractNetworkAddon.java deleted file mode 100644 index b07029a7a..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/AbstractNetworkAddon.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import net.minecraft.resources.ResourceLocation; -import org.slf4j.LoggerFactory; -import org.slf4j.Logger; -import org.jetbrains.annotations.Nullable; - -/** - * A network addon is a simple abstraction to hold information about a player's registered channels. - * - * @param the channel handler type - */ -public abstract class AbstractNetworkAddon { - protected final GlobalReceiverRegistry receiver; - protected final Logger logger; - // A lock is used due to possible access on netty's event loops and game thread at same times such as during dynamic registration - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - // Sync map should be fine as there is little read write competition - // All access to this map is guarded by the lock - private final Map handlers = new HashMap<>(); - private final AtomicBoolean disconnected = new AtomicBoolean(); // blocks redundant disconnect notifications - - protected AbstractNetworkAddon(GlobalReceiverRegistry receiver, String description) { - this.receiver = receiver; - this.logger = LoggerFactory.getLogger(description); - } - - @Nullable - public H getHandler(ResourceLocation channel) { - Lock lock = this.lock.readLock(); - lock.lock(); - - try { - return this.handlers.get(channel); - } finally { - lock.unlock(); - } - } - - public boolean registerChannel(ResourceLocation channelName, H handler) { - Objects.requireNonNull(channelName, "Channel name cannot be null"); - Objects.requireNonNull(handler, "Packet handler cannot be null"); - - if (this.isReservedChannel(channelName)) { - throw new IllegalArgumentException(String.format("Cannot register handler for reserved channel with name \"%s\"", channelName)); - } - - Lock lock = this.lock.writeLock(); - lock.lock(); - - try { - final boolean replaced = this.handlers.putIfAbsent(channelName, handler) == null; - - if (replaced) { - this.handleRegistration(channelName); - } - - return replaced; - } finally { - lock.unlock(); - } - } - - public H unregisterChannel(ResourceLocation channelName) { - Objects.requireNonNull(channelName, "Channel name cannot be null"); - - if (this.isReservedChannel(channelName)) { - throw new IllegalArgumentException(String.format("Cannot register handler for reserved channel with name \"%s\"", channelName)); - } - - Lock lock = this.lock.writeLock(); - lock.lock(); - - try { - final H removed = this.handlers.remove(channelName); - - if (removed != null) { - this.handleUnregistration(channelName); - } - - return removed; - } finally { - lock.unlock(); - } - } - - public Set getReceivableChannels() { - Lock lock = this.lock.readLock(); - lock.lock(); - - try { - return new HashSet<>(this.handlers.keySet()); - } finally { - lock.unlock(); - } - } - - protected abstract void handleRegistration(ResourceLocation channelName); - - protected abstract void handleUnregistration(ResourceLocation channelName); - - public final void handleDisconnect() { - if (disconnected.compareAndSet(false, true)) { - invokeDisconnectEvent(); - } - } - - protected abstract void invokeDisconnectEvent(); - - /** - * Checks if a channel is considered a "reserved" channel. - * A reserved channel such as "minecraft:(un)register" has special handling and should not have any channel handlers registered for it. - * - * @param channelName the channel name - * @return whether the channel is reserved - */ - protected abstract boolean isReservedChannel(ResourceLocation channelName); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/ChannelInfoHolder.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/ChannelInfoHolder.java deleted file mode 100644 index e713fe157..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/ChannelInfoHolder.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking; - -import java.util.Collection; -import net.minecraft.resources.ResourceLocation; - -public interface ChannelInfoHolder { - /** - * @return Channels which are declared as receivable by the other side but have not been declared yet. - */ - Collection getPendingChannelsNames(); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/DisconnectPacketSource.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/DisconnectPacketSource.java deleted file mode 100644 index be14224b1..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/DisconnectPacketSource.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking; - -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.Packet; - -public interface DisconnectPacketSource { - Packet createDisconnectPacket(Component message); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/GlobalReceiverRegistry.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/GlobalReceiverRegistry.java deleted file mode 100644 index 4454385a4..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/GlobalReceiverRegistry.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import net.minecraft.resources.ResourceLocation; -import org.jetbrains.annotations.Nullable; - -public final class GlobalReceiverRegistry { - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - private final Map handlers; - private final Set> trackedAddons = new HashSet<>(); - - public GlobalReceiverRegistry() { - this(new HashMap<>()); // sync map should be fine as there is little read write competitions - } - - public GlobalReceiverRegistry(Map map) { - this.handlers = map; - } - - @Nullable - public H getHandler(ResourceLocation channelName) { - Lock lock = this.lock.readLock(); - lock.lock(); - - try { - return this.handlers.get(channelName); - } finally { - lock.unlock(); - } - } - - public boolean registerGlobalReceiver(ResourceLocation channelName, H handler) { - Objects.requireNonNull(channelName, "Channel name cannot be null"); - Objects.requireNonNull(handler, "Channel handler cannot be null"); - - if (NetworkingImpl.isReservedPlayChannel(channelName)) { - throw new IllegalArgumentException(String.format("Cannot register handler for reserved channel with name \"%s\"", channelName)); - } - - Lock lock = this.lock.writeLock(); - lock.lock(); - - try { - final boolean replaced = this.handlers.putIfAbsent(channelName, handler) == null; - - if (!replaced) { - this.handleRegistration(channelName, handler); - } - - return replaced; - } finally { - lock.unlock(); - } - } - - public H unregisterGlobalReceiver(ResourceLocation channelName) { - Objects.requireNonNull(channelName, "Channel name cannot be null"); - - if (NetworkingImpl.isReservedPlayChannel(channelName)) { - throw new IllegalArgumentException(String.format("Cannot unregister packet handler for reserved channel with name \"%s\"", channelName)); - } - - Lock lock = this.lock.writeLock(); - lock.lock(); - - try { - final H removed = this.handlers.remove(channelName); - - if (removed != null) { - this.handleUnregistration(channelName); - } - - return removed; - } finally { - lock.unlock(); - } - } - - public Map getHandlers() { - Lock lock = this.lock.writeLock(); - lock.lock(); - - try { - return new HashMap<>(this.handlers); - } finally { - lock.unlock(); - } - } - - public Set getChannels() { - Lock lock = this.lock.readLock(); - lock.lock(); - - try { - return new HashSet<>(this.handlers.keySet()); - } finally { - lock.unlock(); - } - } - - // State tracking methods - - public void startSession(AbstractNetworkAddon addon) { - Lock lock = this.lock.writeLock(); - lock.lock(); - - try { - this.trackedAddons.add(addon); - } finally { - lock.unlock(); - } - } - - public void endSession(AbstractNetworkAddon addon) { - Lock lock = this.lock.writeLock(); - lock.lock(); - - try { - this.trackedAddons.remove(addon); - } finally { - lock.unlock(); - } - } - - private void handleRegistration(ResourceLocation channelName, H handler) { - Lock lock = this.lock.writeLock(); - lock.lock(); - - try { - for (AbstractNetworkAddon addon : this.trackedAddons) { - addon.registerChannel(channelName, handler); - } - } finally { - lock.unlock(); - } - } - - private void handleUnregistration(ResourceLocation channelName) { - Lock lock = this.lock.writeLock(); - lock.lock(); - - try { - for (AbstractNetworkAddon addon : this.trackedAddons) { - addon.unregisterChannel(channelName); - } - } finally { - lock.unlock(); - } - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/NetworkHandlerExtensions.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/NetworkHandlerExtensions.java deleted file mode 100644 index ec2919a03..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/NetworkHandlerExtensions.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking; - -public interface NetworkHandlerExtensions { - AbstractNetworkAddon getAddon(); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/NetworkingImpl.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/NetworkingImpl.java deleted file mode 100644 index 01edeef2d..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/NetworkingImpl.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import net.minecraft.network.FriendlyByteBuf; -import org.slf4j.LoggerFactory; -import org.slf4j.Logger; -import com.seibel.lod.forge.fabric.api.networking.v1.PacketByteBufs; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerLoginConnectionEvents; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerLoginNetworking; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerPlayNetworking; -import net.minecraft.resources.ResourceLocation; - -public final class NetworkingImpl { - public static final String MOD_ID = "fabric-networking-api-v1"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - /** - * Id of packet used to register supported channels. - */ - public static final ResourceLocation REGISTER_CHANNEL = new ResourceLocation("minecraft", "register"); - /** - * Id of packet used to unregister supported channels. - */ - public static final ResourceLocation UNREGISTER_CHANNEL = new ResourceLocation("minecraft", "unregister"); - /** - * Id of the packet used to declare all currently supported channels. - * Dynamic registration of supported channels is still allowed using {@link NetworkingImpl#REGISTER_CHANNEL} and {@link NetworkingImpl#UNREGISTER_CHANNEL}. - */ - public static final ResourceLocation EARLY_REGISTRATION_CHANNEL = new ResourceLocation(MOD_ID, "early_registration"); - - public static void init() { - // Login setup - ServerLoginConnectionEvents.QUERY_START.register((handler, server, sender, synchronizer) -> { - // Send early registration packet - FriendlyByteBuf buf = PacketByteBufs.create(); - Collection channelsNames = ServerPlayNetworking.getGlobalReceivers(); - buf.writeVarInt(channelsNames.size()); - - for (ResourceLocation id : channelsNames) { - buf.writeResourceLocation(id); - } - - sender.sendPacket(EARLY_REGISTRATION_CHANNEL, buf); - NetworkingImpl.LOGGER.debug("Sent accepted channels to the client for \"{}\"", handler.getUserName()); - }); - - ServerLoginNetworking.registerGlobalReceiver(EARLY_REGISTRATION_CHANNEL, (server, handler, understood, buf, synchronizer, sender) -> { - if (!understood) { - // The client is likely a vanilla client. - return; - } - - int n = buf.readVarInt(); - List ids = new ArrayList<>(n); - - for (int i = 0; i < n; i++) { - ids.add(buf.readResourceLocation()); - } - - ((ChannelInfoHolder) handler.getConnection()).getPendingChannelsNames().addAll(ids); - NetworkingImpl.LOGGER.debug("Received accepted channels from the client for \"{}\"", handler.getUserName()); - }); - } - - public static boolean isReservedPlayChannel(ResourceLocation channelName) { - return channelName.equals(REGISTER_CHANNEL) || channelName.equals(UNREGISTER_CHANNEL); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/PacketCallbackListener.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/PacketCallbackListener.java deleted file mode 100644 index e7e2ecefc..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/PacketCallbackListener.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking; - -import net.minecraft.network.protocol.Packet; - -public interface PacketCallbackListener { - /** - * Called after a packet has been sent. - * - * @param packet the packet - */ - void sent(Packet packet); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/client/ClientLoginNetworkAddon.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/client/ClientLoginNetworkAddon.java deleted file mode 100644 index dcd655ae4..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/client/ClientLoginNetworkAddon.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking.client; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; - -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import org.jetbrains.annotations.Nullable; -import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientLoginConnectionEvents; -import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientLoginNetworking; -import com.seibel.lod.forge.fabric.api.networking.v1.FutureListeners; -import com.seibel.lod.forge.fabric.api.networking.v1.PacketByteBufs; -import com.seibel.lod.forge.fabric.impl.networking.AbstractNetworkAddon; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.login.ClientboundCustomQueryPacket; -import net.minecraft.network.protocol.login.ServerboundCustomQueryPacket; -import net.minecraft.resources.ResourceLocation; - -public final class ClientLoginNetworkAddon extends AbstractNetworkAddon { - private final ClientHandshakePacketListenerImpl handler; - private final Minecraft client; - private boolean firstResponse = true; - - public ClientLoginNetworkAddon(ClientHandshakePacketListenerImpl handler, Minecraft client) { - super(ClientNetworkingImpl.LOGIN, "ClientLoginNetworkAddon for Client"); - this.handler = handler; - this.client = client; - - ClientLoginConnectionEvents.INIT.invoker().onLoginStart(this.handler, this.client); - this.receiver.startSession(this); - } - - public boolean handlePacket(ClientboundCustomQueryPacket packet) { - return handlePacket(packet.getTransactionId(), packet.getIdentifier(), packet.getData()); - } - - private boolean handlePacket(int queryId, ResourceLocation channelName, FriendlyByteBuf originalBuf) { - this.logger.debug("Handling inbound login response with id {} and channel with name {}", queryId, channelName); - - if (this.firstResponse) { - // Register global handlers - for (Map.Entry entry : ClientNetworkingImpl.LOGIN.getHandlers().entrySet()) { - ClientLoginNetworking.registerReceiver(entry.getKey(), entry.getValue()); - } - - ClientLoginConnectionEvents.QUERY_START.invoker().onLoginQueryStart(this.handler, this.client); - this.firstResponse = false; - } - - @Nullable ClientLoginNetworking.LoginQueryRequestHandler handler = this.getHandler(channelName); - - if (handler == null) { - return false; - } - - FriendlyByteBuf buf = PacketByteBufs.slice(originalBuf); - List>> futureListeners = new ArrayList<>(); - - try { - CompletableFuture<@Nullable FriendlyByteBuf> future = handler.receive(this.client, this.handler, buf, futureListeners::add); - future.thenAccept(result -> { - ServerboundCustomQueryPacket packet = new ServerboundCustomQueryPacket(queryId, result); - GenericFutureListener> listener = null; - - for (GenericFutureListener> each : futureListeners) { - listener = FutureListeners.union(listener, each); - } - - this.handler.getConnection().send(packet, listener); - }); - } catch (Throwable ex) { - this.logger.error("Encountered exception while handling in channel with name \"{}\"", channelName, ex); - throw ex; - } - - return true; - } - - @Override - protected void handleRegistration(ResourceLocation channelName) { - } - - @Override - protected void handleUnregistration(ResourceLocation channelName) { - } - - @Override - protected void invokeDisconnectEvent() { - ClientLoginConnectionEvents.DISCONNECT.invoker().onLoginDisconnect(this.handler, this.client); - this.receiver.endSession(this); - } - - public void handlePlayTransition() { - this.receiver.endSession(this); - } - - @Override - protected boolean isReservedChannel(ResourceLocation channelName) { - return false; - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/client/ClientNetworkingImpl.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/client/ClientNetworkingImpl.java deleted file mode 100644 index e2576d1cd..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/client/ClientNetworkingImpl.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking.client; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -import org.jetbrains.annotations.Nullable; -import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientLoginNetworking; -import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientPlayConnectionEvents; -import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientPlayNetworking; -import com.seibel.lod.forge.fabric.api.networking.v1.PacketByteBufs; -import com.seibel.lod.forge.fabric.impl.networking.ChannelInfoHolder; -import com.seibel.lod.forge.fabric.impl.networking.GlobalReceiverRegistry; -import com.seibel.lod.forge.fabric.impl.networking.NetworkHandlerExtensions; -import com.seibel.lod.forge.fabric.impl.networking.NetworkingImpl; -import com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor.ConnectScreenAccessor; -import com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor.MinecraftClientAccessor; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.ConnectScreen; -import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.network.Connection; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket; -import net.minecraft.resources.ResourceLocation; - -public final class ClientNetworkingImpl { - public static final GlobalReceiverRegistry LOGIN = new GlobalReceiverRegistry<>(); - public static final GlobalReceiverRegistry PLAY = new GlobalReceiverRegistry<>(); - private static ClientPlayNetworkAddon currentPlayAddon; - - public static ClientPlayNetworkAddon getAddon(ClientPacketListener handler) { - return (ClientPlayNetworkAddon) ((NetworkHandlerExtensions) handler).getAddon(); - } - - public static ClientLoginNetworkAddon getAddon(ClientHandshakePacketListenerImpl handler) { - return (ClientLoginNetworkAddon) ((NetworkHandlerExtensions) handler).getAddon(); - } - - public static Packet createPlayC2SPacket(ResourceLocation channelName, FriendlyByteBuf buf) { - return new ServerboundCustomPayloadPacket(channelName, buf); - } - - /** - * Due to the way logging into a integrated or remote dedicated server will differ, we need to obtain the login client connection differently. - */ - @Nullable - public static Connection getLoginConnection() { - final Connection connection = ((MinecraftClientAccessor) Minecraft.getInstance()).getConnection(); - - // Check if we are connecting to an integrated server. This will set the field on MinecraftClient - if (connection != null) { - return connection; - } else { - // We are probably connecting to a remote server. - // Check if the ConnectScreen is the currentScreen to determine that: - if (Minecraft.getInstance().screen instanceof ConnectScreen) { - return ((ConnectScreenAccessor) Minecraft.getInstance().screen).getConnection(); - } - } - - // We are not connected to a server at all. - return null; - } - - @Nullable - public static ClientPlayNetworkAddon getClientPlayAddon() { - // Since Minecraft can be a bit weird, we need to check for the play addon in a few ways: - // If the client's player is set this will work - if (Minecraft.getInstance().getConnection() != null) { - currentPlayAddon = null; // Shouldn't need this anymore - return ClientNetworkingImpl.getAddon(Minecraft.getInstance().getConnection()); - } - - // We haven't hit the end of onGameJoin yet, use our backing field here to access the network handler - if (currentPlayAddon != null) { - return currentPlayAddon; - } - - // We are not in play stage - return null; - } - - public static void setClientPlayAddon(ClientPlayNetworkAddon addon) { - currentPlayAddon = addon; - } - - public static void clientInit() { - // Reference cleanup for the locally stored addon if we are disconnected - ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> { - currentPlayAddon = null; - }); - - // Register a login query handler for early channel registration. - ClientLoginNetworking.registerGlobalReceiver(NetworkingImpl.EARLY_REGISTRATION_CHANNEL, (client, handler, buf, listenerAdder) -> { - int n = buf.readVarInt(); - List ids = new ArrayList<>(n); - - for (int i = 0; i < n; i++) { - ids.add(buf.readResourceLocation()); - } - - ((ChannelInfoHolder) handler.getConnection()).getPendingChannelsNames().addAll(ids); - NetworkingImpl.LOGGER.debug("Received accepted channels from the server"); - - FriendlyByteBuf response = PacketByteBufs.create(); - Collection channels = ClientPlayNetworking.getGlobalReceivers(); - response.writeVarInt(channels.size()); - - for (ResourceLocation id : channels) { - response.writeResourceLocation(id); - } - - NetworkingImpl.LOGGER.debug("Sent accepted channels to the server"); - return CompletableFuture.completedFuture(response); - }); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/client/ClientPlayNetworkAddon.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/client/ClientPlayNetworkAddon.java deleted file mode 100644 index 001136712..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/client/ClientPlayNetworkAddon.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking.client; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import com.seibel.lod.forge.fabric.api.client.networking.v1.C2SPlayChannelEvents; -import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientPlayConnectionEvents; -import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientPlayNetworking; -import com.seibel.lod.forge.fabric.impl.networking.AbstractChanneledNetworkAddon; -import com.seibel.lod.forge.fabric.impl.networking.ChannelInfoHolder; -import com.seibel.lod.forge.fabric.impl.networking.NetworkingImpl; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; -import net.minecraft.resources.ResourceLocation; - -public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon { - private final ClientPacketListener handler; - private final Minecraft client; - private boolean sentInitialRegisterPacket; - - public ClientPlayNetworkAddon(ClientPacketListener handler, Minecraft client) { - super(ClientNetworkingImpl.PLAY, handler.getConnection(), "ClientPlayNetworkAddon for " + handler.getLocalGameProfile().getName()); - this.handler = handler; - this.client = client; - - // Must register pending channels via lateinit - this.registerPendingChannels((ChannelInfoHolder) this.connection); - - // Register global receivers and attach to session - this.receiver.startSession(this); - } - - @Override - public void lateInit() { - for (Map.Entry entry : this.receiver.getHandlers().entrySet()) { - this.registerChannel(entry.getKey(), entry.getValue()); - } - - ClientPlayConnectionEvents.INIT.invoker().onPlayInit(this.handler, this.client); - } - - public void onServerReady() { - ClientPlayConnectionEvents.JOIN.invoker().onPlayReady(this.handler, this, this.client); - - // The client cannot send any packets, including `minecraft:register` until after GameJoinS2CPacket is received. - this.sendInitialChannelRegistrationPacket(); - this.sentInitialRegisterPacket = true; - } - - /** - * Handles an incoming packet. - * - * @param packet the packet to handle - * @return true if the packet has been handled - */ - public boolean handle(ClientboundCustomPayloadPacket packet) { - // Do not handle the packet on game thread - if (this.client.isSameThread()) { - return false; - } - - FriendlyByteBuf buf = packet.getData(); - - try { - return this.handle(packet.getIdentifier(), buf); - } finally { - buf.release(); - } - } - - @Override - protected void receive(ClientPlayNetworking.PlayChannelHandler handler, FriendlyByteBuf buf) { - handler.receive(this.client, this.handler, buf, this); - } - - // impl details - - @Override - protected void schedule(Runnable task) { - Minecraft.getInstance().execute(task); - } - - @Override - public Packet createPacket(ResourceLocation channelName, FriendlyByteBuf buf) { - return ClientPlayNetworking.createC2SPacket(channelName, buf); - } - - @Override - protected void invokeRegisterEvent(List ids) { - C2SPlayChannelEvents.REGISTER.invoker().onChannelRegister(this.handler, this, this.client, ids); - } - - @Override - protected void invokeUnregisterEvent(List ids) { - C2SPlayChannelEvents.UNREGISTER.invoker().onChannelUnregister(this.handler, this, this.client, ids); - } - - @Override - protected void handleRegistration(ResourceLocation channelName) { - // If we can already send packets, immediately send the register packet for this channel - if (this.sentInitialRegisterPacket) { - final FriendlyByteBuf buf = this.createRegistrationPacket(Collections.singleton(channelName)); - - if (buf != null) { - this.sendPacket(NetworkingImpl.REGISTER_CHANNEL, buf); - } - } - } - - @Override - protected void handleUnregistration(ResourceLocation channelName) { - // If we can already send packets, immediately send the unregister packet for this channel - if (this.sentInitialRegisterPacket) { - final FriendlyByteBuf buf = this.createRegistrationPacket(Collections.singleton(channelName)); - - if (buf != null) { - this.sendPacket(NetworkingImpl.UNREGISTER_CHANNEL, buf); - } - } - } - - @Override - protected void invokeDisconnectEvent() { - ClientPlayConnectionEvents.DISCONNECT.invoker().onPlayDisconnect(this.handler, this.client); - this.receiver.endSession(this); - } - - @Override - protected boolean isReservedChannel(ResourceLocation channelName) { - return NetworkingImpl.isReservedPlayChannel(channelName); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/QueryIdFactory.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/QueryIdFactory.java deleted file mode 100644 index 99d09272e..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/QueryIdFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking.server; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Tracks the current query id used for login query responses. - */ -interface QueryIdFactory { - static QueryIdFactory create() { - return new QueryIdFactory() { - private final AtomicInteger currentId = new AtomicInteger(); - - @Override - public int nextId() { - return this.currentId.getAndIncrement(); - } - }; - } - - // called async prob. - int nextId(); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/ServerLoginNetworkAddon.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/ServerLoginNetworkAddon.java deleted file mode 100644 index 1cf0aa3ae..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/ServerLoginNetworkAddon.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking.server; - -import java.util.Collection; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicReference; - -import io.netty.util.concurrent.GenericFutureListener; -import org.jetbrains.annotations.Nullable; -import net.minecraft.network.Connection; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.login.ClientboundCustomQueryPacket; -import net.minecraft.network.protocol.login.ClientboundLoginCompressionPacket; -import net.minecraft.network.protocol.login.ServerboundCustomQueryPacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerLoginPacketListenerImpl; -import com.seibel.lod.forge.fabric.api.networking.v1.PacketByteBufs; -import com.seibel.lod.forge.fabric.api.networking.v1.PacketSender; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerLoginConnectionEvents; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerLoginNetworking; -import com.seibel.lod.forge.fabric.impl.networking.AbstractNetworkAddon; -import com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor.LoginQueryResponseC2SPacketAccessor; -import com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor.ServerLoginNetworkHandlerAccessor; - -public final class ServerLoginNetworkAddon extends AbstractNetworkAddon implements PacketSender { - private final Connection connection; - private final ServerLoginPacketListenerImpl handler; - private final MinecraftServer server; - private final QueryIdFactory queryIdFactory; - private final Collection> waits = new ConcurrentLinkedQueue<>(); - private final Map channels = new ConcurrentHashMap<>(); - private boolean firstQueryTick = true; - - public ServerLoginNetworkAddon(ServerLoginPacketListenerImpl handler) { - super(ServerNetworkingImpl.LOGIN, "ServerLoginNetworkAddon for " + handler.getUserName()); - this.connection = handler.connection; - this.handler = handler; - this.server = ((ServerLoginNetworkHandlerAccessor) handler).getServer(); - this.queryIdFactory = QueryIdFactory.create(); - - ServerLoginConnectionEvents.INIT.invoker().onLoginInit(handler, this.server); - this.receiver.startSession(this); - } - - // return true if no longer ticks query - public boolean queryTick() { - if (this.firstQueryTick) { - // Send the compression packet now so clients receive compressed login queries - this.sendCompressionPacket(); - - // Register global receivers. - for (Map.Entry entry : ServerNetworkingImpl.LOGIN.getHandlers().entrySet()) { - ServerLoginNetworking.registerReceiver(this.handler, entry.getKey(), entry.getValue()); - } - - ServerLoginConnectionEvents.QUERY_START.invoker().onLoginStart(this.handler, this.server, this, this.waits::add); - this.firstQueryTick = false; - } - - AtomicReference error = new AtomicReference<>(); - this.waits.removeIf(future -> { - if (!future.isDone()) { - return false; - } - - try { - future.get(); - } catch (ExecutionException ex) { - Throwable caught = ex.getCause(); - error.getAndUpdate(oldEx -> { - if (oldEx == null) { - return caught; - } - - oldEx.addSuppressed(caught); - return oldEx; - }); - } catch (InterruptedException | CancellationException ignored) { - // ignore - } - - return true; - }); - - return this.channels.isEmpty() && this.waits.isEmpty(); - } - - private void sendCompressionPacket() { - // Compression is not needed for local transport - if (this.server.getCompressionThreshold() >= 0 && !this.connection.isMemoryConnection()) { - this.connection.send(new ClientboundLoginCompressionPacket(this.server.getCompressionThreshold()), (channelFuture) -> - this.connection.setupCompression(this.server.getCompressionThreshold(), true) - ); - } - } - - /** - * Handles an incoming query response during login. - * - * @param packet the packet to handle - * @return true if the packet was handled - */ - public boolean handle(ServerboundCustomQueryPacket packet) { - LoginQueryResponseC2SPacketAccessor access = (LoginQueryResponseC2SPacketAccessor) packet; - return handle(access.getTransactionId(), access.getData()); - } - - private boolean handle(int queryId, @Nullable FriendlyByteBuf originalBuf) { - this.logger.debug("Handling inbound login query with id {}", queryId); - ResourceLocation channel = this.channels.remove(queryId); - - if (channel == null) { - this.logger.warn("Query ID {} was received but no query has been associated in {}!", queryId, this.connection); - return false; - } - - boolean understood = originalBuf != null; - @Nullable ServerLoginNetworking.LoginQueryResponseHandler handler = ServerNetworkingImpl.LOGIN.getHandler(channel); - - if (handler == null) { - return false; - } - - FriendlyByteBuf buf = understood ? PacketByteBufs.slice(originalBuf) : PacketByteBufs.empty(); - - try { - handler.receive(this.server, this.handler, understood, buf, this.waits::add, this); - } catch (Throwable ex) { - this.logger.error("Encountered exception while handling in channel \"{}\"", channel, ex); - throw ex; - } - - return true; - } - - @Override - public Packet createPacket(ResourceLocation channelName, FriendlyByteBuf buf) { - int queryId = this.queryIdFactory.nextId(); - - ClientboundCustomQueryPacket ret = new ClientboundCustomQueryPacket(queryId, channelName, buf); - return ret; - } - - @Override - public void sendPacket(Packet packet) { - Objects.requireNonNull(packet, "Packet cannot be null"); - - this.connection.send(packet); - } - - @Override - public void sendPacket(Packet packet, GenericFutureListener> callback) { - Objects.requireNonNull(packet, "Packet cannot be null"); - - this.connection.send(packet, callback); - } - - public void registerOutgoingPacket(ClientboundCustomQueryPacket packet) { - this.channels.put(packet.getTransactionId(), packet.getIdentifier()); - } - - @Override - protected void handleRegistration(ResourceLocation channelName) { - } - - @Override - protected void handleUnregistration(ResourceLocation channelName) { - } - - @Override - protected void invokeDisconnectEvent() { - ServerLoginConnectionEvents.DISCONNECT.invoker().onLoginDisconnect(this.handler, this.server); - this.receiver.endSession(this); - } - - public void handlePlayTransition() { - this.receiver.endSession(this); - } - - @Override - protected boolean isReservedChannel(ResourceLocation channelName) { - return false; - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/ServerNetworkingImpl.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/ServerNetworkingImpl.java deleted file mode 100644 index 11dfaf284..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/ServerNetworkingImpl.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking.server; - -import com.seibel.lod.forge.fabric.api.networking.v1.ServerLoginNetworking; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerPlayNetworking; -import com.seibel.lod.forge.fabric.impl.networking.GlobalReceiverRegistry; -import com.seibel.lod.forge.fabric.impl.networking.NetworkHandlerExtensions; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.server.network.ServerLoginPacketListenerImpl; - -public final class ServerNetworkingImpl { - public static final GlobalReceiverRegistry LOGIN = new GlobalReceiverRegistry<>(); - public static final GlobalReceiverRegistry PLAY = new GlobalReceiverRegistry<>(); - - public static ServerPlayNetworkAddon getAddon(ServerGamePacketListenerImpl handler) { - return (ServerPlayNetworkAddon) ((NetworkHandlerExtensions) handler).getAddon(); - } - - public static ServerLoginNetworkAddon getAddon(ServerLoginPacketListenerImpl handler) { - return (ServerLoginNetworkAddon) ((NetworkHandlerExtensions) handler).getAddon(); - } - - public static Packet createPlayC2SPacket(ResourceLocation channel, FriendlyByteBuf buf) { - return new ClientboundCustomPayloadPacket(channel, buf); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/ServerPlayNetworkAddon.java b/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/ServerPlayNetworkAddon.java deleted file mode 100644 index df419e63d..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/fabric/impl/networking/server/ServerPlayNetworkAddon.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.fabric.impl.networking.server; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import com.seibel.lod.forge.fabric.api.networking.v1.S2CPlayChannelEvents; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerPlayConnectionEvents; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerPlayNetworking; -import com.seibel.lod.forge.fabric.impl.networking.AbstractChanneledNetworkAddon; -import com.seibel.lod.forge.fabric.impl.networking.ChannelInfoHolder; -import com.seibel.lod.forge.fabric.impl.networking.NetworkingImpl; -import com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor.CustomPayloadC2SPacketAccessor; - -public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon { - private final ServerGamePacketListenerImpl handler; - private final MinecraftServer server; - private boolean sentInitialRegisterPacket; - - public ServerPlayNetworkAddon(ServerGamePacketListenerImpl handler, MinecraftServer server) { - super(ServerNetworkingImpl.PLAY, handler.getConnection(), "ServerPlayNetworkAddon for " + handler.player.getScoreboardName()); - this.handler = handler; - this.server = server; - - // Must register pending channels via lateinit - this.registerPendingChannels((ChannelInfoHolder) this.connection); - - // Register global receivers and attach to session - this.receiver.startSession(this); - } - - @Override - public void lateInit() { - for (Map.Entry entry : this.receiver.getHandlers().entrySet()) { - this.registerChannel(entry.getKey(), entry.getValue()); - } - - ServerPlayConnectionEvents.INIT.invoker().onPlayInit(this.handler, this.server); - } - - public void onClientReady() { - ServerPlayConnectionEvents.JOIN.invoker().onPlayReady(this.handler, this, this.server); - - this.sendInitialChannelRegistrationPacket(); - this.sentInitialRegisterPacket = true; - } - - /** - * Handles an incoming packet. - * - * @param packet the packet to handle - * @return true if the packet has been handled - */ - public boolean handle(ServerboundCustomPayloadPacket packet) { - // Do not handle the packet on game thread - if (this.server.isSameThread()) { - return false; - } - - CustomPayloadC2SPacketAccessor access = (CustomPayloadC2SPacketAccessor) packet; - return this.handle(access.getIdentifier(), access.getData()); - } - - @Override - protected void receive(ServerPlayNetworking.PlayChannelHandler handler, FriendlyByteBuf buf) { - handler.receive(this.server, this.handler.player, this.handler, buf, this); - } - - // impl details - - @Override - protected void schedule(Runnable task) { - this.handler.player.server.execute(task); - } - - @Override - public Packet createPacket(ResourceLocation channelName, FriendlyByteBuf buf) { - return ServerPlayNetworking.createS2CPacket(channelName, buf); - } - - @Override - protected void invokeRegisterEvent(List ids) { - S2CPlayChannelEvents.REGISTER.invoker().onChannelRegister(this.handler, this, this.server, ids); - } - - @Override - protected void invokeUnregisterEvent(List ids) { - S2CPlayChannelEvents.UNREGISTER.invoker().onChannelUnregister(this.handler, this, this.server, ids); - } - - @Override - protected void handleRegistration(ResourceLocation channelName) { - // If we can already send packets, immediately send the register packet for this channel - if (this.sentInitialRegisterPacket) { - final FriendlyByteBuf buf = this.createRegistrationPacket(Collections.singleton(channelName)); - - if (buf != null) { - this.sendPacket(NetworkingImpl.REGISTER_CHANNEL, buf); - } - } - } - - @Override - protected void handleUnregistration(ResourceLocation channelName) { - // If we can already send packets, immediately send the unregister packet for this channel - if (this.sentInitialRegisterPacket) { - final FriendlyByteBuf buf = this.createRegistrationPacket(Collections.singleton(channelName)); - - if (buf != null) { - this.sendPacket(NetworkingImpl.UNREGISTER_CHANNEL, buf); - } - } - } - - @Override - protected void invokeDisconnectEvent() { - ServerPlayConnectionEvents.DISCONNECT.invoker().onPlayDisconnect(this.handler, this.server); - this.receiver.endSession(this); - } - - @Override - protected boolean isReservedChannel(ResourceLocation channelName) { - return NetworkingImpl.isReservedPlayChannel(channelName); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking.zip b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking.zip new file mode 100644 index 000000000..0c4c6af3b Binary files /dev/null and b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking.zip differ diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/ClientConnectionMixin.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/ClientConnectionMixin.java deleted file mode 100644 index 5f2d74b1d..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/ClientConnectionMixin.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking; - -import java.util.Collection; -import java.util.Collections; -import java.util.concurrent.ConcurrentHashMap; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.seibel.lod.forge.fabric.impl.networking.ChannelInfoHolder; -import com.seibel.lod.forge.fabric.impl.networking.DisconnectPacketSource; -import com.seibel.lod.forge.fabric.impl.networking.NetworkHandlerExtensions; -import com.seibel.lod.forge.fabric.impl.networking.PacketCallbackListener; -import net.minecraft.network.Connection; -import net.minecraft.network.PacketListener; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.PacketFlow; -import net.minecraft.resources.ResourceLocation; - -@Mixin(Connection.class) -abstract class ClientConnectionMixin implements ChannelInfoHolder { - @Shadow - private PacketListener packetListener; - - @Shadow - public abstract void send(Packet packet, GenericFutureListener> callback); - - @Shadow - public abstract void disconnect(Component disconnectReason); - - @Unique - private Collection playChannels; - - @Inject(method = "", at = @At("RETURN")) - private void initAddedFields(PacketFlow side, CallbackInfo ci) { - this.playChannels = Collections.newSetFromMap(new ConcurrentHashMap<>()); - } - - // Must be fully qualified due to mixin not working in production without it - @SuppressWarnings("UnnecessaryQualifiedMemberReference") - @Redirect(method = "Lnet/minecraft/network/Connection;exceptionCaught(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Throwable;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;Lio/netty/util/concurrent/GenericFutureListener;)V")) - private void resendOnExceptionCaught(Connection self, Packet packet, GenericFutureListener> listener) { - PacketListener handler = this.packetListener; - - if (handler instanceof DisconnectPacketSource) { - this.send(((DisconnectPacketSource) handler).createDisconnectPacket(new TranslatableComponent("disconnect.genericReason")), listener); - } else { - this.disconnect(new TranslatableComponent("disconnect.genericReason")); // Don't send packet if we cannot send proper packets - } - } - - @Inject(method = "sendPacket", at = @At(value = "FIELD", target = "Lnet/minecraft/network/Connection;sentPackets:I")) - private void checkPacket(Packet packet, GenericFutureListener> callback, CallbackInfo ci) { - if (this.packetListener instanceof PacketCallbackListener) { - ((PacketCallbackListener) this.packetListener).sent(packet); - } - } - - @Inject(method = "channelInactive", at = @At("HEAD")) - private void handleDisconnect(ChannelHandlerContext channelHandlerContext, CallbackInfo ci) throws Exception { - if (packetListener instanceof NetworkHandlerExtensions) { // not the case for client/server query - ((NetworkHandlerExtensions) packetListener).getAddon().handleDisconnect(); - } - } - - @Override - public Collection getPendingChannelsNames() { - return this.playChannels; - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/EntityTrackerEntryMixin.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/EntityTrackerEntryMixin.java deleted file mode 100644 index 458bd9594..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/EntityTrackerEntryMixin.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.seibel.lod.forge.fabric.api.networking.v1.EntityTrackingEvents; -import net.minecraft.server.level.ServerEntity; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.Entity; - -@Mixin(ServerEntity.class) -abstract class EntityTrackerEntryMixin { - @Shadow - @Final - private Entity entity; - - @Inject(method = "addPairing", at = @At("HEAD")) - private void onStartTracking(ServerPlayer player, CallbackInfo ci) { - EntityTrackingEvents.START_TRACKING.invoker().onStartTracking(this.entity, player); - } - - @Inject(method = "removePairing", at = @At("TAIL")) - private void onStopTracking(ServerPlayer player, CallbackInfo ci) { - EntityTrackingEvents.STOP_TRACKING.invoker().onStopTracking(this.entity, player); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/PlayerManagerMixin.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/PlayerManagerMixin.java deleted file mode 100644 index 439001bf7..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/PlayerManagerMixin.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.seibel.lod.forge.fabric.impl.networking.server.ServerNetworkingImpl; -import net.minecraft.network.Connection; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.players.PlayerList; - -@Mixin(PlayerList.class) -abstract class PlayerManagerMixin { - @Inject(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientboundCustomPayloadPacket;(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/network/FriendlyByteBuf;)V")) - private void handlePlayerConnection(Connection connection, ServerPlayer player, CallbackInfo ci) { - ServerNetworkingImpl.getAddon(player.connection).onClientReady(); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/ServerLoginNetworkHandlerMixin.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/ServerLoginNetworkHandlerMixin.java deleted file mode 100644 index 2af7f4c41..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/ServerLoginNetworkHandlerMixin.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.login.ClientboundCustomQueryPacket; -import net.minecraft.network.protocol.login.ClientboundLoginDisconnectPacket; -import net.minecraft.network.protocol.login.ServerboundCustomQueryPacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.ServerLoginPacketListenerImpl; -import com.seibel.lod.forge.fabric.impl.networking.DisconnectPacketSource; -import com.seibel.lod.forge.fabric.impl.networking.NetworkHandlerExtensions; -import com.seibel.lod.forge.fabric.impl.networking.PacketCallbackListener; -import com.seibel.lod.forge.fabric.impl.networking.server.ServerLoginNetworkAddon; - -@Mixin(ServerLoginPacketListenerImpl.class) -abstract class ServerLoginNetworkHandlerMixin implements NetworkHandlerExtensions, DisconnectPacketSource, PacketCallbackListener { - @Shadow - @Final - private MinecraftServer server; - - @Shadow - public abstract void handleAcceptedLogin(); - - @Unique - private ServerLoginNetworkAddon addon; - - @Inject(method = "", at = @At("RETURN")) - private void initAddon(CallbackInfo ci) { - this.addon = new ServerLoginNetworkAddon((ServerLoginPacketListenerImpl) (Object) this); - } - - @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerLoginPacketListenerImpl;handleAcceptedLogin()V")) - private void handlePlayerJoin(ServerLoginPacketListenerImpl handler) { - // Do not accept the player, thereby moving into play stage until all login futures being waited on are completed - if (this.addon.queryTick()) { - this.handleAcceptedLogin(); - } - } - - @Inject(method = "handleCustomQueryPacket", at = @At("HEAD"), cancellable = true) - private void handleCustomPayloadReceivedAsync(ServerboundCustomQueryPacket packet, CallbackInfo ci) { - // Handle queries - if (this.addon.handle(packet)) { - ci.cancel(); - } - } - - @Redirect(method = "handleAcceptedLogin", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getCompressionThreshold()I", ordinal = 0)) - private int removeLateCompressionPacketSending(MinecraftServer server) { - return -1; - } - - @Inject(method = "onDisconnect", at = @At("HEAD")) - private void handleDisconnection(Component reason, CallbackInfo ci) { - this.addon.handleDisconnect(); - } - - @Inject(method = "placeNewPlayer", at = @At("HEAD")) - private void handlePlayTransitionNormal(ServerPlayer player, CallbackInfo ci) { - this.addon.handlePlayTransition(); - } - - @Override - public void sent(Packet packet) { - if (packet instanceof ClientboundCustomQueryPacket) { - this.addon.registerOutgoingPacket((ClientboundCustomQueryPacket) packet); - } - } - - @Override - public ServerLoginNetworkAddon getAddon() { - return this.addon; - } - - @Override - public Packet createDisconnectPacket(Component message) { - return new ClientboundLoginDisconnectPacket(message); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java deleted file mode 100644 index bfaa0507a..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.network.Connection; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ClientboundDisconnectPacket; -import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import com.seibel.lod.forge.fabric.impl.networking.DisconnectPacketSource; -import com.seibel.lod.forge.fabric.impl.networking.NetworkHandlerExtensions; -import com.seibel.lod.forge.fabric.impl.networking.server.ServerPlayNetworkAddon; - -// We want to apply a bit earlier than other mods which may not use us in order to prevent refCount issues -@Mixin(value = ServerGamePacketListenerImpl.class, priority = 999) -abstract class ServerPlayNetworkHandlerMixin implements NetworkHandlerExtensions, DisconnectPacketSource { - @Shadow - @Final - private MinecraftServer server; - @Shadow - @Final - public Connection connection; - - @Unique - private ServerPlayNetworkAddon addon; - - @Inject(method = "", at = @At("RETURN")) - private void initAddon(CallbackInfo ci) { - this.addon = new ServerPlayNetworkAddon((ServerGamePacketListenerImpl) (Object) this, this.server); - // A bit of a hack but it allows the field above to be set in case someone registers handlers during INIT event which refers to said field - this.addon.lateInit(); - } - - @Inject(method = "handleCustomPayload", at = @At("HEAD"), cancellable = true) - private void handleCustomPayloadReceivedAsync(ServerboundCustomPayloadPacket packet, CallbackInfo ci) { - if (this.addon.handle(packet)) { - ci.cancel(); - } - } - - @Inject(method = "onDisconnect", at = @At("HEAD")) - private void handleDisconnection(Component reason, CallbackInfo ci) { - this.addon.handleDisconnect(); - } - - @Override - public ServerPlayNetworkAddon getAddon() { - return this.addon; - } - - @Override - public Packet createDisconnectPacket(Component message) { - return new ClientboundDisconnectPacket(message); - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/ConnectScreenAccessor.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/ConnectScreenAccessor.java deleted file mode 100644 index 3df191246..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/ConnectScreenAccessor.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; -import net.minecraft.client.gui.screens.ConnectScreen; -import net.minecraft.network.Connection; - -@Mixin(ConnectScreen.class) -public interface ConnectScreenAccessor { - @Accessor - Connection getConnection(); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/CustomPayloadC2SPacketAccessor.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/CustomPayloadC2SPacketAccessor.java deleted file mode 100644 index e5547daba..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/CustomPayloadC2SPacketAccessor.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor; - -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket; -import net.minecraft.resources.ResourceLocation; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(ServerboundCustomPayloadPacket.class) -public interface CustomPayloadC2SPacketAccessor { - @Accessor - ResourceLocation getIdentifier(); - - @Accessor - FriendlyByteBuf getData(); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/EntityTrackerAccessor.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/EntityTrackerAccessor.java deleted file mode 100644 index 89be357bd..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/EntityTrackerAccessor.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor; - -import java.util.Set; -import net.minecraft.server.network.ServerPlayerConnection; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(targets = "net/minecraft/server/level/ChunkMap$TrackedEntity") -public interface EntityTrackerAccessor { - @Accessor("seenBy") - Set getPlayersTracking(); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/LoginQueryResponseC2SPacketAccessor.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/LoginQueryResponseC2SPacketAccessor.java deleted file mode 100644 index 438abc5f9..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/LoginQueryResponseC2SPacketAccessor.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor; - -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.login.ServerboundCustomQueryPacket; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(ServerboundCustomQueryPacket.class) -public interface LoginQueryResponseC2SPacketAccessor { - @Accessor - int getTransactionId(); - - @Nullable - @Accessor - FriendlyByteBuf getData(); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/MinecraftClientAccessor.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/MinecraftClientAccessor.java deleted file mode 100644 index 3ee7920c2..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/MinecraftClientAccessor.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor; - -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; -import net.minecraft.client.Minecraft; -import net.minecraft.network.Connection; - -@Mixin(Minecraft.class) -public interface MinecraftClientAccessor { - @Nullable - @Accessor("pendingConnection") - Connection getConnection(); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/ServerLoginNetworkHandlerAccessor.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/ServerLoginNetworkHandlerAccessor.java deleted file mode 100644 index d6fe32d51..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/ServerLoginNetworkHandlerAccessor.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerLoginPacketListenerImpl; - -@Mixin(ServerLoginPacketListenerImpl.class) -public interface ServerLoginNetworkHandlerAccessor { - @Accessor - MinecraftServer getServer(); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/ThreadedAnvilChunkStorageAccessor.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/ThreadedAnvilChunkStorageAccessor.java deleted file mode 100644 index 347f9894e..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/accessor/ThreadedAnvilChunkStorageAccessor.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking.accessor; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import net.minecraft.server.level.ChunkMap; - -@Mixin(ChunkMap.class) -public interface ThreadedAnvilChunkStorageAccessor { - @Accessor - Int2ObjectMap getEntityMap(); -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/client/ClientLoginNetworkHandlerMixin.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/client/ClientLoginNetworkHandlerMixin.java deleted file mode 100644 index 9fd4dc959..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/client/ClientLoginNetworkHandlerMixin.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking.client; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.seibel.lod.forge.fabric.impl.networking.NetworkHandlerExtensions; -import com.seibel.lod.forge.fabric.impl.networking.client.ClientLoginNetworkAddon; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.login.ClientboundCustomQueryPacket; - -@Mixin(ClientHandshakePacketListenerImpl.class) -abstract class ClientLoginNetworkHandlerMixin implements NetworkHandlerExtensions { - @Shadow - @Final - private Minecraft minecraft; - - @Unique - private ClientLoginNetworkAddon addon; - - @Inject(method = "", at = @At("RETURN")) - private void initAddon(CallbackInfo ci) { - this.addon = new ClientLoginNetworkAddon((ClientHandshakePacketListenerImpl) (Object) this, this.minecraft); - } - - @Inject(method = "handleCustomQuery", at = @At(value = "INVOKE", target = "Ljava/util/function/Consumer;accept(Ljava/lang/Object;)V", remap = false, shift = At.Shift.AFTER), cancellable = true) - private void handleQueryRequest(ClientboundCustomQueryPacket packet, CallbackInfo ci) { - if (this.addon.handlePacket(packet)) { - ci.cancel(); - } - } - - @Inject(method = "onDisconnect", at = @At("HEAD")) - private void invokeLoginDisconnectEvent(Component reason, CallbackInfo ci) { - this.addon.handleDisconnect(); - } - - @Inject(method = "handleGameProfile", at = @At("HEAD")) - private void handlePlayTransition(CallbackInfo ci) { - addon.handlePlayTransition(); - } - - @Override - public ClientLoginNetworkAddon getAddon() { - return this.addon; - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java b/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java deleted file mode 100644 index e399e6807..000000000 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.seibel.lod.forge.mixins.fabric.mixin.networking.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.seibel.lod.forge.fabric.impl.networking.NetworkHandlerExtensions; -import com.seibel.lod.forge.fabric.impl.networking.client.ClientNetworkingImpl; -import com.seibel.lod.forge.fabric.impl.networking.client.ClientPlayNetworkAddon; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; -import net.minecraft.network.protocol.game.ClientboundLoginPacket; - -// We want to apply a bit earlier than other mods which may not use us in order to prevent refCount issues - -@Mixin(value = ClientPacketListener.class, priority = 999) -abstract class ClientPlayNetworkHandlerMixin implements NetworkHandlerExtensions { - @Shadow - private Minecraft minecraft; - - @Unique - private ClientPlayNetworkAddon addon; - - @Inject(method = "", at = @At("RETURN")) - private void initAddon(CallbackInfo ci) { - this.addon = new ClientPlayNetworkAddon((ClientPacketListener) (Object) this, this.minecraft); - // A bit of a hack but it allows the field above to be set in case someone registers handlers during INIT event which refers to said field - ClientNetworkingImpl.setClientPlayAddon(this.addon); - this.addon.lateInit(); - } - - @Inject(method = "handleLogin", at = @At("RETURN")) - private void handleServerPlayReady(ClientboundLoginPacket packet, CallbackInfo ci) { - this.addon.onServerReady(); - } - - @Inject(method = "handleCustomPayload", at = @At("HEAD"), cancellable = true) - private void handleCustomPayload(ClientboundCustomPayloadPacket packet, CallbackInfo ci) { - if (this.addon.handle(packet)) { - ci.cancel(); - } - } - - @Inject(method = "onDisconnect", at = @At("HEAD")) - private void handleDisconnection(Component reason, CallbackInfo ci) { - this.addon.handleDisconnect(); - } - - @Override - public ClientPlayNetworkAddon getAddon() { - return this.addon; - } -} diff --git a/forge/src/main/java/com/seibel/lod/forge/networking/NetworkHandler.java b/forge/src/main/java/com/seibel/lod/forge/networking/NetworkHandler.java index 2f8a1063d..6d7ce4043 100644 --- a/forge/src/main/java/com/seibel/lod/forge/networking/NetworkHandler.java +++ b/forge/src/main/java/com/seibel/lod/forge/networking/NetworkHandler.java @@ -21,8 +21,8 @@ package com.seibel.lod.forge.networking; import com.seibel.lod.common.networking.NetworkInterface; import com.seibel.lod.common.networking.Networking; -import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientPlayNetworking; -import com.seibel.lod.forge.fabric.api.networking.v1.ServerPlayNetworking; +//import com.seibel.lod.forge.fabric.api.client.networking.v1.ClientPlayNetworking; +//import com.seibel.lod.forge.fabric.api.networking.v1.ServerPlayNetworking; /** * @author Ran @@ -30,15 +30,15 @@ import com.seibel.lod.forge.fabric.api.networking.v1.ServerPlayNetworking; public class NetworkHandler implements NetworkInterface { @Override public void register_Client() { - ClientPlayNetworking.registerGlobalReceiver(Networking.resourceLocation_meow, (client, handler, buf, responseSender) -> { - com.seibel.lod.common.networking.NetworkHandler.receivePacketClient(client, handler, buf); - }); +// ClientPlayNetworking.registerGlobalReceiver(Networking.resourceLocation_meow, (client, handler, buf, responseSender) -> { +// com.seibel.lod.common.networking.NetworkHandler.receivePacketClient(client, handler, buf); +// }); } @Override public void register_Server() { - ServerPlayNetworking.registerGlobalReceiver(Networking.resourceLocation_meow, (server, player, handler, buf, responseSender) -> { - com.seibel.lod.common.networking.NetworkHandler.receivePacketServer(server, player, handler, buf); - }); +// ServerPlayNetworking.registerGlobalReceiver(Networking.resourceLocation_meow, (server, player, handler, buf, responseSender) -> { +// com.seibel.lod.common.networking.NetworkHandler.receivePacketServer(server, player, handler, buf); +// }); } }