use of net.minecraft.network.play.client.CPacketUseEntity in project SpongeCommon by SpongePowered.
the class MixinNetHandlerPlayServer method processUseEntity.
/**
* @author blood - April 5th, 2016
*
* @reason Due to all the changes we now do for this packet, it is much easier
* to read it all with an overwrite. Information detailing on why each change
* was made can be found in comments below.
*
* @param packetIn The entity use packet
*/
@Overwrite
public void processUseEntity(CPacketUseEntity packetIn) {
// All packets received by server are handled first on the Netty Thread
if (!SpongeImpl.getServer().isCallingFromMinecraftThread()) {
if (packetIn.getAction() == CPacketUseEntity.Action.INTERACT) {
// when INTERACT_AT does not return a successful result.
return;
} else {
// queue packet for main thread
PacketThreadUtil.checkThreadAndEnqueue(packetIn, (NetHandlerPlayServer) (Object) this, this.player.getServerWorld());
return;
}
}
// Sponge end
WorldServer worldserver = this.serverController.getWorld(this.player.dimension);
Entity entity = packetIn.getEntityFromWorld(worldserver);
this.player.markPlayerActive();
if (entity != null) {
boolean flag = this.player.canEntityBeSeen(entity);
// 6 blocks
double d0 = 36.0D;
if (!flag) {
// 1.5 blocks
d0 = 9.0D;
}
if (this.player.getDistanceSq(entity) < d0) {
if (packetIn.getAction() == CPacketUseEntity.Action.INTERACT_AT) {
// Sponge start - Fire interact events
EnumHand hand = packetIn.getHand();
ItemStack itemstack = hand != null ? this.player.getHeldItem(hand) : ItemStack.EMPTY;
Sponge.getCauseStackManager().addContext(EventContextKeys.USED_ITEM, ItemStackUtil.snapshotOf(itemstack));
SpongeCommonEventFactory.lastSecondaryPacketTick = this.serverController.getTickCounter();
// Is interaction allowed with item in hand
if (SpongeCommonEventFactory.callInteractItemEventSecondary(this.player, itemstack, hand, VecHelper.toVector3d(packetIn.getHitVec()), entity).isCancelled() || SpongeCommonEventFactory.callInteractEntityEventSecondary(this.player, entity, hand, VecHelper.toVector3d(entity.getPositionVector().add(packetIn.getHitVec()))).isCancelled()) {
// Restore held item in hand
int index = ((IMixinInventoryPlayer) this.player.inventory).getHeldItemIndex(hand);
Slot slot = this.player.openContainer.getSlotFromInventory(this.player.inventory, index);
sendPacket(new SPacketSetSlot(this.player.openContainer.windowId, slot.slotNumber, itemstack));
// which means that we need to force an update
if (itemstack.getItem() == Items.LEAD) {
// Detach entity again
sendPacket(new SPacketEntityAttach(entity, null));
} else {
// Other cases may involve a specific DataParameter of the entity
// We fix the client state by marking it as dirty so it will be updated on the client the next tick
DataParameter<?> parameter = findModifiedEntityInteractDataParameter(itemstack, entity);
if (parameter != null) {
entity.getDataManager().setDirty(parameter);
}
}
return;
}
// If INTERACT_AT is not successful, run the INTERACT logic
if (entity.applyPlayerInteraction(this.player, packetIn.getHitVec(), hand) != EnumActionResult.SUCCESS) {
this.player.interactOn(entity, hand);
}
// Sponge end
} else if (packetIn.getAction() == CPacketUseEntity.Action.ATTACK) {
// Sponge start - Call interact event
// Will be null in the packet during ATTACK
EnumHand hand = EnumHand.MAIN_HAND;
ItemStack itemstack = this.player.getHeldItem(hand);
SpongeCommonEventFactory.lastPrimaryPacketTick = this.serverController.getTickCounter();
Vector3d hitVec = null;
if (packetIn.getHitVec() == null) {
final RayTraceResult result = SpongeImplHooks.rayTraceEyes(player, SpongeImplHooks.getBlockReachDistance(player));
hitVec = result == null ? null : VecHelper.toVector3d(result.hitVec);
}
if (SpongeCommonEventFactory.callInteractItemEventPrimary(this.player, itemstack, hand, hitVec, entity).isCancelled()) {
((IMixinEntityPlayerMP) this.player).restorePacketItem(hand);
return;
}
if (entity instanceof EntityItem || entity instanceof EntityXPOrb || entity instanceof EntityArrow || entity == this.player) {
this.disconnect(new TextComponentTranslation("multiplayer.disconnect.invalid_entity_attacked"));
this.serverController.logWarning("Player " + this.player.getName() + " tried to attack an invalid entity");
return;
}
// Sponge start
if (entity instanceof Player && !((World) this.player.world).getProperties().isPVPEnabled()) {
// PVP is disabled, ignore
return;
}
if (SpongeCommonEventFactory.callInteractEntityEventPrimary(this.player, entity, hand, hitVec).isCancelled()) {
((IMixinEntityPlayerMP) this.player).restorePacketItem(hand);
return;
}
// Sponge end
this.player.attackTargetEntityWithCurrentItem(entity);
}
}
}
}
use of net.minecraft.network.play.client.CPacketUseEntity in project SpongeCommon by SpongePowered.
the class AttackEntityPacketState method unwind.
@Override
public void unwind(BasicPacketContext context) {
final EntityPlayerMP player = context.getPacketPlayer();
final CPacketUseEntity useEntityPacket = context.getPacket();
final net.minecraft.entity.Entity entity = useEntityPacket.getEntityFromWorld(player.world);
if (entity == null) {
// Something happened?
return;
}
final World spongeWorld = EntityUtil.getSpongeWorld(player);
EntityUtil.toMixin(entity).setNotifier(player.getUniqueID());
context.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(items -> {
// For destruction, this should be empty, however, some
// times,
// it may not be?
final PrettyPrinter printer = new PrettyPrinter(60);
printer.add("Processing Attack Entity").centre().hr();
printer.add("There are some captured items after the entity was destructed!");
printer.addWrapped(60, "%s : %s", "Items captured", items);
printer.add("Stacktrace:");
printer.add(new Exception("Stack trace"));
printer.trace(System.err, SpongeImpl.getLogger(), Level.TRACE);
});
context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blocks -> TrackingUtil.processBlockCaptures(blocks, this, context));
context.getCapturedEntityDropSupplier().acceptIfNotEmpty(map -> {
for (Map.Entry<UUID, Collection<ItemDropData>> entry : map.asMap().entrySet()) {
final UUID key = entry.getKey();
final Optional<Entity> affectedEntity = spongeWorld.getEntity(key);
if (!affectedEntity.isPresent()) {
continue;
}
final Collection<ItemDropData> itemStacks = entry.getValue();
if (itemStacks.isEmpty()) {
return;
}
final List<ItemDropData> items = new ArrayList<>(itemStacks);
if (!items.isEmpty()) {
try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
final List<Entity> itemEntities = items.stream().map(data -> data.create(((WorldServer) player.world))).map(EntityUtil::fromNative).collect(Collectors.toList());
Sponge.getCauseStackManager().pushCause(player);
Sponge.getCauseStackManager().pushCause(affectedEntity.get());
Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
final DropItemEvent.Destruct destruct = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), itemEntities);
SpongeImpl.postEvent(destruct);
if (!destruct.isCancelled()) {
processSpawnedEntities(player, destruct);
}
}
}
}
});
context.getCapturedEntityItemDropSupplier().acceptIfNotEmpty(map -> {
try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
Sponge.getCauseStackManager().pushCause(player);
Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
for (Map.Entry<UUID, Collection<EntityItem>> entry : map.asMap().entrySet()) {
final UUID key = entry.getKey();
final Optional<Entity> attackedEntities = spongeWorld.getEntity(key);
if (!attackedEntities.isPresent()) {
continue;
}
final List<Entity> items = entry.getValue().stream().map(EntityUtil::fromNative).collect(Collectors.toList());
final DropItemEvent.Destruct destruct = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), items);
SpongeImpl.postEvent(destruct);
if (!destruct.isCancelled()) {
processSpawnedEntities(player, destruct);
}
}
}
});
}
use of net.minecraft.network.play.client.CPacketUseEntity in project SpongeCommon by SpongePowered.
the class InteractAtEntityPacketState method unwind.
@Override
public void unwind(BasicPacketContext context) {
final EntityPlayerMP player = context.getPacketPlayer();
final CPacketUseEntity useEntityPacket = context.getPacket();
final net.minecraft.entity.Entity entity = useEntityPacket.getEntityFromWorld(player.world);
if (entity == null) {
// Something happened?
return;
}
final World spongeWorld = EntityUtil.getSpongeWorld(player);
EntityUtil.toMixin(entity).setNotifier(player.getUniqueID());
try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
Sponge.getCauseStackManager().pushCause(player);
Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PLACEMENT);
context.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
SpongeImpl.postEvent(event);
if (!event.isCancelled()) {
processSpawnedEntities(player, event);
}
});
context.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(entities -> {
final List<Entity> items = entities.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), items);
SpongeImpl.postEvent(event);
if (!event.isCancelled()) {
processSpawnedEntities(player, event);
}
});
context.getCapturedEntityDropSupplier().acceptIfNotEmpty(map -> {
final PrettyPrinter printer = new PrettyPrinter(80);
printer.add("Processing Interact At Entity").centre().hr();
printer.add("The item stacks captured are: ");
for (Map.Entry<UUID, Collection<ItemDropData>> entry : map.asMap().entrySet()) {
printer.add(" - Entity with UUID: %s", entry.getKey());
for (ItemDropData stack : entry.getValue()) {
printer.add(" - %s", stack);
}
}
printer.trace(System.err);
});
context.getCapturedEntityItemDropSupplier().acceptIfNotEmpty(map -> {
for (Map.Entry<UUID, Collection<EntityItem>> entry : map.asMap().entrySet()) {
final UUID entityUuid = entry.getKey();
final net.minecraft.entity.Entity entityFromUuid = player.getServerWorld().getEntityFromUuid(entityUuid);
if (entityFromUuid != null) {
final List<Entity> entities = entry.getValue().stream().map(EntityUtil::fromNative).collect(Collectors.toList());
if (!entities.isEmpty()) {
DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
SpongeImpl.postEvent(event);
if (!event.isCancelled()) {
processSpawnedEntities(player, event);
}
}
}
}
});
context.getCapturedItemStackSupplier().acceptAndClearIfNotEmpty(drops -> {
final List<EntityItem> items = drops.stream().map(drop -> drop.create(player.getServerWorld())).collect(Collectors.toList());
final List<Entity> entities = items.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
if (!entities.isEmpty()) {
DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
SpongeImpl.postEvent(event);
if (!event.isCancelled()) {
processSpawnedEntities(player, event);
}
}
});
}
context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(snapshots -> TrackingUtil.processBlockCaptures(snapshots, this, context));
}
use of net.minecraft.network.play.client.CPacketUseEntity in project SpongeCommon by SpongePowered.
the class InteractAtEntityPacketState method isPacketIgnored.
@Override
public boolean isPacketIgnored(Packet<?> packetIn, EntityPlayerMP packetPlayer) {
final CPacketUseEntity useEntityPacket = (CPacketUseEntity) packetIn;
// There are cases where a player is interacting with an entity that doesn't exist on the server.
@Nullable net.minecraft.entity.Entity entity = useEntityPacket.getEntityFromWorld(packetPlayer.world);
return entity == null;
}
use of net.minecraft.network.play.client.CPacketUseEntity in project SpongeCommon by SpongePowered.
the class AttackEntityPacketState method isPacketIgnored.
@Override
public boolean isPacketIgnored(Packet<?> packetIn, EntityPlayerMP packetPlayer) {
final CPacketUseEntity useEntityPacket = (CPacketUseEntity) packetIn;
// There are cases where a player is interacting with an entity that
// doesn't exist on the server.
@Nullable net.minecraft.entity.Entity entity = useEntityPacket.getEntityFromWorld(packetPlayer.world);
return entity == null;
}
Aggregations