@@ -355,6 +355,13 @@ public void a(PacketPlayInVehicleMove packetplayinvehiclemove) {
355
355
}
356
356
speed *= 2f ; // TODO: Get the speed of the vehicle instead of the player
357
357
358
+ // Paper start - Prevent moving into unloaded chunks
359
+ if (player .world .paperConfig .preventMovingIntoUnloadedChunks && !worldserver .isChunkLoaded ((int ) Math .floor (packetplayinvehiclemove .getX ()) >> 4 , (int ) Math .floor (packetplayinvehiclemove .getZ ()) >> 4 , false )) {
360
+ this .networkManager .sendPacket (new PacketPlayOutVehicleMove (entity ));
361
+ return ;
362
+ }
363
+ // Paper end
364
+
358
365
if (d10 - d9 > Math .max (100.0D , Math .pow ((double ) (org .spigotmc .SpigotConfig .movedTooQuicklyMultiplier * (float ) i * speed ), 2 )) && (!this .minecraftServer .R () || !this .minecraftServer .Q ().equals (entity .getName ()))) { // Spigot
359
366
// CraftBukkit end
360
367
PlayerConnection .LOGGER .warn ("{} (vehicle of {}) moved too quickly! {},{},{}" , entity .getName (), this .player .getName (), Double .valueOf (d6 ), Double .valueOf (d7 ), Double .valueOf (d8 ));
@@ -386,13 +393,13 @@ public void a(PacketPlayInVehicleMove packetplayinvehiclemove) {
386
393
}
387
394
388
395
entity .setLocation (d3 , d4 , d5 , f , f1 );
389
- Location curPos = getPlayer ().getLocation (); // Paper
390
- player .setLocation (d3 , d4 , d5 , f , f1 ); // Paper
396
+ Location curPos = getPlayer ().getLocation (); // Paper
397
+ player .setLocation (d3 , d4 , d5 , player . yaw , player . pitch ); // CraftBukkit // Paper
391
398
boolean flag2 = worldserver .getCubes (entity , entity .getBoundingBox ().shrink (0.0625D )).isEmpty ();
392
399
393
400
if (flag && (flag1 || !flag2 )) {
394
401
entity .setLocation (d0 , d1 , d2 , f , f1 );
395
- player .setLocation (d0 , d1 , d2 , f , f1 ); // Paper
402
+ player .setLocation (d3 , d4 , d5 , player . yaw , player . pitch ); // CraftBukkit // Paper
396
403
this .networkManager .sendPacket (new PacketPlayOutVehicleMove (entity ));
397
404
return ;
398
405
}
@@ -552,9 +559,9 @@ public void a(PacketPlayInFlying packetplayinflying) {
552
559
double d1 = this .player .locY ;
553
560
double d2 = this .player .locZ ;
554
561
double d3 = this .player .locY ;
555
- double d4 = packetplayinflying .a (this .player .locX );
562
+ double d4 = packetplayinflying .a (this .player .locX ); double toX = d4 ; // Paper - OBFHELPER
556
563
double d5 = packetplayinflying .b (this .player .locY );
557
- double d6 = packetplayinflying .c (this .player .locZ );
564
+ double d6 = packetplayinflying .c (this .player .locZ ); double toZ = d6 ; // Paper - OBFHELPER
558
565
float f = packetplayinflying .a (this .player .yaw );
559
566
float f1 = packetplayinflying .b (this .player .pitch );
560
567
double d7 = d4 - this .l ;
@@ -594,6 +601,13 @@ public void a(PacketPlayInFlying packetplayinflying) {
594
601
speed = player .abilities .walkSpeed * 10f ;
595
602
}
596
603
604
+ // Paper start - Prevent moving into unloaded chunks
605
+ if (player .world .paperConfig .preventMovingIntoUnloadedChunks && (this .player .locX != toX || this .player .locZ != toZ ) && !worldserver .isChunkLoaded ((int ) Math .floor (toX ) >> 4 , (int ) Math .floor (toZ ) >> 4 , false )) {
606
+ this .internalTeleport (this .player .locX , this .player .locY , this .player .locZ , this .player .yaw , this .player .pitch , Collections .emptySet ());
607
+ return ;
608
+ }
609
+ // Paper end
610
+
597
611
if (!this .player .L () && (!this .player .x ().getGameRules ().getBoolean ("disableElytraMovementCheck" ) || !this .player .cP ())) {
598
612
float f2 = this .player .cP () ? 300.0F : 100.0F ;
599
613
@@ -1695,7 +1709,7 @@ public void a(PacketPlayInUseEntity packetplayinuseentity) {
1695
1709
1696
1710
if (event .isCancelled () || this .player .inventory .getItemInHand () == null || this .player .inventory .getItemInHand ().getItem () != origItem ) {
1697
1711
// Refresh the current entity metadata
1698
- this . sendPacket (new PacketPlayOutEntityMetadata (entity .getId (), entity .datawatcher , true ));
1712
+ entity . tracker . broadcast (new PacketPlayOutEntityMetadata (entity .getId (), entity .datawatcher , true )); // Paper - update entity for all players
1699
1713
}
1700
1714
1701
1715
if (event .isCancelled ()) {
@@ -2232,7 +2246,7 @@ public void a(PacketPlayInUpdateSign packetplayinupdatesign) {
2232
2246
2233
2247
TileEntitySign tileentitysign = (TileEntitySign ) tileentity ;
2234
2248
2235
- if (!tileentitysign .a () || tileentitysign .e () != this .player ) {
2249
+ if (!tileentitysign .a () || tileentitysign .signEditor == null || ! tileentitysign . signEditor . equals ( this .player . getUniqueID ())) { // Paper
2236
2250
this .minecraftServer .warning ("Player " + this .player .getName () + " just tried to change non-editable sign" );
2237
2251
this .sendPacket (tileentity .getUpdatePacket ()); // CraftBukkit
2238
2252
return ;
@@ -2248,6 +2262,14 @@ public void a(PacketPlayInUpdateSign packetplayinupdatesign) {
2248
2262
String [] lines = new String [4 ];
2249
2263
2250
2264
for (int i = 0 ; i < astring .length ; ++i ) {
2265
+ // Paper start - cap line length - modified clients can send longer data than normal
2266
+ if (astring [i ].length () > TileEntitySign .MAX_SIGN_LINE_LENGTH && TileEntitySign .MAX_SIGN_LINE_LENGTH > 0 ) {
2267
+ int offset = astring [i ].codePoints ().limit (TileEntitySign .MAX_SIGN_LINE_LENGTH ).map (Character ::charCount ).sum ();
2268
+ if (offset > astring .length ) {
2269
+ astring [i ] = astring [i ].substring (0 , offset );
2270
+ }
2271
+ }
2272
+ // Paper end
2251
2273
lines [i ] = SharedConstants .a (astring [i ]); //Paper - Replaced with anvil color stripping method to stop exploits that allow colored signs to be created.
2252
2274
}
2253
2275
SignChangeEvent event = new SignChangeEvent ((org .bukkit .craftbukkit .block .CraftBlock ) player .getWorld ().getBlockAt (x , y , z ), this .server .getPlayer (this .player ), lines );
@@ -2350,6 +2372,45 @@ public void a(PacketPlayInSettings packetplayinsettings) {
2350
2372
this .player .a (packetplayinsettings );
2351
2373
}
2352
2374
2375
+ // Paper start
2376
+ private boolean validateBook (ItemStack testStack ) {
2377
+ NBTTagList pageList = testStack .getTag ().getList ("pages" , 8 );
2378
+ long byteTotal = 0 ;
2379
+ int maxBookPageSize = com .destroystokyo .paper .PaperConfig .maxBookPageSize ;
2380
+ double multiplier = Math .max (0.3D , Math .min (1D , com .destroystokyo .paper .PaperConfig .maxBookTotalSizeMultiplier ));
2381
+ long byteAllowed = maxBookPageSize ;
2382
+ for (int i = 0 ; i < pageList .size (); ++i ) {
2383
+ String testString = pageList .getString (i );
2384
+ int byteLength = testString .getBytes (java .nio .charset .StandardCharsets .UTF_8 ).length ;
2385
+ byteTotal += byteLength ;
2386
+
2387
+ int length = testString .length ();
2388
+ int multibytes = 0 ;
2389
+ if (length != byteLength ) {
2390
+ for (char c : testString .toCharArray ()) {
2391
+ if (c > 127 ) {
2392
+ multibytes ++;
2393
+ }
2394
+ }
2395
+ }
2396
+ byteAllowed += (maxBookPageSize * Math .min (1 , Math .max (0.1D , (double ) length / 255D ))) * multiplier ;
2397
+
2398
+ if (multibytes > 1 ) {
2399
+ // penalize MB
2400
+ byteAllowed -= multibytes ;
2401
+ }
2402
+ }
2403
+
2404
+ if (byteTotal > byteAllowed ) {
2405
+ PlayerConnection .LOGGER .warn (this .player .getName () + " tried to send too large of a book. Book Size: " + byteTotal + " - Allowed: " + byteAllowed + " - Pages: " + pageList .size ());
2406
+ minecraftServer .postToMainThread (() -> this .disconnect ("Book too large!" ));
2407
+ return false ;
2408
+ }
2409
+
2410
+ return true ;
2411
+ }
2412
+ // Paper end
2413
+
2353
2414
public void a (PacketPlayInCustomPayload packetplayincustompayload ) {
2354
2415
PlayerConnectionUtils .ensureMainThread (packetplayincustompayload , this , this .player .x ());
2355
2416
String s = packetplayincustompayload .a ();
@@ -2383,6 +2444,7 @@ public void a(PacketPlayInCustomPayload packetplayincustompayload) {
2383
2444
}
2384
2445
2385
2446
if (itemstack .getItem () == Items .WRITABLE_BOOK && itemstack .getItem () == itemstack1 .getItem ()) {
2447
+ if (!validateBook (itemstack )) return ; // Paper
2386
2448
itemstack1 .a ("pages" , (NBTBase ) itemstack .getTag ().getList ("pages" , 8 ));
2387
2449
CraftEventFactory .handleEditBookEvent (player , itemstack1 ); // CraftBukkit
2388
2450
}
@@ -2418,6 +2480,7 @@ public void a(PacketPlayInCustomPayload packetplayincustompayload) {
2418
2480
}
2419
2481
2420
2482
if (itemstack .getItem () == Items .WRITABLE_BOOK && itemstack1 .getItem () == Items .WRITABLE_BOOK ) {
2483
+ if (!validateBook (itemstack )) return ; // Paper
2421
2484
ItemStack itemstack2 = new ItemStack (Items .WRITTEN_BOOK );
2422
2485
2423
2486
itemstack2 .a ("author" , (NBTBase ) (new NBTTagString (this .player .getName ())));
0 commit comments