/** Copyright (C) <2017> <coolAlias> This file is part of coolAlias' Zelda Sword Skills Minecraft Mod; as such, you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package zeldaswordskills.network; import java.util.Collection; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.Packet; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; import net.minecraftforge.fml.relauncher.Side; import zeldaswordskills.network.bidirectional.ActivateSkillPacket; import zeldaswordskills.network.bidirectional.AttackTimePacket; import zeldaswordskills.network.bidirectional.DeactivateSkillPacket; import zeldaswordskills.network.bidirectional.LearnSongPacket; import zeldaswordskills.network.bidirectional.PlayRecordPacket; import zeldaswordskills.network.bidirectional.PlaySoundPacket; import zeldaswordskills.network.client.AttackBlockedPacket; import zeldaswordskills.network.client.InLiquidPacket; import zeldaswordskills.network.client.MortalDrawPacket; import zeldaswordskills.network.client.OpenGossipStoneEditorPacket; import zeldaswordskills.network.client.OpenSongGuiPacket; import zeldaswordskills.network.client.PacketISpawnParticles; import zeldaswordskills.network.client.SetItemModePacket; import zeldaswordskills.network.client.SetNockedArrowPacket; import zeldaswordskills.network.client.SpawnNayruParticlesPacket; import zeldaswordskills.network.client.SyncConfigPacket; import zeldaswordskills.network.client.SyncCurrentMagicPacket; import zeldaswordskills.network.client.SyncEntityInfoPacket; import zeldaswordskills.network.client.SyncPlayerInfoPacket; import zeldaswordskills.network.client.SyncQuestPacket; import zeldaswordskills.network.client.SyncQuestsPacket; import zeldaswordskills.network.client.SyncSkillPacket; import zeldaswordskills.network.client.UnpressKeyPacket; import zeldaswordskills.network.client.UpdateBuffPacket; import zeldaswordskills.network.client.UpdateComboPacket; import zeldaswordskills.network.server.AddExhaustionPacket; import zeldaswordskills.network.server.BombTickPacket; import zeldaswordskills.network.server.BorrowMaskPacket; import zeldaswordskills.network.server.CycleItemModePacket; import zeldaswordskills.network.server.DashImpactPacket; import zeldaswordskills.network.server.EndComboPacket; import zeldaswordskills.network.server.FallDistancePacket; import zeldaswordskills.network.server.GetBombPacket; import zeldaswordskills.network.server.HeldBlockColorPacket; import zeldaswordskills.network.server.OpenGuiPacket; import zeldaswordskills.network.server.RefreshSpinPacket; import zeldaswordskills.network.server.RequestCurrentMagicPacket; import zeldaswordskills.network.server.SetGossipStoneMessagePacket; import zeldaswordskills.network.server.TargetIdPacket; import zeldaswordskills.network.server.ZeldaSongPacket; import zeldaswordskills.ref.ModInfo; /** * * Houses the SimpleNetworkWrapper instance and provides wrapper methods for sending packets. * */ public class PacketDispatcher { private static byte packetId = 0; private static final SimpleNetworkWrapper dispatcher = NetworkRegistry.INSTANCE.newSimpleChannel(ModInfo.CHANNEL); /** * Registers all packets and handlers - call this during {@link FMLPreInitializationEvent} */ public static final void preInit() { // Bidirectional packets registerMessage(ActivateSkillPacket.class); registerMessage(AttackTimePacket.class); registerMessage(DeactivateSkillPacket.class); registerMessage(LearnSongPacket.class); registerMessage(PlayRecordPacket.class); registerMessage(PlaySoundPacket.class); // Packets handled on CLIENT registerMessage(AttackBlockedPacket.class); registerMessage(InLiquidPacket.class); registerMessage(MortalDrawPacket.class); registerMessage(OpenGossipStoneEditorPacket.class); registerMessage(OpenSongGuiPacket.class); registerMessage(PacketISpawnParticles.class); registerMessage(SetItemModePacket.class); registerMessage(SetNockedArrowPacket.class); registerMessage(SpawnNayruParticlesPacket.class); registerMessage(SyncConfigPacket.class); registerMessage(SyncCurrentMagicPacket.class); registerMessage(SyncEntityInfoPacket.class); registerMessage(SyncPlayerInfoPacket.class); registerMessage(SyncQuestPacket.class); registerMessage(SyncQuestsPacket.class); registerMessage(SyncSkillPacket.class); registerMessage(UnpressKeyPacket.class); registerMessage(UpdateBuffPacket.class); registerMessage(UpdateComboPacket.class); // Packets handled on SERVER registerMessage(AddExhaustionPacket.class); registerMessage(BombTickPacket.class); registerMessage(BorrowMaskPacket.class); registerMessage(CycleItemModePacket.class); registerMessage(DashImpactPacket.class); registerMessage(EndComboPacket.class); registerMessage(FallDistancePacket.class); registerMessage(GetBombPacket.class); registerMessage(HeldBlockColorPacket.class); registerMessage(OpenGuiPacket.class); registerMessage(RefreshSpinPacket.class); registerMessage(RequestCurrentMagicPacket.class); registerMessage(SetGossipStoneMessagePacket.class); registerMessage(TargetIdPacket.class); registerMessage(ZeldaSongPacket.class); } /** * Registers an {@link AbstractMessage} to the appropriate side(s) */ private static final <T extends AbstractMessage<T> & IMessageHandler<T, IMessage>> void registerMessage(Class<T> clazz) { if (AbstractMessage.AbstractClientMessage.class.isAssignableFrom(clazz)) { PacketDispatcher.dispatcher.registerMessage(clazz, clazz, packetId++, Side.CLIENT); } else if (AbstractMessage.AbstractServerMessage.class.isAssignableFrom(clazz)) { PacketDispatcher.dispatcher.registerMessage(clazz, clazz, packetId++, Side.SERVER); } else { PacketDispatcher.dispatcher.registerMessage(clazz, clazz, packetId, Side.CLIENT); PacketDispatcher.dispatcher.registerMessage(clazz, clazz, packetId++, Side.SERVER); } } /** * Send this message to the specified player's client-side counterpart. * See {@link SimpleNetworkWrapper#sendTo(IMessage, EntityPlayerMP)} */ public static final void sendTo(IMessage message, EntityPlayerMP player) { PacketDispatcher.dispatcher.sendTo(message, player); } /** * Sends this message to players provided. SERVER->CLIENT only. */ public static void sendToPlayers(IMessage message, Collection<? extends EntityPlayer> players) { for (EntityPlayer player : players) { if (player instanceof EntityPlayerMP) { PacketDispatcher.dispatcher.sendTo(message, (EntityPlayerMP) player); } } } /** * Send this message to everyone. * See {@link SimpleNetworkWrapper#sendToAll(IMessage)} */ public static void sendToAll(IMessage message) { PacketDispatcher.dispatcher.sendToAll(message); } /** * Send this message to everyone within a certain range of a point. * See {@link SimpleNetworkWrapper#sendToAllAround(IMessage, NetworkRegistry.TargetPoint)} */ public static final void sendToAllAround(IMessage message, NetworkRegistry.TargetPoint point) { PacketDispatcher.dispatcher.sendToAllAround(message, point); } /** * Sends a message to everyone within a certain range of the coordinates in the same dimension. * Shortcut to {@link SimpleNetworkWrapper#sendToAllAround(IMessage, NetworkRegistry.TargetPoint)} */ public static final void sendToAllAround(IMessage message, int dimension, double x, double y, double z, double range) { PacketDispatcher.sendToAllAround(message, new NetworkRegistry.TargetPoint(dimension, x, y, z, range)); } /** * Sends a message to everyone within a certain range of the entity provided. * Shortcut to {@link SimpleNetworkWrapper#sendToAllAround(IMessage, NetworkRegistry.TargetPoint)} */ public static final void sendToAllAround(IMessage message, Entity entity, double range) { PacketDispatcher.sendToAllAround(message, entity.worldObj.provider.getDimensionId(), entity.posX, entity.posY, entity.posZ, range); } /** * Send this message to everyone within the supplied dimension. * See {@link SimpleNetworkWrapper#sendToDimension(IMessage, int)} */ public static final void sendToDimension(IMessage message, int dimensionId) { PacketDispatcher.dispatcher.sendToDimension(message, dimensionId); } /** * Send this message to the server. * See {@link SimpleNetworkWrapper#sendToServer(IMessage)} */ public static final void sendToServer(IMessage message) { PacketDispatcher.dispatcher.sendToServer(message); } /** * Sends a vanilla Packet to a player. SERVER->CLIENT only. */ public static void sendTo(Packet<?> packet, EntityPlayer player) { if (player instanceof EntityPlayerMP) { ((EntityPlayerMP) player).playerNetServerHandler.sendPacket(packet); } } /** * Sends a vanilla Packet to players provided. SERVER->CLIENT only. */ public static void sendToPlayers(Packet<?> packet, Collection<? extends EntityPlayer> players) { for (EntityPlayer player : players) { if (player instanceof EntityPlayerMP) { ((EntityPlayerMP) player).playerNetServerHandler.sendPacket(packet); } } } /** * Sends a vanilla Packet to all players in the list except for the one player. SERVER->CLIENT only. */ public static void sendToPlayersExcept(Packet<?> packet, EntityPlayer player, Collection<? extends EntityPlayer> players) { for (EntityPlayer p : players) { if (p != player && p instanceof EntityPlayerMP) { ((EntityPlayerMP) p).playerNetServerHandler.sendPacket(packet); } } } /** * Sends a vanilla Packet to all players in the same dimension. SERVER->CLIENT only. */ public static void sendToAll(Packet<?> packet, World world) { if (world instanceof WorldServer) { for (Object o : ((WorldServer) world).playerEntities) { if (o instanceof EntityPlayerMP) { ((EntityPlayerMP) o).playerNetServerHandler.sendPacket(packet); } } } } /** * Sends a vanilla Packet to all players within the given range of an entity. SERVER->CLIENT only. */ public static void sendToAllAround(Packet<?> packet, Entity entity, int range) { int rangeSq = (range * range); if (entity.worldObj instanceof WorldServer) { for (Object o : ((WorldServer) entity.worldObj).playerEntities) { if (o instanceof EntityPlayerMP) { EntityPlayerMP player = (EntityPlayerMP) o; if (player.getDistanceSqToEntity(entity) <= rangeSq) { ((EntityPlayerMP) o).playerNetServerHandler.sendPacket(packet); } } } } } }