Async Operation Catching

Catch and throw an exception when a potentially unsafe operation occurs on a thread other than the main server thread.

By: md_5 <git@md-5.net>
This commit is contained in:
CraftBukkit/Spigot
2014-03-25 16:10:01 +11:00
parent 973f52a650
commit 5240271410
12 changed files with 185 additions and 97 deletions

View File

@@ -216,10 +216,13 @@
this.activeEffects.clear();
}
@@ -781,6 +841,17 @@
}
}
@@ -778,8 +838,19 @@
if (mobeffect != null) {
this.activeEffects.put(mobeffect.getEffect(), mobeffect);
}
+ }
+ }
+
+ // CraftBukkit start
+ if (nbt.contains("Bukkit.MaxHealth")) {
+ Tag nbtbase = nbt.get("Bukkit.MaxHealth");
@@ -227,13 +230,12 @@
+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(((FloatTag) nbtbase).getAsDouble());
+ } else if (nbtbase.getId() == 3) {
+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(((IntTag) nbtbase).getAsDouble());
+ }
+ }
}
}
+ // CraftBukkit end
+
if (nbt.contains("Health", 99)) {
this.setHealth(nbt.getFloat("Health"));
}
@@ -819,9 +890,32 @@
}
@@ -348,7 +350,7 @@
}
}
@@ -987,24 +1117,54 @@
@@ -987,24 +1117,55 @@
return this.addEffect(effect, (Entity) null);
}
@@ -363,6 +365,7 @@
+ }
+
+ public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) {
+ org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot
+ if (this.isTickingEffects) {
+ this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause));
+ return true;
@@ -412,7 +415,7 @@
return flag;
}
}
@@ -1031,14 +1191,40 @@
@@ -1031,14 +1192,40 @@
return this.getType().is(EntityTypeTags.INVERTED_HEALING_AND_HARM);
}
@@ -455,7 +458,7 @@
if (mobeffect != null) {
this.onEffectsRemoved(List.of(mobeffect));
return true;
@@ -1142,20 +1328,55 @@
@@ -1142,20 +1329,55 @@
}
@@ -512,7 +515,7 @@
this.entityData.set(LivingEntity.DATA_HEALTH_ID, Mth.clamp(health, 0.0F, this.getMaxHealth()));
}
@@ -1167,7 +1388,7 @@
@@ -1167,7 +1389,7 @@
public boolean hurtServer(ServerLevel world, DamageSource source, float amount) {
if (this.isInvulnerableTo(world, source)) {
return false;
@@ -521,7 +524,7 @@
return false;
} else if (source.is(DamageTypeTags.IS_FIRE) && this.hasEffect(MobEffects.FIRE_RESISTANCE)) {
return false;
@@ -1182,10 +1403,11 @@
@@ -1182,10 +1404,11 @@
}
float f1 = amount;
@@ -535,7 +538,7 @@
this.hurtCurrentlyUsedShield(amount);
f2 = amount;
amount = 0.0F;
@@ -1202,15 +1424,26 @@
@@ -1202,15 +1425,26 @@
flag = true;
}
@@ -564,7 +567,7 @@
this.walkAnimation.setSpeed(1.5F);
if (Float.isNaN(amount) || Float.isInfinite(amount)) {
amount = Float.MAX_VALUE;
@@ -1218,18 +1451,27 @@
@@ -1218,18 +1452,27 @@
boolean flag1 = true;
@@ -596,7 +599,7 @@
this.hurtDuration = 10;
this.hurtTime = this.hurtDuration;
}
@@ -1243,7 +1485,7 @@
@@ -1243,7 +1486,7 @@
world.broadcastDamageEvent(this, source);
}
@@ -605,7 +608,7 @@
this.markHurt();
}
@@ -1263,7 +1505,7 @@
@@ -1263,7 +1506,7 @@
d1 = source.getSourcePosition().z() - this.getZ();
}
@@ -614,7 +617,7 @@
if (!flag) {
this.indicateDamage(d0, d1);
}
@@ -1282,7 +1524,7 @@
@@ -1282,7 +1525,7 @@
this.playHurtSound(source);
}
@@ -623,7 +626,7 @@
if (flag2) {
this.lastDamageSource = source;
@@ -1329,10 +1571,10 @@
@@ -1329,10 +1572,10 @@
}
@Nullable
@@ -636,7 +639,7 @@
this.lastHurtByPlayerTime = 100;
this.lastHurtByPlayer = entityhuman;
return entityhuman;
@@ -1342,8 +1584,8 @@
@@ -1342,8 +1585,8 @@
this.lastHurtByPlayerTime = 100;
LivingEntity entityliving = entitywolf.getOwner();
@@ -647,7 +650,7 @@
this.lastHurtByPlayer = entityhuman1;
} else {
@@ -1363,7 +1605,7 @@
@@ -1363,7 +1606,7 @@
}
protected void blockedByShield(LivingEntity target) {
@@ -656,7 +659,7 @@
}
private boolean checkTotemDeathProtection(DamageSource source) {
@@ -1375,20 +1617,33 @@
@@ -1375,20 +1618,33 @@
InteractionHand[] aenumhand = InteractionHand.values();
int i = aenumhand.length;
@@ -694,7 +697,7 @@
ServerPlayer entityplayer = (ServerPlayer) this;
entityplayer.awardStat(Stats.ITEM_USED.get(itemstack.getItem()));
@@ -1512,14 +1767,22 @@
@@ -1512,14 +1768,22 @@
BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState();
if (this.level().getBlockState(blockposition).isAir() && iblockdata.canSurvive(this.level(), blockposition)) {
@@ -719,7 +722,7 @@
this.level().addFreshEntity(entityitem);
}
}
@@ -1530,24 +1793,39 @@
@@ -1530,22 +1794,37 @@
protected void dropAllDeathLoot(ServerLevel world, DamageSource damageSource) {
boolean flag = this.lastHurtByPlayerTime > 0;
@@ -749,8 +752,8 @@
}
+ return 0; // CraftBukkit
}
+ }
+
+ protected void dropExperience(ServerLevel world, @Nullable Entity attacker) {
+ // CraftBukkit start - Update getExpReward() above if the removed if() changes!
+ if (!(this instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon)) { // CraftBukkit - SPIGOT-2420: Special case ender dragon will drop the xp over time
@@ -758,12 +761,10 @@
+ this.expToDrop = 0;
+ }
+ // CraftBukkit end
+ }
+
protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) {}
}
public long getLootTableSeed() {
@@ -1612,19 +1890,31 @@
protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) {}
@@ -1612,19 +1891,31 @@
}
public void knockback(double strength, double x, double z) {
@@ -802,7 +803,7 @@
}
}
@@ -1683,6 +1973,20 @@
@@ -1683,6 +1974,20 @@
return new LivingEntity.Fallsounds(SoundEvents.GENERIC_SMALL_FALL, SoundEvents.GENERIC_BIG_FALL);
}
@@ -823,7 +824,7 @@
public Optional<BlockPos> getLastClimbablePos() {
return this.lastClimbablePos;
}
@@ -1757,9 +2061,14 @@
@@ -1757,9 +2062,14 @@
int i = this.calculateFallDamage(fallDistance, damageMultiplier);
if (i > 0) {
@@ -839,7 +840,7 @@
return true;
} else {
return flag;
@@ -1830,7 +2139,7 @@
@@ -1830,7 +2140,7 @@
protected float getDamageAfterArmorAbsorb(DamageSource source, float amount) {
if (!source.is(DamageTypeTags.BYPASSES_ARMOR)) {
@@ -848,7 +849,7 @@
amount = CombatRules.getDamageAfterAbsorb(this, amount, source, (float) this.getArmorValue(), (float) this.getAttributeValue(Attributes.ARMOR_TOUGHNESS));
}
@@ -1841,7 +2150,8 @@
@@ -1841,7 +2151,8 @@
if (source.is(DamageTypeTags.BYPASSES_EFFECTS)) {
return amount;
} else {
@@ -858,7 +859,7 @@
int i = (this.getEffect(MobEffects.DAMAGE_RESISTANCE).getAmplifier() + 1) * 5;
int j = 25 - i;
float f1 = amount * (float) j;
@@ -1884,18 +2194,144 @@
@@ -1884,18 +2195,144 @@
}
}
@@ -1012,7 +1013,7 @@
if (entity instanceof ServerPlayer) {
ServerPlayer entityplayer = (ServerPlayer) entity;
@@ -1904,13 +2340,48 @@
@@ -1904,13 +2341,48 @@
}
}
@@ -1065,7 +1066,7 @@
}
public CombatTracker getCombatTracker() {
@@ -1935,9 +2406,19 @@
@@ -1935,9 +2407,19 @@
}
public final void setArrowCount(int stuckArrowCount) {
@@ -1086,7 +1087,7 @@
public final int getStingerCount() {
return (Integer) this.entityData.get(LivingEntity.DATA_STINGER_COUNT_ID);
}
@@ -1999,7 +2480,7 @@
@@ -1999,7 +2481,7 @@
this.playSound(soundeffect, this.getSoundVolume(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
}
@@ -1095,7 +1096,7 @@
this.setHealth(0.0F);
this.die(this.damageSources().generic());
}
@@ -2182,6 +2663,12 @@
@@ -2182,6 +2664,12 @@
public abstract ItemStack getItemBySlot(EquipmentSlot slot);
@@ -1108,7 +1109,7 @@
public abstract void setItemSlot(EquipmentSlot slot, ItemStack stack);
public Iterable<ItemStack> getHandSlots() {
@@ -2494,7 +2981,7 @@
@@ -2494,7 +2982,7 @@
}
@@ -1117,7 +1118,7 @@
Vec3 vec3d1 = this.getRiddenInput(controllingPlayer, movementInput);
this.tickRidden(controllingPlayer, vec3d1);
@@ -2507,13 +2994,13 @@
@@ -2507,13 +2995,13 @@
}
@@ -1134,7 +1135,7 @@
return this.getSpeed();
}
@@ -2571,7 +3058,7 @@
@@ -2571,7 +3059,7 @@
double d1 = Mth.clamp(motion.z, -0.15000000596046448D, 0.15000000596046448D);
double d2 = Math.max(motion.y, -0.15000000596046448D);
@@ -1143,7 +1144,7 @@
d2 = 0.0D;
}
@@ -2586,7 +3073,7 @@
@@ -2586,7 +3074,7 @@
}
protected float getFlyingSpeed() {
@@ -1152,7 +1153,7 @@
}
public float getSpeed() {
@@ -2634,7 +3121,7 @@
@@ -2634,7 +3122,7 @@
}
}
@@ -1161,7 +1162,7 @@
if (this.tickCount % 20 == 0) {
this.getCombatTracker().recheckStatus();
}
@@ -2741,7 +3228,7 @@
@@ -2741,7 +3229,7 @@
this.elytraAnimationState.tick();
}
@@ -1170,7 +1171,7 @@
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
if (map != null) {
@@ -3000,7 +3487,7 @@
@@ -3000,7 +3488,7 @@
{
LivingEntity entityliving = this.getControllingPassenger();
@@ -1179,7 +1180,7 @@
if (this.isAlive()) {
this.travelRidden(entityhuman, vec3d1);
break label112;
@@ -3063,6 +3550,7 @@
@@ -3063,6 +3551,7 @@
this.checkSlowFallDistance();
if (!this.level().isClientSide) {
if (!this.canGlide()) {
@@ -1187,7 +1188,7 @@
this.setSharedFlag(7, false);
return;
}
@@ -3113,7 +3601,7 @@
@@ -3113,7 +3602,7 @@
Level world = this.level();
if (!(world instanceof ServerLevel worldserver)) {
@@ -1196,7 +1197,7 @@
} else {
List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this));
@@ -3305,15 +3793,22 @@
@@ -3305,15 +3794,22 @@
@Override
public boolean isPickable() {
@@ -1221,7 +1222,7 @@
public float getYHeadRot() {
return this.yHeadRot;
}
@@ -3483,8 +3978,31 @@
@@ -3483,8 +3979,31 @@
this.releaseUsingItem();
} else {
if (!this.useItem.isEmpty() && this.isUsingItem()) {
@@ -1254,7 +1255,7 @@
if (itemstack != this.useItem) {
this.setItemInHand(enumhand, itemstack);
}
@@ -3568,12 +4086,18 @@
@@ -3568,12 +4087,18 @@
}
public boolean randomTeleport(double x, double y, double z, boolean particleEffects) {
@@ -1275,7 +1276,7 @@
Level world = this.level();
if (world.hasChunkAt(blockposition)) {
@@ -3592,18 +4116,43 @@
@@ -3592,18 +4117,43 @@
}
if (flag2) {
@@ -1323,7 +1324,7 @@
world.broadcastEntityEvent(this, (byte) 46);
}
@@ -3613,7 +4162,7 @@
@@ -3613,7 +4163,7 @@
entitycreature.getNavigation().stop();
}
@@ -1332,7 +1333,7 @@
}
}
@@ -3706,7 +4255,7 @@
@@ -3706,7 +4256,7 @@
}
public void stopSleeping() {
@@ -1341,7 +1342,7 @@
Level world = this.level();
java.util.Objects.requireNonNull(world);
@@ -3718,9 +4267,9 @@
@@ -3718,9 +4268,9 @@
this.level().setBlock(blockposition, (BlockState) iblockdata.setValue(BedBlock.OCCUPIED, false), 3);
Vec3 vec3d = (Vec3) BedBlock.findStandUpPosition(this.getType(), this.level(), blockposition, enumdirection, this.getYRot()).orElseGet(() -> {
@@ -1353,7 +1354,7 @@
});
Vec3 vec3d1 = Vec3.atBottomCenterOf(blockposition).subtract(vec3d).normalize();
float f = (float) Mth.wrapDegrees(Mth.atan2(vec3d1.z, vec3d1.x) * 57.2957763671875D - 90.0D);
@@ -3740,7 +4289,7 @@
@@ -3740,7 +4290,7 @@
@Nullable
public Direction getBedOrientation() {
@@ -1362,7 +1363,7 @@
return blockposition != null ? BedBlock.getBedOrientation(this.level(), blockposition) : null;
}
@@ -3905,7 +4454,7 @@
@@ -3905,7 +4455,7 @@
public float maxUpStep() {
float f = (float) this.getAttributeValue(Attributes.STEP_HEIGHT);