Port fixes for #45 and #48 from 1.15

This commit is contained in:
IzzelAliz 2020-09-18 09:31:14 +08:00
parent b7e47a47ed
commit 6c82601fe9
8 changed files with 60 additions and 20 deletions

View File

@ -34,4 +34,6 @@ public interface ServerPlayerEntityBridge extends PlayerEntityBridge {
void bridge$reset(); void bridge$reset();
Entity bridge$changeDimension(ServerWorld world, PlayerTeleportEvent.TeleportCause cause); Entity bridge$changeDimension(ServerWorld world, PlayerTeleportEvent.TeleportCause cause);
boolean bridge$initialized();
} }

View File

@ -476,19 +476,21 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
@Inject(method = "getHealth", cancellable = true, at = @At("HEAD")) @Inject(method = "getHealth", cancellable = true, at = @At("HEAD"))
public void arclight$scaledHealth(CallbackInfoReturnable<Float> cir) { public void arclight$scaledHealth(CallbackInfoReturnable<Float> cir) {
if (this instanceof ServerPlayerEntityBridge) { if (this instanceof ServerPlayerEntityBridge && ((ServerPlayerEntityBridge) this).bridge$initialized()) {
cir.setReturnValue((float) ((ServerPlayerEntityBridge) this).bridge$getBukkitEntity().getHealth()); cir.setReturnValue((float) ((ServerPlayerEntityBridge) this).bridge$getBukkitEntity().getHealth());
} }
} }
@Inject(method = "setHealth", cancellable = true, at = @At("HEAD")) @Inject(method = "setHealth", cancellable = true, at = @At("HEAD"))
public void arclight$setScaled(float health, CallbackInfo ci) { public void arclight$setScaled(float health, CallbackInfo ci) {
if (this instanceof ServerPlayerEntityBridge) { if (this instanceof ServerPlayerEntityBridge && ((ServerPlayerEntityBridge) this).bridge$initialized()) {
CraftPlayer player = ((ServerPlayerEntityBridge) this).bridge$getBukkitEntity(); CraftPlayer player = ((ServerPlayerEntityBridge) this).bridge$getBukkitEntity();
player.setRealHealth(MathHelper.clamp(health, 0.0F, player.getMaxHealth())); double realHealth = MathHelper.clamp(health, 0.0F, player.getMaxHealth());
player.setRealHealth(realHealth);
player.updateScaledHealth(false); player.updateScaledHealth(false);
player.setRealHealth(realHealth);
ci.cancel(); ci.cancel();
} }
} }

View File

@ -113,12 +113,16 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
arclight$fireEvent = false; arclight$fireEvent = false;
EntityTargetEvent.TargetReason reason = arclight$reason == null ? EntityTargetEvent.TargetReason.UNKNOWN : arclight$reason; EntityTargetEvent.TargetReason reason = arclight$reason == null ? EntityTargetEvent.TargetReason.UNKNOWN : arclight$reason;
arclight$reason = null; arclight$reason = null;
if (getAttackTarget() == livingEntity) {
arclight$targetSuccess = false;
return;
}
if (fireEvent) { if (fireEvent) {
if (reason == EntityTargetEvent.TargetReason.UNKNOWN && this.getAttackTarget() != null && livingEntity == null) { if (reason == EntityTargetEvent.TargetReason.UNKNOWN && this.getAttackTarget() != null && livingEntity == null) {
reason = (this.getAttackTarget().isAlive() ? EntityTargetEvent.TargetReason.FORGOT_TARGET : EntityTargetEvent.TargetReason.TARGET_DIED); reason = (this.getAttackTarget().isAlive() ? EntityTargetEvent.TargetReason.FORGOT_TARGET : EntityTargetEvent.TargetReason.TARGET_DIED);
} }
if (reason == EntityTargetEvent.TargetReason.UNKNOWN) { if (reason == EntityTargetEvent.TargetReason.UNKNOWN) {
ArclightMod.LOGGER.log(Level.WARN, "Unknown target reason, please report on the issue tracker", new Exception()); ArclightMod.LOGGER.log(Level.WARN, "Unknown target reason setting {} target to {}", this, livingEntity);
} }
CraftLivingEntity ctarget = null; CraftLivingEntity ctarget = null;
if (livingEntity != null) { if (livingEntity != null) {
@ -143,12 +147,8 @@ public abstract class MobEntityMixin extends LivingEntityMixin implements MobEnt
public boolean setGoalTarget(LivingEntity livingEntity, EntityTargetEvent.TargetReason reason, boolean fireEvent) { public boolean setGoalTarget(LivingEntity livingEntity, EntityTargetEvent.TargetReason reason, boolean fireEvent) {
bridge$pushGoalTargetReason(reason, fireEvent); bridge$pushGoalTargetReason(reason, fireEvent);
if (getAttackTarget() == livingEntity) { setAttackTarget(livingEntity);
return false; return arclight$targetSuccess;
} else {
setAttackTarget(livingEntity);
return arclight$targetSuccess;
}
} }
@Override @Override

View File

@ -58,10 +58,7 @@ public abstract class EndermanEntityMixin extends CreatureEntityMixin implements
*/ */
@Overwrite @Overwrite
public void setAttackTarget(@Nullable LivingEntity entity) { public void setAttackTarget(@Nullable LivingEntity entity) {
if (this.getAttackTarget() == entity) { this.bridge$pushGoalTargetReason(EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true);
return;
}
this.bridge$pushGoalTargetReason(EntityTargetEvent.TargetReason.UNKNOWN, true);
super.setAttackTarget(entity); super.setAttackTarget(entity);
if (arclight$targetSuccess) { if (arclight$targetSuccess) {
bridge$updateTarget(getAttackTarget()); bridge$updateTarget(getAttackTarget());

View File

@ -183,12 +183,19 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
private float pluginRainPosition; private float pluginRainPosition;
private float pluginRainPositionPrevious; private float pluginRainPositionPrevious;
public String locale = "en_us"; public String locale = "en_us";
private boolean arclight$initialized = false;
@Inject(method = "<init>", at = @At("RETURN")) @Inject(method = "<init>", at = @At("RETURN"))
public void arclight$init(CallbackInfo ci) { public void arclight$init(CallbackInfo ci) {
this.displayName = getScoreboardName(); this.displayName = getScoreboardName();
this.canPickUpLoot = true; this.canPickUpLoot = true;
this.maxHealthCache = this.getMaxHealth(); this.maxHealthCache = this.getMaxHealth();
this.arclight$initialized = true;
}
@Override
public boolean bridge$initialized() {
return this.arclight$initialized;
} }
public final BlockPos getSpawnPoint(ServerWorld worldserver) { public final BlockPos getSpawnPoint(ServerWorld worldserver) {

View File

@ -1,10 +1,18 @@
package io.izzel.arclight.common.mixin.core.network.datasync; package io.izzel.arclight.common.mixin.core.network.datasync;
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.common.bridge.network.datasync.EntityDataManagerBridge; import io.izzel.arclight.common.bridge.network.datasync.EntityDataManagerBridge;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.network.datasync.EntityDataManager;
import org.bukkit.craftbukkit.v.entity.CraftPlayer;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; 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;
@Mixin(EntityDataManager.class) @Mixin(EntityDataManager.class)
public abstract class EntityDataManagerMixin implements EntityDataManagerBridge { public abstract class EntityDataManagerMixin implements EntityDataManagerBridge {
@ -12,8 +20,18 @@ public abstract class EntityDataManagerMixin implements EntityDataManagerBridge
// @formatter:off // @formatter:off
@Shadow protected abstract <T> EntityDataManager.DataEntry<T> getEntry(DataParameter<T> key); @Shadow protected abstract <T> EntityDataManager.DataEntry<T> getEntry(DataParameter<T> key);
@Shadow private boolean dirty; @Shadow private boolean dirty;
@Shadow @Final private Entity entity;
// @formatter:on // @formatter:on
@Inject(method = "set", at = @At("HEAD"))
private <T> void arclight$syncHealth(DataParameter<T> key, T value, CallbackInfo ci) {
if (key == LivingEntity.HEALTH && this.entity instanceof ServerPlayerEntityBridge
&& ((ServerPlayerEntityBridge) this.entity).bridge$initialized()) {
CraftPlayer player = ((ServerPlayerEntityBridge) this.entity).bridge$getBukkitEntity();
player.setRealHealth(((Float) value));
}
}
public <T> void markDirty(DataParameter<T> key) { public <T> void markDirty(DataParameter<T> key) {
EntityDataManager.DataEntry<T> entry = this.getEntry(key); EntityDataManager.DataEntry<T> entry = this.getEntry(key);
entry.setDirty(true); entry.setDirty(true);

View File

@ -43,7 +43,6 @@ import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@ -219,12 +218,26 @@ public abstract class TrackedEntityMixin implements TrackedEntityBridge {
} }
} }
@Redirect(method = "track", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/TrackedEntity;sendSpawnPackets(Ljava/util/function/Consumer;)V")) @Inject(method = "track", at = @At("HEAD"))
private void arclight$addPlayer(TrackedEntity trackedEntity, Consumer<IPacket<?>> consumer, ServerPlayerEntity playerEntity) { private void arclight$addPlayer(ServerPlayerEntity player, CallbackInfo ci) {
a(consumer, playerEntity); this.arclight$player = player;
} }
public void a(Consumer<IPacket<?>> consumer, ServerPlayerEntity entityplayer) { private transient ServerPlayerEntity arclight$player;
public void a(final Consumer<IPacket<?>> consumer, ServerPlayerEntity playerEntity) {
this.arclight$player = playerEntity;
this.sendSpawnPackets(consumer);
}
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public void sendSpawnPackets(final Consumer<IPacket<?>> consumer) {
ServerPlayerEntity player = arclight$player;
arclight$player = null;
MobEntity entityinsentient; MobEntity entityinsentient;
if (this.trackedEntity.removed) { if (this.trackedEntity.removed) {
return; return;
@ -238,7 +251,7 @@ public abstract class TrackedEntityMixin implements TrackedEntityBridge {
boolean flag = this.sendVelocityUpdates; boolean flag = this.sendVelocityUpdates;
if (this.trackedEntity instanceof LivingEntity) { if (this.trackedEntity instanceof LivingEntity) {
Collection<ModifiableAttributeInstance> collection = ((LivingEntity) this.trackedEntity).getAttributeManager().getWatchedInstances(); Collection<ModifiableAttributeInstance> collection = ((LivingEntity) this.trackedEntity).getAttributeManager().getWatchedInstances();
if (this.trackedEntity.getEntityId() == entityplayer.getEntityId()) { if (this.trackedEntity.getEntityId() == player.getEntityId()) {
((ServerPlayerEntityBridge) this.trackedEntity).bridge$getBukkitEntity().injectScaledMaxHealth(collection, false); ((ServerPlayerEntityBridge) this.trackedEntity).bridge$getBukkitEntity().injectScaledMaxHealth(collection, false);
} }
if (!collection.isEmpty()) { if (!collection.isEmpty()) {

View File

@ -13,6 +13,7 @@
"overwrites": { "overwrites": {
"conformVisibility": true "conformVisibility": true
}, },
"mixinPriority": 500,
"mixins": [ "mixins": [
"advancements.AdvancementMixin", "advancements.AdvancementMixin",
"advancements.PlayerAdvancementsMixin", "advancements.PlayerAdvancementsMixin",