Commits

Thinkofname authored 9cd081f1ad8
Rework speed limiting to better handle server-set high velocities
No tags

nms-patches/EntityPlayer.patch

Modified
1 ---- ../work/decompile-8eb82bde/net/minecraft/server/EntityPlayer.java 2015-01-09 16:51:30.962362579 +1100
2 -+++ src/main/java/net/minecraft/server/EntityPlayer.java 2015-01-09 16:51:30.962362579 +1100
1 +--- ../work/decompile-8eb82bde//net/minecraft/server/EntityPlayer.java 2015-01-22 22:25:21.173416238 +0000
2 ++++ src/main/java/net/minecraft/server/EntityPlayer.java 2015-01-22 22:25:21.177416238 +0000
3 3 @@ -13,6 +13,17 @@
4 4 import org.apache.logging.log4j.LogManager;
5 5 import org.apache.logging.log4j.Logger;
6 6
7 7 +// CraftBukkit start
8 8 +import org.bukkit.Bukkit;
9 9 +import org.bukkit.WeatherType;
10 10 +import org.bukkit.craftbukkit.CraftWorld;
11 11 +import org.bukkit.craftbukkit.entity.CraftPlayer;
12 12 +import org.bukkit.craftbukkit.event.CraftEventFactory;
85 85 + this.setPosition(position.getX() + 0.5, position.getY(), position.getZ() + 0.5);
86 86 + }
87 87 + this.dimension = ((WorldServer) this.world).dimension;
88 88 + this.playerInteractManager.a((WorldServer) world);
89 89 + }
90 90 + // CraftBukkit end
91 91 +
92 92 public void levelDown(int i) {
93 93 super.levelDown(i);
94 94 this.lastSentExp = -1;
95 -@@ -114,6 +167,11 @@
95 +@@ -113,7 +166,26 @@
96 + this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.br(), EnumCombatEventType.END_COMBAT));
96 97 }
97 98
99 ++ // CraftBukkit start
100 ++ public double movementLimit = 0;
101 ++ public boolean hasLoggedSpeed = false;
102 ++
98 103 public void s_() {
104 ++ // Limit based on the server motion for the player
105 ++ double limit = this.motX * this.motX
106 ++ + this.motY * this.motY
107 ++ + this.motZ * this.motZ;
108 ++ limit *= 1.5; // Give a little extra room
109 ++ limit = Math.max(4, limit);
110 ++ hasLoggedSpeed = false;
111 ++ movementLimit = Math.min(movementLimit + limit, 2000);
112 ++ // CraftBukkit end
113 ++
99 114 + // CraftBukkit start
100 115 + if (this.joining) {
101 116 + this.joining = false;
102 117 + }
103 118 + // CraftBukkit end
104 119 this.playerInteractManager.a();
105 120 --this.invulnerableTicks;
106 121 if (this.noDamageTicks > 0) {
107 -@@ -155,7 +213,7 @@
122 +@@ -155,7 +227,7 @@
108 123 chunk = this.world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z);
109 124 if (chunk.isReady()) {
110 125 arraylist.add(chunk);
111 126 - arraylist1.addAll(((WorldServer) this.world).getTileEntities(chunkcoordintpair.x * 16, 0, chunkcoordintpair.z * 16, chunkcoordintpair.x * 16 + 16, 256, chunkcoordintpair.z * 16 + 16));
112 127 + arraylist1.addAll(chunk.tileEntities.values()); // CraftBukkit - Get tile entities directly from the chunk instead of the world
113 128 iterator1.remove();
114 129 }
115 130 }
116 -@@ -220,8 +278,9 @@
131 +@@ -220,8 +292,9 @@
117 132 }
118 133 }
119 134
120 135 + // CraftBukkit - Optionally scale health
121 136 if (this.getHealth() != this.bK || this.bL != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.bM) {
122 137 - this.playerConnection.sendPacket(new PacketPlayOutUpdateHealth(this.getHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel()));
123 138 + this.playerConnection.sendPacket(new PacketPlayOutUpdateHealth(this.getBukkitEntity().getScaledHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel()));
124 139 this.bK = this.getHealth();
125 140 this.bL = this.foodData.getFoodLevel();
126 141 this.bM = this.foodData.getSaturationLevel() == 0.0F;
127 -@@ -229,15 +288,14 @@
142 +@@ -229,15 +302,14 @@
128 143
129 144 if (this.getHealth() + this.getAbsorptionHearts() != this.bJ) {
130 145 this.bJ = this.getHealth() + this.getAbsorptionHearts();
131 146 - Collection collection = this.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.g);
132 147 - Iterator iterator = collection.iterator();
133 148 -
134 149 - while (iterator.hasNext()) {
135 150 - ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next();
136 151 -
137 152 - this.getScoreboard().getPlayerScoreForObjective(this.getName(), scoreboardobjective).updateForList(Arrays.asList(new EntityHuman[] { this}));
138 153 - }
139 154 + // CraftBukkit - Update ALL the scores!
140 155 + this.world.getServer().getScoreboardManager().updateAllScoresForList(IScoreboardCriteria.g, this.getName(), com.google.common.collect.ImmutableList.of(this));
141 -+ }
156 + }
142 157 + // CraftBukkit start - Force max health updates
143 158 + if (this.maxHealthCache != this.getMaxHealth()) {
144 159 + this.getBukkitEntity().updateScaledHealth();
145 - }
160 ++ }
146 161 + // CraftBukkit end
147 162
148 163 if (this.expTotal != this.lastSentExp) {
149 164 this.lastSentExp = this.expTotal;
150 -@@ -247,7 +305,17 @@
165 +@@ -247,7 +319,17 @@
151 166 if (this.ticksLived % 20 * 5 == 0 && !this.getStatisticManager().hasAchievement(AchievementList.L)) {
152 167 this.h_();
153 168 }
154 169 +
155 170 + // CraftBukkit start - initialize oldLevel and fire PlayerLevelChangeEvent
156 171 + if (this.oldLevel == -1) {
157 172 + this.oldLevel = this.expLevel;
158 173 + }
159 174
160 175 + if (this.oldLevel != this.expLevel) {
161 176 + CraftEventFactory.callPlayerLevelChangeEvent(this.world.getServer().getPlayer((EntityPlayer) this), this.oldLevel, this.expLevel);
162 177 + this.oldLevel = this.expLevel;
163 178 + }
164 179 + // CraftBukkit end
165 180 } catch (Throwable throwable) {
166 181 CrashReport crashreport = CrashReport.a(throwable, "Ticking player");
167 182 CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Player being ticked");
168 -@@ -296,30 +364,64 @@
183 +@@ -296,30 +378,64 @@
169 184 }
170 185
171 186 public void die(DamageSource damagesource) {
172 187 - if (this.world.getGameRules().getBoolean("showDeathMessages")) {
173 188 - ScoreboardTeamBase scoreboardteambase = this.getScoreboardTeam();
174 189 + // CraftBukkit start - fire PlayerDeathEvent
175 190 + if (this.dead) {
176 191 + return;
177 192 + }
178 193
236 251 + Collection collection = this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.d, this.getName(), new java.util.ArrayList<ScoreboardScore>());
237 252 Iterator iterator = collection.iterator();
238 253
239 254 while (iterator.hasNext()) {
240 255 - ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next();
241 256 - ScoreboardScore scoreboardscore = this.getScoreboard().getPlayerScoreForObjective(this.getName(), scoreboardobjective);
242 257 + ScoreboardScore scoreboardscore = (ScoreboardScore) iterator.next(); // CraftBukkit - Use our scores instead
243 258
244 259 scoreboardscore.incrementScore();
245 260 }
246 -@@ -376,7 +478,8 @@
261 +@@ -376,7 +492,8 @@
247 262 }
248 263
249 264 private boolean cq() {
250 265 - return this.server.getPVP();
251 266 + // CraftBukkit - this.server.getPvP() -> this.world.pvpMode
252 267 + return this.world.pvpMode;
253 268 }
254 269
255 270 public void c(int i) {
256 -@@ -388,6 +491,8 @@
271 +@@ -388,6 +505,8 @@
257 272 } else {
258 273 if (this.dimension == 0 && i == 1) {
259 274 this.b((Statistic) AchievementList.C);
260 275 + // CraftBukkit start - Rely on custom portal management
261 276 + /*
262 277 BlockPosition blockposition = this.server.getWorldServer(i).getDimensionSpawn();
263 278
264 279 if (blockposition != null) {
265 -@@ -395,11 +500,16 @@
280 +@@ -395,11 +514,16 @@
266 281 }
267 282
268 283 i = 1;
269 284 + */
270 285 + // CraftBukkit end
271 286 } else {
272 287 this.b((Statistic) AchievementList.y);
273 288 }
274 289
275 290 - this.server.getPlayerList().changeDimension(this, i);
276 291 + // CraftBukkit start
277 292 + TeleportCause cause = (this.dimension == 1 || i == 1) ? TeleportCause.END_PORTAL : TeleportCause.NETHER_PORTAL;
278 293 + this.server.getPlayerList().changeDimension(this, i, cause);
279 294 + // CraftBukkit end
280 295 this.lastSentExp = -1;
281 296 this.bK = -1.0F;
282 297 this.bL = -1;
283 -@@ -442,6 +552,8 @@
298 +@@ -442,6 +566,8 @@
284 299 }
285 300
286 301 public void a(boolean flag, boolean flag1, boolean flag2) {
287 302 + if (!this.sleeping) return; // CraftBukkit - Can't leave bed if not in one!
288 303 +
289 304 if (this.isSleeping()) {
290 305 this.u().getTracker().sendPacketToEntity(this, new PacketPlayOutAnimation(this, 2));
291 306 }
292 -@@ -490,19 +602,46 @@
307 +@@ -490,19 +616,46 @@
293 308 this.playerConnection.sendPacket(new PacketPlayOutOpenSignEditor(tileentitysign.getPosition()));
294 309 }
295 310
296 311 - public void nextContainerCounter() {
297 312 + public int nextContainerCounter() { // CraftBukkit - private void -> public int
298 313 this.containerCounter = this.containerCounter % 100 + 1;
299 314 + return containerCounter; // CraftBukkit
300 315 }
301 316
302 317 public void openTileEntity(ITileEntityContainer itileentitycontainer) {
331 346 + }
332 347 + container = CraftEventFactory.callInventoryOpenEvent(this, container, cancelled);
333 348 + if (container == null && !cancelled) { // Let pre-cancelled events fall through
334 349 + iinventory.closeContainer(this);
335 350 + return;
336 351 + }
337 352 + // CraftBukkit end
338 353 if (this.activeContainer != this.defaultContainer) {
339 354 this.closeInventory();
340 355 }
341 -@@ -510,9 +649,11 @@
356 +@@ -510,9 +663,11 @@
342 357 if (iinventory instanceof ITileInventory) {
343 358 ITileInventory itileinventory = (ITileInventory) iinventory;
344 359
345 360 - if (itileinventory.q_() && !this.a(itileinventory.i()) && !this.v()) {
346 361 + if (itileinventory.q_() && !this.a(itileinventory.i()) && !this.v() && container == null) { // CraftBukkit - allow plugins to uncancel the lock
347 362 this.playerConnection.sendPacket(new PacketPlayOutChat(new ChatMessage("container.isLocked", new Object[] { iinventory.getScoreboardDisplayName()}), (byte) 2));
348 363 this.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect("random.door_close", this.locX, this.locY, this.locZ, 1.0F, 1.0F));
349 364 +
350 365 + iinventory.closeContainer(this); // CraftBukkit
351 366 return;
352 367 }
353 368 }
354 -@@ -520,10 +661,10 @@
369 +@@ -520,10 +675,10 @@
355 370 this.nextContainerCounter();
356 371 if (iinventory instanceof ITileEntityContainer) {
357 372 this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, ((ITileEntityContainer) iinventory).getContainerName(), iinventory.getScoreboardDisplayName(), iinventory.getSize()));
358 373 - this.activeContainer = ((ITileEntityContainer) iinventory).createContainer(this.inventory, this);
359 374 + this.activeContainer = container; // CraftBukkit
360 375 } else {
361 376 this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, "minecraft:container", iinventory.getScoreboardDisplayName(), iinventory.getSize()));
362 377 - this.activeContainer = new ContainerChest(this.inventory, iinventory, this);
363 378 + this.activeContainer = container; // CraftBukkit
364 379 }
365 380
366 381 this.activeContainer.windowId = this.containerCounter;
367 -@@ -531,8 +672,14 @@
382 +@@ -531,8 +686,14 @@
368 383 }
369 384
370 385 public void openTrade(IMerchant imerchant) {
371 386 + // CraftBukkit start - Inventory open hook
372 387 + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerMerchant(this.inventory, imerchant, this.world));
373 388 + if (container == null) {
374 389 + return;
375 390 + }
376 391 + // CraftBukkit end
377 392 this.nextContainerCounter();
378 393 - this.activeContainer = new ContainerMerchant(this.inventory, imerchant, this.world);
379 394 + this.activeContainer = container; // CraftBukkit
380 395 this.activeContainer.windowId = this.containerCounter;
381 396 this.activeContainer.addSlotListener(this);
382 397 InventoryMerchant inventorymerchant = ((ContainerMerchant) this.activeContainer).e();
383 -@@ -552,13 +699,20 @@
398 +@@ -552,13 +713,20 @@
384 399 }
385 400
386 401 public void openHorseInventory(EntityHorse entityhorse, IInventory iinventory) {
387 402 + // CraftBukkit start - Inventory open hook
388 403 + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHorse(this.inventory, iinventory, entityhorse, this));
389 404 + if (container == null) {
390 405 + iinventory.closeContainer(this);
391 406 + return;
392 407 + }
393 408 + // CraftBukkit end
394 409 if (this.activeContainer != this.defaultContainer) {
395 410 this.closeInventory();
396 411 }
397 412
398 413 this.nextContainerCounter();
399 414 this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, "EntityHorse", iinventory.getScoreboardDisplayName(), iinventory.getSize(), entityhorse.getId()));
400 415 - this.activeContainer = new ContainerHorse(this.inventory, iinventory, entityhorse, this);
401 416 + this.activeContainer = container;
402 417 this.activeContainer.windowId = this.containerCounter;
403 418 this.activeContainer.addSlotListener(this);
404 419 }
405 -@@ -587,6 +741,11 @@
420 +@@ -587,6 +755,11 @@
406 421 public void a(Container container, List list) {
407 422 this.playerConnection.sendPacket(new PacketPlayOutWindowItems(container.windowId, list));
408 423 this.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.inventory.getCarried()));
409 424 + // CraftBukkit start - Send a Set Slot to update the crafting result slot
410 425 + if (java.util.EnumSet.of(InventoryType.CRAFTING,InventoryType.WORKBENCH).contains(container.getBukkitView().getType())) {
411 426 + this.playerConnection.sendPacket(new PacketPlayOutSetSlot(container.windowId, 0, container.getSlot(0).getItem()));
412 427 + }
413 428 + // CraftBukkit end
414 429 }
415 430
416 431 public void setContainerData(Container container, int i, int j) {
417 -@@ -601,6 +760,7 @@
432 +@@ -601,6 +774,7 @@
418 433 }
419 434
420 435 public void closeInventory() {
421 436 + CraftEventFactory.handleInventoryCloseEvent(this); // CraftBukkit
422 437 this.playerConnection.sendPacket(new PacketPlayOutCloseWindow(this.activeContainer.windowId));
423 438 this.p();
424 439 }
425 -@@ -681,7 +841,16 @@
440 +@@ -681,7 +855,16 @@
426 441
427 442 public void triggerHealthUpdate() {
428 443 this.bK = -1.0E8F;
429 444 + this.lastSentExp = -1; // CraftBukkit - Added to reset
430 445 + }
431 446 +
432 447 + // CraftBukkit start - Support multi-line messages
433 448 + public void sendMessage(IChatBaseComponent[] ichatbasecomponent) {
434 449 + for (IChatBaseComponent component : ichatbasecomponent) {
435 450 + this.sendMessage(component);
436 451 + }
437 452 }
438 453 + // CraftBukkit end
439 454
440 455 public void b(IChatBaseComponent ichatbasecomponent) {
441 456 this.playerConnection.sendPacket(new PacketPlayOutChat(ichatbasecomponent));
442 -@@ -747,6 +916,8 @@
457 +@@ -747,6 +930,8 @@
443 458 }
444 459
445 460 public void a(EnumGamemode enumgamemode) {
446 461 + getBukkitEntity().setGameMode(org.bukkit.GameMode.getByValue(enumgamemode.getId()));
447 462 + /* CraftBukkit start - defer to our setGameMode
448 463 this.playerInteractManager.setGameMode(enumgamemode);
449 464 this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(3, (float) enumgamemode.getId()));
450 465 if (enumgamemode == EnumGamemode.SPECTATOR) {
451 -@@ -757,6 +928,7 @@
466 +@@ -757,6 +942,7 @@
452 467
453 468 this.updateAbilities();
454 469 this.bO();
455 470 + // CraftBukkit end */
456 471 }
457 472
458 473 public boolean v() {
459 -@@ -768,6 +940,7 @@
474 +@@ -768,6 +954,7 @@
460 475 }
461 476
462 477 public boolean a(int i, String s) {
463 478 + /* CraftBukkit start
464 479 if ("seed".equals(s) && !this.server.ad()) {
465 480 return true;
466 481 } else if (!"tell".equals(s) && !"help".equals(s) && !"me".equals(s) && !"trigger".equals(s)) {
467 -@@ -781,6 +954,9 @@
482 +@@ -781,6 +968,9 @@
468 483 } else {
469 484 return true;
470 485 }
471 486 + */
472 487 + return true;
473 488 + // CraftBukkit end
474 489 }
475 490
476 491 public String w() {
477 -@@ -867,6 +1043,129 @@
492 +@@ -867,6 +1057,129 @@
478 493 }
479 494
480 495 public IChatBaseComponent getPlayerListName() {
481 496 - return null;
482 497 + return listName; // CraftBukkit
483 498 + }
484 499 +
485 500 + // CraftBukkit start - Add per-player time and weather.
486 501 + public long timeOffset = 0;
487 502 + public boolean relativeTime = true;

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut