Packet obfuscation and reduction
This commit is contained in:
@@ -5,10 +5,10 @@ Subject: [PATCH] Build Changes
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||||
index d80cfcb94db51440b5d0aa589a9a3d8a4189a9aa..9dbad4407dcf1a7070d5c5a692473cf57a4543e7 100644
|
index cb1a931417073908be5c7aa1af710477775b3dbd..0c3c936990f161eb3de9a33f8983e4da571befac 100644
|
||||||
--- a/build.gradle.kts
|
--- a/build.gradle.kts
|
||||||
+++ b/build.gradle.kts
|
+++ b/build.gradle.kts
|
||||||
@@ -29,8 +29,8 @@ repositories {
|
@@ -28,8 +28,8 @@ repositories {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -19,7 +19,7 @@ index d80cfcb94db51440b5d0aa589a9a3d8a4189a9aa..9dbad4407dcf1a7070d5c5a692473cf5
|
|||||||
// Paper start
|
// Paper start
|
||||||
implementation("org.jline:jline-terminal-jansi:3.12.1")
|
implementation("org.jline:jline-terminal-jansi:3.12.1")
|
||||||
implementation("net.minecrell:terminalconsoleappender:1.2.0")
|
implementation("net.minecrell:terminalconsoleappender:1.2.0")
|
||||||
@@ -82,7 +82,7 @@ tasks.jar {
|
@@ -81,7 +81,7 @@ tasks.jar {
|
||||||
attributes(
|
attributes(
|
||||||
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
||||||
"Implementation-Title" to "CraftBukkit",
|
"Implementation-Title" to "CraftBukkit",
|
||||||
@@ -28,7 +28,7 @@ index d80cfcb94db51440b5d0aa589a9a3d8a4189a9aa..9dbad4407dcf1a7070d5c5a692473cf5
|
|||||||
"Implementation-Vendor" to date, // Paper
|
"Implementation-Vendor" to date, // Paper
|
||||||
"Specification-Title" to "Bukkit",
|
"Specification-Title" to "Bukkit",
|
||||||
"Specification-Version" to project.version,
|
"Specification-Version" to project.version,
|
||||||
@@ -207,7 +207,7 @@ tasks.test {
|
@@ -206,7 +206,7 @@ tasks.test {
|
||||||
fun TaskContainer.registerRunTask(
|
fun TaskContainer.registerRunTask(
|
||||||
name: String, block: JavaExec.() -> Unit
|
name: String, block: JavaExec.() -> Unit
|
||||||
): TaskProvider<JavaExec> = register<JavaExec>(name) {
|
): TaskProvider<JavaExec> = register<JavaExec>(name) {
|
||||||
@@ -51,10 +51,10 @@ index fe6d5051b139cd6079e288ffdf20e30fdd46fdda..c3c2b44c998ccb73594e4f33a571508a
|
|||||||
|
|
||||||
public SystemReport fillSystemReport(SystemReport details) {
|
public SystemReport fillSystemReport(SystemReport details) {
|
||||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||||
index f925130552cb4ff2f813b1ddae9ac2f915e17bd5..7df81489dd9d3c7ed84b3b6bdf2b724903fbcdc4 100644
|
index 0adb686d690e1be0c5540625efbecc46bac5d045..d32b296d63e8f16ad4ba6e5e8da259d2905098ef 100644
|
||||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||||
@@ -249,7 +249,7 @@ import javax.annotation.Nullable; // Paper
|
@@ -251,7 +251,7 @@ import javax.annotation.Nullable; // Paper
|
||||||
import javax.annotation.Nonnull; // Paper
|
import javax.annotation.Nonnull; // Paper
|
||||||
|
|
||||||
public final class CraftServer implements Server {
|
public final class CraftServer implements Server {
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ index 21d1e0c9c471e9e556b5bd70166a769b46105c7a..d46dc12001bd46596c3bb2e24144bbe4
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||||
index b93056b91e7ebd49e6ddb53ccb6c05c056088df9..a9315b7acec3c2ccaf879e0f1d45c062d8e201b1 100644
|
index f936e9f9a9fa655fa997d6862b5ed54c04169d35..465a1e179f6ae43d253d692255c8fe144179efe3 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||||
@@ -550,12 +550,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
@@ -552,12 +552,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -46,7 +46,7 @@ index b93056b91e7ebd49e6ddb53ccb6c05c056088df9..a9315b7acec3c2ccaf879e0f1d45c062
|
|||||||
// CraftBukkit start - tree generation
|
// CraftBukkit start - tree generation
|
||||||
if (this.captureTreeGeneration) {
|
if (this.captureTreeGeneration) {
|
||||||
// Paper start
|
// Paper start
|
||||||
@@ -602,7 +602,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
@@ -604,7 +604,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||||
} else {
|
} else {
|
||||||
BlockState iblockdata2 = this.getBlockState(pos);
|
BlockState iblockdata2 = this.getBlockState(pos);
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ index b93056b91e7ebd49e6ddb53ccb6c05c056088df9..a9315b7acec3c2ccaf879e0f1d45c062
|
|||||||
this.getProfiler().push("queueCheckLight");
|
this.getProfiler().push("queueCheckLight");
|
||||||
this.getChunkSource().getLightEngine().checkBlock(pos);
|
this.getChunkSource().getLightEngine().checkBlock(pos);
|
||||||
this.getProfiler().pop();
|
this.getProfiler().pop();
|
||||||
@@ -749,7 +749,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
@@ -751,7 +751,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||||
Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY);
|
Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ index 3e5e358e24bd84a05785a9391526f316475e95ff..9914a92040a63b6102eb6171f058ea1c
|
|||||||
CompoundTag newData = this.getTagClone();
|
CompoundTag newData = this.getTagClone();
|
||||||
int newCount = this.getCount();
|
int newCount = this.getCount();
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||||
index a9315b7acec3c2ccaf879e0f1d45c062d8e201b1..7dec61b831860e372f1785c2ae838cb3ad2fc623 100644
|
index 465a1e179f6ae43d253d692255c8fe144179efe3..46a1b0519aaccc2b5625104d42168254bfb27cd9 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||||
@@ -175,6 +175,27 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
@@ -176,6 +176,27 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||||
public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
|
public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
|
||||||
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
|
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ index a9315b7acec3c2ccaf879e0f1d45c062d8e201b1..7dec61b831860e372f1785c2ae838cb3
|
|||||||
// Paper start - fix and optimise world upgrading
|
// Paper start - fix and optimise world upgrading
|
||||||
// copied from below
|
// copied from below
|
||||||
public static ResourceKey<DimensionType> getDimensionKey(DimensionType manager) {
|
public static ResourceKey<DimensionType> getDimensionKey(DimensionType manager) {
|
||||||
@@ -704,6 +725,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
@@ -706,6 +727,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||||
if (!this.preventPoiUpdated) {
|
if (!this.preventPoiUpdated) {
|
||||||
this.onBlockStateChange(blockposition, iblockdata1, iblockdata2);
|
this.onBlockStateChange(blockposition, iblockdata1, iblockdata2);
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ index a9315b7acec3c2ccaf879e0f1d45c062d8e201b1..7dec61b831860e372f1785c2ae838cb3
|
|||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -809,8 +831,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
@@ -811,8 +833,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||||
public void neighborChanged(BlockPos pos, Block sourceBlock, BlockPos neighborPos) {
|
public void neighborChanged(BlockPos pos, Block sourceBlock, BlockPos neighborPos) {
|
||||||
if (!this.isClientSide) {
|
if (!this.isClientSide) {
|
||||||
BlockState iblockdata = this.getBlockState(pos);
|
BlockState iblockdata = this.getBlockState(pos);
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Add BlockDestroyedByNeighborEvent
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||||
index 7dec61b831860e372f1785c2ae838cb3ad2fc623..9b704693ea8d8677d3c25d5a3c08d4ef26aa1fc3 100644
|
index 46a1b0519aaccc2b5625104d42168254bfb27cd9..5e87676aa9dfa26ac052aa0c1fce35b8822e7a50 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||||
@@ -747,6 +747,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
@@ -749,6 +749,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||||
if (iblockdata.isAir()) {
|
if (iblockdata.isAir()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
217
patches/server/0013-Packet-obfuscation-and-reduction.patch
Normal file
217
patches/server/0013-Packet-obfuscation-and-reduction.patch
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Cryptite <cryptite@gmail.com>
|
||||||
|
Date: Wed, 6 Oct 2021 11:03:01 -0500
|
||||||
|
Subject: [PATCH] Packet obfuscation and reduction
|
||||||
|
|
||||||
|
Minecraft is overzealous about packet updates for Entities. In Loka's case, we want to reduce as many unnecessary
|
||||||
|
packet updates as possible. This patch is likely to be updated over and over in terms of reducing packet sends.
|
||||||
|
|
||||||
|
In summary, this patch creates the concept of a "foreignValue" of a packet's data. We treat packets in two ways:
|
||||||
|
1) The packet sent to the player itself (the normal way). This always has all of the values as usual.
|
||||||
|
2) The packet data as seen by any other (foreign) players.
|
||||||
|
|
||||||
|
This patch adds the ability to set a "foreignValue" for an entity value so as to obfuscate data received by other players.
|
||||||
|
The current packets modified/obfuscated are the following:
|
||||||
|
|
||||||
|
- Health - Foreign Players will only receive packets that say the player is "alive or dead (max health or 0 health).
|
||||||
|
-- This reduces the amount of health packet updates as well which is great for players in combat.
|
||||||
|
|
||||||
|
- Air Level - Foreign players will only ever see a player as having full oxygen
|
||||||
|
-- Air level packets are sent PER-TICK, and as such a player with any change in air level will only spam themselves
|
||||||
|
with packets instead of every single player within tracking distance
|
||||||
|
|
||||||
|
- Score - Foreign players will only see a player's score as 0 and will not update due to gathering xp orbs, etc.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||||
|
index 3e17f6131bf590d7c4a16b79c1c145cb4f565bc9..e1233fa58d068448d0accef7a7f6725fcb902848 100644
|
||||||
|
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||||
|
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||||
|
@@ -22,6 +22,13 @@ public class ClientboundSetEntityDataPacket implements Packet<ClientGamePacketLi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Slice start
|
||||||
|
+ public ClientboundSetEntityDataPacket(int id, List<SynchedEntityData.DataItem<?>> packedItems) {
|
||||||
|
+ this.id = id;
|
||||||
|
+ this.packedItems = packedItems;
|
||||||
|
+ }
|
||||||
|
+ // Slice end
|
||||||
|
+
|
||||||
|
public ClientboundSetEntityDataPacket(FriendlyByteBuf buf) {
|
||||||
|
this.id = buf.readVarInt();
|
||||||
|
this.packedItems = SynchedEntityData.unpack(buf);
|
||||||
|
diff --git a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
||||||
|
index 4df12454001f0de5f358c88d876e34c35a736c42..72c74d2369a36b14f1103aa74b096f50e7990f4d 100644
|
||||||
|
--- a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
||||||
|
+++ b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
||||||
|
@@ -136,6 +136,11 @@ public class SynchedEntityData {
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void set(EntityDataAccessor<T> key, T value) {
|
||||||
|
+ //Slice start
|
||||||
|
+ set(key, value, null);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public <T> void set(EntityDataAccessor<T> key, T value, @Nullable T foreignValue) { // Slice end
|
||||||
|
SynchedEntityData.DataItem<T> datawatcher_item = this.getItem(key);
|
||||||
|
|
||||||
|
if (ObjectUtils.notEqual(value, datawatcher_item.getValue())) {
|
||||||
|
@@ -145,6 +150,11 @@ public class SynchedEntityData {
|
||||||
|
this.isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Slice start
|
||||||
|
+ if (foreignValue != null && ObjectUtils.notEqual(foreignValue, datawatcher_item.getForeignValue())) {
|
||||||
|
+ datawatcher_item.setForeignValue(foreignValue);
|
||||||
|
+ }
|
||||||
|
+ // Slice end
|
||||||
|
}
|
||||||
|
|
||||||
|
// CraftBukkit start - add method from above
|
||||||
|
@@ -200,6 +210,28 @@ public class SynchedEntityData {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Slice start
|
||||||
|
+ @Nullable
|
||||||
|
+ public List<SynchedEntityData.DataItem<?>> packForeignDirty(List<DataItem<?>> unpackedData) {
|
||||||
|
+ List<SynchedEntityData.DataItem<?>> list = null;
|
||||||
|
+
|
||||||
|
+ for (DataItem<?> dataItem : unpackedData) {
|
||||||
|
+ DataItem<?> item = itemsById.get(dataItem.accessor.getId());
|
||||||
|
+ if (item.isDirty(true)) {
|
||||||
|
+ item.setForeignDirty(false);
|
||||||
|
+
|
||||||
|
+ if (list == null) {
|
||||||
|
+ list = Lists.newArrayList();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ list.add(item.copy(true));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return list;
|
||||||
|
+ }
|
||||||
|
+ // Slice end
|
||||||
|
+
|
||||||
|
@Nullable
|
||||||
|
public List<SynchedEntityData.DataItem<?>> getAll() {
|
||||||
|
List<SynchedEntityData.DataItem<?>> list = null;
|
||||||
|
@@ -313,11 +345,14 @@ public class SynchedEntityData {
|
||||||
|
final EntityDataAccessor<T> accessor;
|
||||||
|
T value;
|
||||||
|
private boolean dirty;
|
||||||
|
+ @Nullable T foreignValue = null; // Slice
|
||||||
|
+ private boolean foreignDirty; // Slice
|
||||||
|
|
||||||
|
public DataItem(EntityDataAccessor<T> data, T value) {
|
||||||
|
this.accessor = data;
|
||||||
|
this.value = value;
|
||||||
|
this.dirty = true;
|
||||||
|
+ this.foreignDirty = true; // Slice
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityDataAccessor<T> getAccessor() {
|
||||||
|
@@ -343,5 +378,34 @@ public class SynchedEntityData {
|
||||||
|
public SynchedEntityData.DataItem<T> copy() {
|
||||||
|
return new SynchedEntityData.DataItem<>(this.accessor, this.accessor.getSerializer().copy(this.value));
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Slice start
|
||||||
|
+ public void setForeignValue(T foreignValue) {
|
||||||
|
+ this.foreignValue = foreignValue;
|
||||||
|
+ this.foreignDirty = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public @Nullable T getForeignValue() {
|
||||||
|
+ return foreignValue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public boolean isDirty(boolean foreign) {
|
||||||
|
+ if (foreign) {
|
||||||
|
+ //There must be a foreign value in order for this to be dirty, otherwise we consider this a normal
|
||||||
|
+ //value and check the normal dirty flag.
|
||||||
|
+ return foreignValue == null || this.foreignDirty;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return this.dirty;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public void setForeignDirty(boolean dirty) {
|
||||||
|
+ this.foreignDirty = dirty;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public SynchedEntityData.DataItem<T> copy(boolean foreign) {
|
||||||
|
+ return new SynchedEntityData.DataItem<>(this.accessor, this.accessor.getSerializer().copy((foreign && this.foreignValue != null ? this.foreignValue : this.value)));
|
||||||
|
+ }
|
||||||
|
+ // Slice end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||||
|
index b7c9294fdd3d799d410afba4a1118aa371c98533..b5205bfc6f9834dc811df71bfb96494448c8dfed 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||||
|
@@ -368,7 +368,21 @@ public class ServerEntity {
|
||||||
|
SynchedEntityData datawatcher = this.entity.getEntityData();
|
||||||
|
|
||||||
|
if (datawatcher.isDirty()) {
|
||||||
|
- this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), datawatcher, false));
|
||||||
|
+ // Slice start
|
||||||
|
+ ClientboundSetEntityDataPacket dataPacket = new ClientboundSetEntityDataPacket(this.entity.getId(), datawatcher, false);
|
||||||
|
+ if (this.entity instanceof ServerPlayer serverPlayer) {
|
||||||
|
+ serverPlayer.connection.send(dataPacket);
|
||||||
|
+
|
||||||
|
+ //Get the packedData that the original packet has, and then determine if any of those are changed in
|
||||||
|
+ //the foreign version. If null, nothing to notify foreign trackers about.
|
||||||
|
+ List<SynchedEntityData.DataItem<?>> dirtyItems = datawatcher.packForeignDirty(dataPacket.getUnpackedData());
|
||||||
|
+ if (dirtyItems != null) {
|
||||||
|
+ this.broadcast(new ClientboundSetEntityDataPacket(this.entity.getId(), dirtyItems));
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ this.broadcastAndSend(dataPacket);
|
||||||
|
+ }
|
||||||
|
+ // Slice end
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.entity instanceof LivingEntity) {
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||||
|
index 049a9ba9cc96880513e681f7d29bd5f9681fbb0e..37836b6f9b39ab1dcbfa1e4dea90e4d12fc9e5b9 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||||
|
@@ -2944,7 +2944,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
- this.entityData.set(Entity.DATA_AIR_SUPPLY_ID, event.getAmount());
|
||||||
|
+ this.entityData.set(Entity.DATA_AIR_SUPPLY_ID, event.getAmount(), getMaxAirSupply()); // Slice
|
||||||
|
// CraftBukkit end
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||||
|
index 4a35056b01b947c57f7ca06c974463008fc4bbef..80a8ea35b47cc649f435856cad19a80d69da8425 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||||
|
@@ -633,7 +633,7 @@ public abstract class Player extends LivingEntity {
|
||||||
|
public void increaseScore(int score) {
|
||||||
|
int j = this.getScore();
|
||||||
|
|
||||||
|
- this.entityData.set(Player.DATA_SCORE_ID, j + score);
|
||||||
|
+ this.entityData.set(Player.DATA_SCORE_ID, j + score, 0); // Slice
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||||
|
index c64911651f3d736c83cc83996de04920b091cc57..cf8d4edba400d5f21737c0af52a1193f69386fa9 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||||
|
@@ -1997,7 +1997,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||||
|
this.sendHealthUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- this.getHandle().getEntityData().set(LivingEntity.DATA_HEALTH_ID, (float) this.getScaledHealth());
|
||||||
|
+ this.getHandle().getEntityData().set(LivingEntity.DATA_HEALTH_ID, (float) this.getScaledHealth(), isDead() ? 0f : 20f); // Slice
|
||||||
|
|
||||||
|
this.getHandle().maxHealthCache = getMaxHealth();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user