Skip to content

Instantly share code, notes, and snippets.

@Dragorn421
Last active May 19, 2017 21:38
Show Gist options
  • Save Dragorn421/7a8f08f63a48db7409852a7f04100e07 to your computer and use it in GitHub Desktop.
Save Dragorn421/7a8f08f63a48db7409852a7f04100e07 to your computer and use it in GitHub Desktop.
DISCLAIMER: I OWN NONE OF THIS CODE
PlayerConnection#a(PacketPlayInFlying) (actually called for any player movement it seems)
calls
EntityPlayer#l()
calls
EntityHuman#t_()
calls
EntityLiving#t_()
calls
Entity#t_()
calls
EntityLiving#K()
calls
EntityLiving#bi() (most likely named tickPotionEffects() when deobfuscated)
Crash happens with Iterator#next() in EntityLiving#bi() meaning potion effects are modified while the bi() inner loop runs
public void t_() {
this.K();// line 247 in Entity#t_()
}
public void t_() {
this.noclip = this.isSpectator();
if (this.isSpectator()) {
this.onGround = false;
}
if (this.g != null) {
ItemStack itemstack = this.inventory.getItemInHand();
if (itemstack == this.g) {
if (this.h <= 25 && this.h % 4 == 0) {
this.b(itemstack, 5);
}
if (--this.h == 0 && !this.world.isClientSide) {
this.s();
}
} else {
this.bV();
}
}
if (this.bp > 0) {
--this.bp;
}
if (this.isSleeping()) {
++this.sleepTicks;
if (this.sleepTicks > 100) {
this.sleepTicks = 100;
}
if (!this.world.isClientSide) {
if (!this.p()) {
this.a(true, true, false);
} else if (this.world.w()) {
this.a(false, true, true);
}
}
} else if (this.sleepTicks > 0) {
++this.sleepTicks;
if (this.sleepTicks >= 110) {
this.sleepTicks = 0;
}
}
super.t_();// line 173 EntityHuman#t_()
if (!this.world.isClientSide && this.activeContainer != null && !this.activeContainer.a(this)) {
this.closeInventory();
this.activeContainer = this.defaultContainer;
}
if (this.isBurning() && this.abilities.isInvulnerable) {
this.extinguish();
}
this.bq = this.bt;
this.br = this.bu;
this.bs = this.bv;
double d0 = this.locX - this.bt;
double d1 = this.locY - this.bu;
double d2 = this.locZ - this.bv;
double d3 = 10.0D;
if (d0 > d3) {
this.bq = this.bt = this.locX;
}
if (d2 > d3) {
this.bs = this.bv = this.locZ;
}
if (d1 > d3) {
this.br = this.bu = this.locY;
}
if (d0 < -d3) {
this.bq = this.bt = this.locX;
}
if (d2 < -d3) {
this.bs = this.bv = this.locZ;
}
if (d1 < -d3) {
this.br = this.bu = this.locY;
}
this.bt += d0 * 0.25D;
this.bv += d2 * 0.25D;
this.bu += d1 * 0.25D;
if (this.vehicle == null) {
this.e = null;
}
if (!this.world.isClientSide) {
this.foodData.a(this);
this.b(StatisticList.g);
if (this.isAlive()) {
this.b(StatisticList.h);
}
}
int i = 29999999;
double d4 = MathHelper.a(this.locX, -2.9999999E7D, 2.9999999E7D);
double d5 = MathHelper.a(this.locZ, -2.9999999E7D, 2.9999999E7D);
if (d4 != this.locX || d5 != this.locZ) {
this.setPosition(d4, this.locY, d5);
}
}
public void K() {
this.ay = this.az;
super.K();
this.world.methodProfiler.a("livingEntityBaseTick");
boolean flag = this instanceof EntityHuman;
if (this.isAlive()) {
if (this.inBlock()) {
this.damageEntity(DamageSource.STUCK, 1.0F);
} else if (flag && !this.world.getWorldBorder().a(this.getBoundingBox())) {
double d0 = this.world.getWorldBorder().a((Entity) this) + this.world.getWorldBorder().getDamageBuffer();
if (d0 < 0.0D) {
this.damageEntity(DamageSource.STUCK, (float) Math.max(1, MathHelper.floor(-d0 * this.world.getWorldBorder().getDamageAmount())));
}
}
}
if (this.isFireProof() || this.world.isClientSide) {
this.extinguish();
}
boolean flag1 = flag && ((EntityHuman) this).abilities.isInvulnerable;
if (this.isAlive()) {
if (this.a(Material.WATER)) {
if (!this.aY() && !this.hasEffect(MobEffectList.WATER_BREATHING.id) && !flag1) {
this.setAirTicks(this.j(this.getAirTicks()));
if (this.getAirTicks() == -20) {
this.setAirTicks(0);
for (int i = 0; i < 8; ++i) {
float f = this.random.nextFloat() - this.random.nextFloat();
float f1 = this.random.nextFloat() - this.random.nextFloat();
float f2 = this.random.nextFloat() - this.random.nextFloat();
this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX + (double) f, this.locY + (double) f1, this.locZ + (double) f2, this.motX, this.motY, this.motZ, new int[0]);
}
this.damageEntity(DamageSource.DROWN, 2.0F);
}
}
if (!this.world.isClientSide && this.au() && this.vehicle instanceof EntityLiving) {
this.mount((Entity) null);
}
} else {
// CraftBukkit start - Only set if needed to work around a DataWatcher inefficiency
if (this.getAirTicks() != 300) {
this.setAirTicks(maxAirTicks);
}
// CraftBukkit end
}
}
if (this.isAlive() && this.U()) {
this.extinguish();
}
this.aE = this.aF;
if (this.hurtTicks > 0) {
--this.hurtTicks;
}
if (this.noDamageTicks > 0 && !(this instanceof EntityPlayer)) {
--this.noDamageTicks;
}
if (this.getHealth() <= 0.0F) {
this.aZ();
}
if (this.lastDamageByPlayerTime > 0) {
--this.lastDamageByPlayerTime;
} else {
this.killer = null;
}
if (this.bk != null && !this.bk.isAlive()) {
this.bk = null;
}
if (this.lastDamager != null) {
if (!this.lastDamager.isAlive()) {
this.b((EntityLiving) null);
} else if (this.ticksLived - this.hurtTimestamp > 100) {
this.b((EntityLiving) null);
}
}
this.bi();// line 257 in EntityLiving#K() from Entity#t_()
this.aU = this.aT;
this.aJ = this.aI;
this.aL = this.aK;
this.lastYaw = this.yaw;
this.lastPitch = this.pitch;
this.world.methodProfiler.b();
}
protected void bi() {
Iterator iterator = this.effects.keySet().iterator();
isTickingEffects = true; // CraftBukkit
while (iterator.hasNext()) {
Integer integer = (Integer) iterator.next();// line 472 in EntityLiving#bi() from EntityLiving#K() from Entity#t_()
MobEffect mobeffect = (MobEffect) this.effects.get(integer);
if (!mobeffect.tick(this)) {
if (!this.world.isClientSide) {
iterator.remove();
this.b(mobeffect);
}
} else if (mobeffect.getDuration() % 600 == 0) {
this.a(mobeffect, false);
}
}
// CraftBukkit start
isTickingEffects = false;
for (Object e : effectsToProcess) {
if (e instanceof MobEffect) {
addEffect((MobEffect) e);
} else {
removeEffect((Integer) e);
}
}
// CraftBukkit end
if (this.updateEffects) {
if (!this.world.isClientSide) {
this.B();
}
this.updateEffects = false;
}
int i = this.datawatcher.getInt(7);
boolean flag = this.datawatcher.getByte(8) > 0;
if (i > 0) {
boolean flag1 = false;
if (!this.isInvisible()) {
flag1 = this.random.nextBoolean();
} else {
flag1 = this.random.nextInt(15) == 0;
}
if (flag) {
flag1 &= this.random.nextInt(5) == 0;
}
if (flag1 && i > 0) {
double d0 = (double) (i >> 16 & 255) / 255.0D;
double d1 = (double) (i >> 8 & 255) / 255.0D;
double d2 = (double) (i >> 0 & 255) / 255.0D;
this.world.addParticle(flag ? EnumParticle.SPELL_MOB_AMBIENT : EnumParticle.SPELL_MOB, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, d0, d1, d2, new int[0]);
}
}
}
public void t_() {
SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot
super.t_();// line 1448 EntityLiving#t_()
if (!this.world.isClientSide) {
int i = this.bv();
if (i > 0) {
if (this.at <= 0) {
this.at = 20 * (30 - i);
}
--this.at;
if (this.at <= 0) {
this.o(i - 1);
}
}
for (int j = 0; j < 5; ++j) {
ItemStack itemstack = this.h[j];
ItemStack itemstack1 = this.getEquipment(j);
if (!ItemStack.matches(itemstack1, itemstack)) {
((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutEntityEquipment(this.getId(), j, itemstack1)));
if (itemstack != null) {
this.c.a(itemstack.B());
}
if (itemstack1 != null) {
this.c.b(itemstack1.B());
}
this.h[j] = itemstack1 == null ? null : itemstack1.cloneItemStack();
}
}
if (this.ticksLived % 20 == 0) {
this.bs().g();
}
}
SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot
this.m();
SpigotTimings.timerEntityTickRest.startTiming(); // Spigot
double d0 = this.locX - this.lastX;
double d1 = this.locZ - this.lastZ;
float f = (float) (d0 * d0 + d1 * d1);
float f1 = this.aI;
float f2 = 0.0F;
this.aR = this.aS;
float f3 = 0.0F;
if (f > 0.0025000002F) {
f3 = 1.0F;
f2 = (float) Math.sqrt((double) f) * 3.0F;
// CraftBukkit - Math -> TrigMath
f1 = (float) org.bukkit.craftbukkit.TrigMath.atan2(d1, d0) * 180.0F / 3.1415927F - 90.0F;
}
if (this.az > 0.0F) {
f1 = this.yaw;
}
if (!this.onGround) {
f3 = 0.0F;
}
this.aS += (f3 - this.aS) * 0.3F;
this.world.methodProfiler.a("headTurn");
f2 = this.h(f1, f2);
this.world.methodProfiler.b();
this.world.methodProfiler.a("rangeChecks");
while (this.yaw - this.lastYaw < -180.0F) {
this.lastYaw -= 360.0F;
}
while (this.yaw - this.lastYaw >= 180.0F) {
this.lastYaw += 360.0F;
}
while (this.aI - this.aJ < -180.0F) {
this.aJ -= 360.0F;
}
while (this.aI - this.aJ >= 180.0F) {
this.aJ += 360.0F;
}
while (this.pitch - this.lastPitch < -180.0F) {
this.lastPitch -= 360.0F;
}
while (this.pitch - this.lastPitch >= 180.0F) {
this.lastPitch += 360.0F;
}
while (this.aK - this.aL < -180.0F) {
this.aL -= 360.0F;
}
while (this.aK - this.aL >= 180.0F) {
this.aL += 360.0F;
}
this.world.methodProfiler.b();
this.aT += f2;
SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot
}
public void l() {
try {
super.t_();// line 285 EntityPlayer#l()
for (int i = 0; i < this.inventory.getSize(); ++i) {
ItemStack itemstack = this.inventory.getItem(i);
if (itemstack != null && itemstack.getItem().f()) {
Packet packet = ((ItemWorldMapBase) itemstack.getItem()).c(itemstack, this.world, this);
if (packet != null) {
this.playerConnection.sendPacket(packet);
}
}
}
// CraftBukkit - Optionally scale health
if (this.getHealth() != this.bM || this.bN != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.bO) {
this.playerConnection.sendPacket(new PacketPlayOutUpdateHealth(this.getBukkitEntity().getScaledHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel()));
this.bM = this.getHealth();
this.bN = this.foodData.getFoodLevel();
this.bO = this.foodData.getSaturationLevel() == 0.0F;
}
if (this.getHealth() + this.getAbsorptionHearts() != this.bL) {
this.bL = this.getHealth() + this.getAbsorptionHearts();
Collection collection = this.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.g);
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next();
this.getScoreboard().getPlayerScoreForObjective(this.getName(), scoreboardobjective).updateForList(Arrays.asList(new EntityHuman[] { this}));
}
// CraftBukkit - Update ALL the scores!
this.world.getServer().getScoreboardManager().updateAllScoresForList(IScoreboardCriteria.g, this.getName(), com.google.common.collect.ImmutableList.of(this));
}
// CraftBukkit start - Force max health updates
if (this.maxHealthCache != this.getMaxHealth()) {
this.getBukkitEntity().updateScaledHealth();
}
// CraftBukkit end
if (this.expTotal != this.lastSentExp) {
this.lastSentExp = this.expTotal;
this.playerConnection.sendPacket(new PacketPlayOutExperience(this.exp, this.expTotal, this.expLevel));
}
if (this.ticksLived % 20 * 5 == 0 && !this.getStatisticManager().hasAchievement(AchievementList.L)) {
this.i_();
}
// CraftBukkit start - initialize oldLevel and fire PlayerLevelChangeEvent
if (this.oldLevel == -1) {
this.oldLevel = this.expLevel;
}
if (this.oldLevel != this.expLevel) {
CraftEventFactory.callPlayerLevelChangeEvent(this.world.getServer().getPlayer((EntityPlayer) this), this.oldLevel, this.expLevel);
this.oldLevel = this.expLevel;
}
// CraftBukkit end
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.a(throwable, "Ticking player");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Player being ticked");
this.appendEntityCrashDetails(crashreportsystemdetails);
throw new ReportedException(crashreport);
}
}
public void a(PacketPlayInFlying packetplayinflying) {
PlayerConnectionUtils.ensureMainThread(packetplayinflying, this, this.player.u());
if (this.b(packetplayinflying)) {
this.disconnect("Invalid move packet received");
} else {
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
this.h = true;
if (!this.player.viewingCredits) {
double d0 = this.player.locX;
double d1 = this.player.locY;
double d2 = this.player.locZ;
double d3 = 0.0D;
double d4 = packetplayinflying.a() - this.o;
double d5 = packetplayinflying.b() - this.p;
double d6 = packetplayinflying.c() - this.q;
if (packetplayinflying.g()) {
d3 = d4 * d4 + d5 * d5 + d6 * d6;
if (!this.checkMovement && d3 < 0.25D) {
this.checkMovement = true;
}
}
// CraftBukkit start - fire PlayerMoveEvent
Player player = this.getPlayer();
// Spigot Start
if ( !hasMoved )
{
Location curPos = player.getLocation();
lastPosX = curPos.getX();
lastPosY = curPos.getY();
lastPosZ = curPos.getZ();
lastYaw = curPos.getYaw();
lastPitch = curPos.getPitch();
hasMoved = true;
}
// Spigot End
Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
// If the packet contains movement information then we update the To location with the correct XYZ.
if (packetplayinflying.hasPos && !(packetplayinflying.hasPos && packetplayinflying.y == -999.0D)) {
to.setX(packetplayinflying.x);
to.setY(packetplayinflying.y);
to.setZ(packetplayinflying.z);
}
// If the packet contains look information then we update the To location with the correct Yaw & Pitch.
if (packetplayinflying.hasLook) {
to.setYaw(packetplayinflying.yaw);
to.setPitch(packetplayinflying.pitch);
}
// Prevent 40 event-calls for less than a single pixel of movement >.>
double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2);
float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch());
if ((delta > 1f / 256 || deltaAngle > 10f) && (this.checkMovement && !this.player.dead)) {
this.lastPosX = to.getX();
this.lastPosY = to.getY();
this.lastPosZ = to.getZ();
this.lastYaw = to.getYaw();
this.lastPitch = to.getPitch();
// Skip the first time we do this
if (true) { // Spigot - don't skip any move events
Location oldTo = to.clone();
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
this.server.getPluginManager().callEvent(event);
// If the event is cancelled we move the player back to their old location.
if (event.isCancelled()) {
this.player.playerConnection.sendPacket(new PacketPlayOutPosition(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet()));
return;
}
/* If a Plugin has changed the To destination then we teleport the Player
there to avoid any 'Moved wrongly' or 'Moved too quickly' errors.
We only do this if the Event was not cancelled. */
if (!oldTo.equals(event.getTo()) && !event.isCancelled()) {
this.player.getBukkitEntity().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.UNKNOWN);
return;
}
/* Check to see if the Players Location has some how changed during the call of the event.
This can happen due to a plugin teleporting the player instead of using .setTo() */
if (!from.equals(this.getPlayer().getLocation()) && this.justTeleported) {
this.justTeleported = false;
return;
}
}
}
if (this.checkMovement && !this.player.dead) {
// CraftBukkit end
this.f = this.e;
double d7;
double d8;
double d9;
if (this.player.vehicle != null) {
float f = this.player.yaw;
float f1 = this.player.pitch;
this.player.vehicle.al();
d7 = this.player.locX;
d8 = this.player.locY;
d9 = this.player.locZ;
if (packetplayinflying.h()) {
f = packetplayinflying.d();
f1 = packetplayinflying.e();
}
this.player.onGround = packetplayinflying.f();
this.player.l();
this.player.setLocation(d7, d8, d9, f, f1);
if (this.player.vehicle != null) {
this.player.vehicle.al();
}
this.minecraftServer.getPlayerList().d(this.player);
if (this.player.vehicle != null) {
this.player.vehicle.ai = true; // CraftBukkit - moved from below
if (d3 > 4.0D) {
Entity entity = this.player.vehicle;
this.player.playerConnection.sendPacket(new PacketPlayOutEntityTeleport(entity));
this.a(this.player.locX, this.player.locY, this.player.locZ, this.player.yaw, this.player.pitch);
}
// this.player.vehicle.ai = true; // CraftBukkit - moved up
}
if (this.checkMovement) {
this.o = this.player.locX;
this.p = this.player.locY;
this.q = this.player.locZ;
}
worldserver.g(this.player);
return;
}
if (this.player.isSleeping()) {
this.player.l();
this.player.setLocation(this.o, this.p, this.q, this.player.yaw, this.player.pitch);
worldserver.g(this.player);
return;
}
double d10 = this.player.locY;
this.o = this.player.locX;
this.p = this.player.locY;
this.q = this.player.locZ;
d7 = this.player.locX;
d8 = this.player.locY;
d9 = this.player.locZ;
float f2 = this.player.yaw;
float f3 = this.player.pitch;
if (packetplayinflying.g() && packetplayinflying.b() == -999.0D) {
packetplayinflying.a(false);
}
if (packetplayinflying.g()) {
d7 = packetplayinflying.a();
d8 = packetplayinflying.b();
d9 = packetplayinflying.c();
if (Math.abs(packetplayinflying.a()) > 3.0E7D || Math.abs(packetplayinflying.c()) > 3.0E7D) {
this.disconnect("Illegal position");
return;
}
}
if (packetplayinflying.h()) {
f2 = packetplayinflying.d();
f3 = packetplayinflying.e();
}
this.player.l();// line 382 in PlayerConnection#a(PacketPlayInFlying)
this.player.setLocation(this.o, this.p, this.q, f2, f3);
if (!this.checkMovement) {
return;
}
double d11 = d7 - this.player.locX;
double d12 = d8 - this.player.locY;
double d13 = d9 - this.player.locZ;
double d14 = this.player.motX * this.player.motX + this.player.motY * this.player.motY + this.player.motZ * this.player.motZ;
double d15 = d11 * d11 + d12 * d12 + d13 * d13;
// Spigot: make "moved too quickly" limit configurable
if (d15 - d14 > org.spigotmc.SpigotConfig.movedTooQuicklyThreshold && this.checkMovement && (!this.minecraftServer.T() || !this.minecraftServer.S().equals(this.player.getName()))) { // CraftBukkit - Added this.checkMovement condition to solve this check being triggered by teleports
PlayerConnection.c.warn(this.player.getName() + " moved too quickly! " + d11 + "," + d12 + "," + d13 + " (" + d11 + ", " + d12 + ", " + d13 + ")");
this.a(this.o, this.p, this.q, this.player.yaw, this.player.pitch);
return;
}
float f4 = 0.0625F;
boolean flag = worldserver.getCubes(this.player, this.player.getBoundingBox().shrink((double) f4, (double) f4, (double) f4)).isEmpty();
if (this.player.onGround && !packetplayinflying.f() && d12 > 0.0D) {
this.player.bF();
}
this.player.move(d11, d12, d13);
this.player.onGround = packetplayinflying.f();
double d16 = d12;
d11 = d7 - this.player.locX;
d12 = d8 - this.player.locY;
if (d12 > -0.5D || d12 < 0.5D) {
d12 = 0.0D;
}
d13 = d9 - this.player.locZ;
d15 = d11 * d11 + d12 * d12 + d13 * d13;
boolean flag1 = false;
// Spigot: make "moved wrongly" limit configurable
if (d15 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.playerInteractManager.isCreative()) {
flag1 = true;
PlayerConnection.c.warn(this.player.getName() + " moved wrongly!");
}
this.player.setLocation(d7, d8, d9, f2, f3);
this.player.checkMovement(this.player.locX - d0, this.player.locY - d1, this.player.locZ - d2);
if (!this.player.noclip) {
boolean flag2 = worldserver.getCubes(this.player, this.player.getBoundingBox().shrink((double) f4, (double) f4, (double) f4)).isEmpty();
if (flag && (flag1 || !flag2) && !this.player.isSleeping()) {
this.a(this.o, this.p, this.q, f2, f3);
return;
}
}
AxisAlignedBB axisalignedbb = this.player.getBoundingBox().grow((double) f4, (double) f4, (double) f4).a(0.0D, -0.55D, 0.0D);
if (!this.minecraftServer.getAllowFlight() && !this.player.abilities.canFly && !worldserver.c(axisalignedbb)) {
if (d16 >= -0.03125D) {
++this.g;
if (this.g > 80) {
PlayerConnection.c.warn(this.player.getName() + " was kicked for floating too long!");
this.disconnect("Flying is not enabled on this server");
return;
}
}
} else {
this.g = 0;
}
this.player.onGround = packetplayinflying.f();
this.minecraftServer.getPlayerList().d(this.player);
this.player.a(this.player.locY - d10, packetplayinflying.f());
} else if (this.e - this.f > 20) {
this.a(this.o, this.p, this.q, this.player.yaw, this.player.pitch);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment