mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 16:27:47 +00:00
Add a FML outbound target for all players tracking a point or entity in the world. Closes #3677 (#4631)
This commit is contained in:
1 parent
f5c0b894bf
commit
1d7c04daeb
5 files changed
+273
No files matched your search
@@ -25,6 +25,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import java.util.EnumMap;
|
||||
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
@@ -177,6 +178,33 @@ public class FMLEventChannel {
|
||||
channels.get(Side.SERVER).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send to all tracking the point
|
||||
* The {@code range} field of the {@link NetworkRegistry.TargetPoint} is ignored.
|
||||
* @param pkt
|
||||
* @param point
|
||||
*/
|
||||
public void sendToAllTracking(FMLProxyPacket pkt, NetworkRegistry.TargetPoint point)
|
||||
{
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TRACKING_POINT);
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point);
|
||||
channels.get(Side.SERVER).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send to all tracking the entity
|
||||
* This is not equivalent to {@link #sendToAllTracking(FMLProxyPacket, NetworkRegistry.TargetPoint)}
|
||||
* because entities have different tracking distances based on their type.
|
||||
* @param pkt
|
||||
* @param entity
|
||||
*/
|
||||
public void sendToAllTracking(FMLProxyPacket pkt, Entity entity)
|
||||
{
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TRACKING_ENTITY);
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(entity);
|
||||
channels.get(Side.SERVER).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send to all in a dimension
|
||||
* @param pkt
|
||||
|
||||
@@ -26,9 +26,17 @@ import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import io.netty.util.AttributeKey;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.server.management.PlayerChunkMap;
|
||||
import net.minecraft.server.management.PlayerChunkMapEntry;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
@@ -231,6 +239,79 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
||||
return builder.build();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The packet is sent to all players that are watching the Chunk containing the supplied {@link TargetPoint}.
|
||||
* The {@code range} field of the {@link TargetPoint} is ignored.
|
||||
*/
|
||||
TRACKING_POINT(Sets.immutableEnumSet(Side.SERVER))
|
||||
{
|
||||
@Override
|
||||
public void validateArgs(Object args)
|
||||
{
|
||||
if (!(args instanceof TargetPoint))
|
||||
{
|
||||
throw new RuntimeException("TRACKING_POINT expects a TargetPoint argument");
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
TargetPoint tp = (TargetPoint)args;
|
||||
WorldServer world = DimensionManager.getWorld(tp.dimension);
|
||||
if (world == null)
|
||||
{
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
PlayerChunkMapEntry entry = world.getPlayerChunkMap().getEntry(MathHelper.floor(tp.x) >> 4, MathHelper.floor(tp.z) >> 4);
|
||||
if (entry == null)
|
||||
{
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
ImmutableList.Builder<NetworkDispatcher> builder = ImmutableList.builder();
|
||||
for (EntityPlayerMP player : entry.getWatchingPlayers())
|
||||
{
|
||||
NetworkDispatcher dispatcher = player.connection.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||
if (dispatcher != null) builder.add(dispatcher);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The packet is sent to all players tracking the supplied {@link Entity}. This is different from {@link #TRACKING_POINT} because Entities
|
||||
* can have different tracking distances depending on their type.
|
||||
*/
|
||||
TRACKING_ENTITY(Sets.immutableEnumSet(Side.SERVER))
|
||||
{
|
||||
@Override
|
||||
public void validateArgs(Object args)
|
||||
{
|
||||
if (!(args instanceof Entity))
|
||||
{
|
||||
throw new RuntimeException("TRACKING_ENTITY expects an Entity argument");
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
Entity e = (Entity)args;
|
||||
Set<? extends EntityPlayer> players = FMLCommonHandler.instance().getMinecraftServerInstance()
|
||||
.getWorld(e.dimension).getEntityTracker().getTrackingPlayers(e);
|
||||
|
||||
ImmutableList.Builder<NetworkDispatcher> builder = ImmutableList.builder();
|
||||
for (EntityPlayer player : players)
|
||||
{
|
||||
NetworkDispatcher dispatcher = ((EntityPlayerMP) player).connection.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||
if (dispatcher != null) builder.add(dispatcher);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The packet is sent to the server this client is currently conversing with.
|
||||
* @author cpw
|
||||
|
||||
+32
@@ -24,6 +24,7 @@ import io.netty.channel.ChannelFutureListener;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.EnumMap;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.IThreadListener;
|
||||
|
||||
import io.netty.channel.ChannelHandler;
|
||||
@@ -263,6 +264,37 @@ public class SimpleNetworkWrapper {
|
||||
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this message to everyone tracking a point.
|
||||
* The {@link IMessageHandler} for this message type should be on the CLIENT side.
|
||||
* The {@code range} field of the {@link TargetPoint} is ignored.
|
||||
*
|
||||
* @param message The message to send
|
||||
* @param point The tracked {@link TargetPoint} around which to send
|
||||
*/
|
||||
public void sendToAllTracking(IMessage message, NetworkRegistry.TargetPoint point)
|
||||
{
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TRACKING_POINT);
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point);
|
||||
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this message to everyone tracking an entity.
|
||||
* The {@link IMessageHandler} for this message type should be on the CLIENT side.
|
||||
* This is not equivalent to {@link #sendToAllTracking(IMessage, TargetPoint)}
|
||||
* because entities have different tracking distances based on their type.
|
||||
*
|
||||
* @param message The message to send
|
||||
* @param entity The tracked entity around which to send
|
||||
*/
|
||||
public void sendToAllTracking(IMessage message, Entity entity)
|
||||
{
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TRACKING_ENTITY);
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(entity);
|
||||
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send this message to everyone within the supplied dimension.
|
||||
* The {@link IMessageHandler} for this message type should be on the CLIENT side.
|
||||
|
||||
Reference in new issue
Block a user