559 lines
27 KiB
Diff
559 lines
27 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Etil <81570777+etil2jz@users.noreply.github.com>
|
|
Date: Fri, 12 Nov 2021 21:43:06 +0100
|
|
Subject: [PATCH] Slice Patches
|
|
|
|
|
|
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..6029102a2e3631d563b5f1846bc2eab8268c9ac6 100644
|
|
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
|
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
|
@@ -21,6 +21,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();
|
|
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
|
index 4c9660176e783999301565790b8cf6f47b0d02a2..2741e4f58ab0c239f791d00aa813cde4d378feea 100644
|
|
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
|
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
|
@@ -41,6 +41,12 @@ public class ClientboundSetPlayerTeamPacket implements Packet<ClientGamePacketLi
|
|
public static ClientboundSetPlayerTeamPacket createPlayerPacket(PlayerTeam team, String playerName, ClientboundSetPlayerTeamPacket.Action operation) {
|
|
return new ClientboundSetPlayerTeamPacket(team.getName(), operation == ClientboundSetPlayerTeamPacket.Action.ADD ? 3 : 4, Optional.empty(), ImmutableList.of(playerName));
|
|
}
|
|
+
|
|
+ // Slice start
|
|
+ public static ClientboundSetPlayerTeamPacket createMultiplePlayerPacket(PlayerTeam team, Collection<String> players, ClientboundSetPlayerTeamPacket.Action operation) {
|
|
+ return new ClientboundSetPlayerTeamPacket(team.getName(), operation == ClientboundSetPlayerTeamPacket.Action.ADD ? 3 : 4, Optional.empty(), players);
|
|
+ }
|
|
+ // Slice end
|
|
|
|
public ClientboundSetPlayerTeamPacket(FriendlyByteBuf buf) {
|
|
this.name = buf.readUtf(16);
|
|
diff --git a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
|
index 4df12454001f0de5f358c88d876e34c35a736c42..a26f3538e286407f655f075f6aa63033b3b748c6 100644
|
|
--- a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
|
+++ b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
|
@@ -136,6 +136,12 @@ 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())) {
|
|
@@ -144,7 +150,12 @@ public class SynchedEntityData {
|
|
datawatcher_item.setDirty(true);
|
|
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
|
|
@@ -199,6 +210,28 @@ public class SynchedEntityData {
|
|
this.isDirty = false;
|
|
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() {
|
|
@@ -313,11 +346,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 +379,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/ServerScoreboard.java b/src/main/java/net/minecraft/server/ServerScoreboard.java
|
|
index 130a928f156961bae9ca184b3ca31004dbba1012..063e4f9f140a39c519b1d4892bfa331d1265755c 100644
|
|
--- a/src/main/java/net/minecraft/server/ServerScoreboard.java
|
|
+++ b/src/main/java/net/minecraft/server/ServerScoreboard.java
|
|
@@ -3,6 +3,7 @@ package net.minecraft.server;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Sets;
|
|
import java.util.Iterator;
|
|
+import java.util.Collection; // Slice
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.Set;
|
|
@@ -91,6 +92,19 @@ public class ServerScoreboard extends Scoreboard {
|
|
return false;
|
|
}
|
|
}
|
|
+
|
|
+ // Slice start
|
|
+ @Override
|
|
+ public boolean addPlayersToTeam(Collection<String> players, PlayerTeam team) {
|
|
+ if (super.addPlayersToTeam(players, team)) {
|
|
+ this.sendAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.ADD));
|
|
+ this.setDirty();
|
|
+ return true;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ // Slice end
|
|
|
|
@Override
|
|
public void removePlayerFromTeam(String playerName, PlayerTeam team) {
|
|
@@ -98,6 +112,19 @@ public class ServerScoreboard extends Scoreboard {
|
|
this.sendAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(team, playerName, ClientboundSetPlayerTeamPacket.Action.REMOVE));
|
|
this.setDirty();
|
|
}
|
|
+
|
|
+ // Slice start
|
|
+ @Override
|
|
+ public boolean removePlayersFromTeam(Collection<String> players, PlayerTeam team) {
|
|
+ if (super.removePlayersFromTeam(players, team)) {
|
|
+ this.sendAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.REMOVE));
|
|
+ this.setDirty();
|
|
+ return true;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ // Slice end
|
|
|
|
@Override
|
|
public void onObjectiveAdded(Objective objective) {
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
|
index 96b11907d99e058041e81a29f8727465e3fa6723..0a3edd5c6a3ef8341855d138dadf24e6db09e54d 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
|
@@ -387,7 +387,19 @@ 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));
|
|
+ }
|
|
+ // Slice end
|
|
}
|
|
|
|
if (this.entity instanceof LivingEntity) {
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
index 1ae7a10df7460f223413c38ac6bd85dba15fb347..e9fb961f20486f522a679e35d1fe4c586e379420 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
@@ -200,6 +200,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
|
public final UUID uuid;
|
|
public boolean hasPhysicsEvent = true; // Paper
|
|
public boolean hasEntityMoveEvent = false; // Paper
|
|
+ public boolean instance; // Slice
|
|
public static Throwable getAddToWorldStackTrace(Entity entity) {
|
|
return new Throwable(entity + " Added to world at " + new java.util.Date());
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
index 24a8c047b717c26b6efb4cd67c061527bc6c9cd4..def69c8b959f859952d7f1d1443f1e4c17843bfb 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
@@ -263,6 +263,7 @@ public class ServerPlayer extends Player {
|
|
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
|
|
public boolean needsChunkCenterUpdate; // Paper - no-tick view distance // Paper - public
|
|
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - there are a lot of changes to do if we change all methods leading to the event
|
|
+ public boolean smoothWorldTeleport; // Slice
|
|
|
|
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile) {
|
|
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
|
|
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
index 4caef00726f3e421cec2ef955c3db8d074348c49..370af31206bb1cd9fa50541a95baa7a12aec8cd0 100644
|
|
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
@@ -952,11 +952,11 @@ public abstract class PlayerList {
|
|
}
|
|
// CraftBukkit start
|
|
LevelData worlddata = worldserver1.getLevelData();
|
|
- entityplayer1.connection.send(new ClientboundRespawnPacket(worldserver1.dimensionType(), worldserver1.dimension(), BiomeManager.obfuscateSeed(worldserver1.getSeed()), entityplayer1.gameMode.getGameModeForPlayer(), entityplayer1.gameMode.getPreviousGameModeForPlayer(), worldserver1.isDebug(), worldserver1.isFlat(), flag));
|
|
+ if (!entityplayer.smoothWorldTeleport) entityplayer1.connection.send(new ClientboundRespawnPacket(worldserver1.dimensionType(), worldserver1.dimension(), BiomeManager.obfuscateSeed(worldserver1.getSeed()), entityplayer1.gameMode.getGameModeForPlayer(), entityplayer1.gameMode.getPreviousGameModeForPlayer(), worldserver1.isDebug(), worldserver1.isFlat(), flag));
|
|
entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.getChunkSource().chunkMap.playerChunkManager.getLoadDistance())); // Spigot // Paper - no-tick view distance// Paper - replace old player chunk management
|
|
entityplayer1.setLevel(worldserver1);
|
|
entityplayer1.unsetRemoved();
|
|
- entityplayer1.connection.teleport(new Location(worldserver1.getWorld(), entityplayer1.getX(), entityplayer1.getY(), entityplayer1.getZ(), entityplayer1.getYRot(), entityplayer1.getXRot()));
|
|
+ if (!entityplayer.smoothWorldTeleport) entityplayer1.connection.teleport(new Location(worldserver1.getWorld(), entityplayer1.getX(), entityplayer1.getY(), entityplayer1.getZ(), entityplayer1.getYRot(), entityplayer1.getXRot()));
|
|
entityplayer1.setShiftKeyDown(false);
|
|
|
|
// entityplayer1.connection.b(entityplayer1.locX(), entityplayer1.locY(), entityplayer1.locZ(), entityplayer1.getYRot(), entityplayer1.getXRot());
|
|
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
index 4e5a8be29816b96ce1738e6cedffd99b00909036..2c0ca9194e8ad3b53776455db54cca16dc1095e4 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
@@ -787,7 +787,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
|
|
|
this.checkOutOfWorld();
|
|
if (!this.level.isClientSide) {
|
|
- this.setSharedFlagOnFire(this.remainingFireTicks > 0);
|
|
+ if (this instanceof net.minecraft.world.entity.LivingEntity livingEntity) {
|
|
+ this.setSharedFlagOnFire(this.remainingFireTicks > 0 && !livingEntity.hasEffect(net.minecraft.world.effect.MobEffects.FIRE_RESISTANCE));
|
|
+ } else {
|
|
+ this.setSharedFlagOnFire(this.remainingFireTicks > 0);
|
|
+ }
|
|
}
|
|
|
|
this.firstTick = false;
|
|
@@ -2969,7 +2973,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/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
index 8576d7f4acba258a9d42218e7d50cc3067236b52..82678fd59a4a49cca6e5a90b850197d93d5fa18f 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
@@ -3024,7 +3024,7 @@ public abstract class LivingEntity extends Entity {
|
|
|
|
ItemStack itemstack1 = this.getItemBySlot(enumitemslot);
|
|
|
|
- if (!ItemStack.matches(itemstack1, itemstack)) {
|
|
+ if (!ItemStack.isSameIgnoreDurability(itemstack1, itemstack)) {
|
|
// Paper start - PlayerArmorChangeEvent
|
|
if (this instanceof ServerPlayer && enumitemslot.getType() == EquipmentSlot.Type.ARMOR) {
|
|
final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack);
|
|
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 94e76e295dbd0f3bac4b30a3e7338cd56a971207..4484c6dc092f5fc8e1a33b0e7096f618e45df879 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/net/minecraft/world/level/biome/MobSpawnSettings.java b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
|
|
index 86528ff031014e788d72a8bf7c1c9443512096bb..51d3557db8caa9852ec2627ab53d802be2b59745 100644
|
|
--- a/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
|
|
+++ b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
|
|
@@ -41,9 +41,10 @@ public class MobSpawnSettings {
|
|
}), Codec.BOOL.fieldOf("player_spawn_friendly").orElse(false).forGetter(MobSpawnSettings::playerSpawnFriendly)).apply(instance, MobSpawnSettings::new);
|
|
});
|
|
private final float creatureGenerationProbability;
|
|
- private final Map<MobCategory, WeightedRandomList<MobSpawnSettings.SpawnerData>> spawners;
|
|
- private final Map<EntityType<?>, MobSpawnSettings.MobSpawnCost> mobSpawnCosts;
|
|
+ private Map<MobCategory, WeightedRandomList<MobSpawnSettings.SpawnerData>> spawners; // Slice
|
|
+ private Map<EntityType<?>, MobSpawnSettings.MobSpawnCost> mobSpawnCosts; // Slice
|
|
private final boolean playerSpawnFriendly;
|
|
+ private boolean stripped; // Slice
|
|
|
|
MobSpawnSettings(float creatureSpawnProbability, Map<MobCategory, WeightedRandomList<MobSpawnSettings.SpawnerData>> spawners, Map<EntityType<?>, MobSpawnSettings.MobSpawnCost> spawnCosts, boolean playerSpawnFriendly) {
|
|
this.creatureGenerationProbability = creatureSpawnProbability;
|
|
@@ -51,13 +52,50 @@ public class MobSpawnSettings {
|
|
this.mobSpawnCosts = ImmutableMap.copyOf(spawnCosts);
|
|
this.playerSpawnFriendly = playerSpawnFriendly;
|
|
}
|
|
+
|
|
+ // Slice start
|
|
+ // This very stupid thing is because Mob Spawning Biome data is statically registered before CraftServer
|
|
+ // is even created. As a result, we need to lazily rebuild our spawning data here which is very cool and very
|
|
+ // stupid. But it should only really happen once up front, so isn't the end of the world
|
|
+ private void stripSpawnData() {
|
|
+ if (wtf.etil.mirai.MiraiConfig.globalBlockedMobSpawnTypes.isEmpty()) {
|
|
+ stripped = true;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ Map<EntityType<?>, MobSpawnSettings.MobSpawnCost> finalMobSpawnCosts = new java.util.HashMap<>();
|
|
+ for (Entry<EntityType<?>, MobSpawnSettings.MobSpawnCost> entry : mobSpawnCosts.entrySet()) {
|
|
+ if (!wtf.etil.mirai.MiraiConfig.globalBlockedMobSpawnTypes.contains(entry.getKey())) {
|
|
+ finalMobSpawnCosts.put(entry.getKey(), entry.getValue());
|
|
+ }
|
|
+ }
|
|
+ this.mobSpawnCosts = ImmutableMap.copyOf(finalMobSpawnCosts);
|
|
+
|
|
+ Map<MobCategory, WeightedRandomList<MobSpawnSettings.SpawnerData>> finalSpawners = new java.util.HashMap<>();
|
|
+ for (Entry<MobCategory, WeightedRandomList<SpawnerData>> entry : spawners.entrySet()) {
|
|
+ List<SpawnerData> finalSpawnerData = new java.util.ArrayList<>();
|
|
+ for (SpawnerData spawnerData : entry.getValue().unwrap()) {
|
|
+ if (!wtf.etil.mirai.MiraiConfig.globalBlockedMobSpawnTypes.contains(spawnerData.type)) {
|
|
+ finalSpawnerData.add(spawnerData);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ finalSpawners.put(entry.getKey(), finalSpawnerData.isEmpty() ? EMPTY_MOB_LIST : WeightedRandomList.create(finalSpawnerData));
|
|
+ }
|
|
+
|
|
+ this.spawners = ImmutableMap.copyOf(finalSpawners);
|
|
+ stripped = true;
|
|
+ }
|
|
+ // Slice end
|
|
|
|
public WeightedRandomList<MobSpawnSettings.SpawnerData> getMobs(MobCategory spawnGroup) {
|
|
+ if (!stripped) stripSpawnData(); // Slice
|
|
return this.spawners.getOrDefault(spawnGroup, EMPTY_MOB_LIST);
|
|
}
|
|
|
|
@Nullable
|
|
public MobSpawnSettings.MobSpawnCost getMobSpawnCost(EntityType<?> entityType) {
|
|
+ if (!stripped) stripSpawnData(); // Slice
|
|
return this.mobSpawnCosts.get(entityType);
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/scores/Scoreboard.java b/src/main/java/net/minecraft/world/scores/Scoreboard.java
|
|
index 3e75ea4d5a6c83ca570b29e3c1a5d51fb132379a..8a55e56a3aa1a8aa4c0780f46a98110c7b931155 100644
|
|
--- a/src/main/java/net/minecraft/world/scores/Scoreboard.java
|
|
+++ b/src/main/java/net/minecraft/world/scores/Scoreboard.java
|
|
@@ -223,6 +223,28 @@ public class Scoreboard {
|
|
return team.getPlayers().add(playerName);
|
|
}
|
|
}
|
|
+
|
|
+ // Slice start
|
|
+ public boolean addPlayersToTeam(Collection<String> players, PlayerTeam team) {
|
|
+ boolean anyAdded = false;
|
|
+ for (String playerName : players) {
|
|
+ if (playerName.length() > 40) {
|
|
+ net.minecraft.server.MinecraftServer.LOGGER.warn("The player name '" + playerName + "' is too long!");
|
|
+ } else {
|
|
+ if (this.getPlayersTeam(playerName) != null) {
|
|
+ this.removePlayerFromTeam(playerName);
|
|
+ }
|
|
+
|
|
+ this.teamsByPlayer.put(playerName, team);
|
|
+ if (team.getPlayers().add(playerName)) {
|
|
+ anyAdded = true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return anyAdded;
|
|
+ }
|
|
+ // Slice end
|
|
|
|
public boolean removePlayerFromTeam(String playerName) {
|
|
PlayerTeam playerTeam = this.getPlayersTeam(playerName);
|
|
@@ -242,6 +264,24 @@ public class Scoreboard {
|
|
team.getPlayers().remove(playerName);
|
|
}
|
|
}
|
|
+
|
|
+ // Slice start
|
|
+ public boolean removePlayersFromTeam(Collection<String> players, PlayerTeam team) {
|
|
+ boolean anyRemoved = false;
|
|
+ for (String playerName : players) {
|
|
+ if (this.getPlayersTeam(playerName) != team) {
|
|
+ net.minecraft.server.MinecraftServer.LOGGER.warn("Player " + playerName + " is either on another team or not on any team. Cannot remove from team '" + team.getName() + "'.");
|
|
+ } else {
|
|
+ this.teamsByPlayer.remove(playerName);
|
|
+ if (team.getPlayers().remove(playerName)) {
|
|
+ anyRemoved = true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return anyRemoved;
|
|
+ }
|
|
+ // Slice end
|
|
|
|
public Collection<String> getTeamNames() {
|
|
return this.teamsByName.keySet();
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
index 3b386ecc7630ab50cac1ae6fcb3141d444a74434..c7a33c379b29a39db8cfcfd4c6298b26fc4663e6 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
@@ -1195,6 +1195,18 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
|
public void setAutoSave(boolean value) {
|
|
world.noSave = !value;
|
|
}
|
|
+
|
|
+ // Slice start
|
|
+ @Override
|
|
+ public boolean isInstance() {
|
|
+ return world.instance;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setInstance(boolean value) {
|
|
+ world.instance = value;
|
|
+ }
|
|
+ // Slice end
|
|
|
|
@Override
|
|
public void setDifficulty(Difficulty difficulty) {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
index 2176269aa602049d69ec65bb1c1629a6680ccfa2..9c69d26ccdf6bf2b5f2128328ac792c175047b2c 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -2010,7 +2010,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();
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
|
|
index 2b87a652798cb632fe76bf20e9e7f8cb8bfb3b7b..1b10b3628e09b6c831e4907bf79e87a503e92dcf 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
|
|
@@ -1,6 +1,7 @@
|
|
package org.bukkit.craftbukkit.scoreboard;
|
|
|
|
import com.google.common.collect.ImmutableSet;
|
|
+import java.util.Collection; // Slice
|
|
import java.util.Set;
|
|
import net.minecraft.world.scores.PlayerTeam;
|
|
import net.minecraft.world.scores.Team.Visibility;
|
|
@@ -225,6 +226,16 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
|
|
|
|
scoreboard.board.addPlayerToTeam(entry, team);
|
|
}
|
|
+
|
|
+ // Slice start
|
|
+ @Override
|
|
+ public void addEntries(Collection<String> entries) throws IllegalStateException, IllegalArgumentException {
|
|
+ Validate.notNull(entries, "Entries cannot be null");
|
|
+ CraftScoreboard scoreboard = checkState();
|
|
+
|
|
+ scoreboard.board.addPlayersToTeam(entries, team);
|
|
+ }
|
|
+ // Slice end
|
|
|
|
@Override
|
|
public boolean removePlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException {
|
|
@@ -244,6 +255,25 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
|
|
scoreboard.board.removePlayerFromTeam(entry, team);
|
|
return true;
|
|
}
|
|
+
|
|
+ // Slice start
|
|
+ @Override
|
|
+ public boolean removeEntries(Collection<String> entries) throws IllegalStateException, IllegalArgumentException {
|
|
+ Validate.notNull(entries, "Entry cannot be null");
|
|
+ CraftScoreboard scoreboard = this.checkState();
|
|
+
|
|
+ boolean anyRemoved = false;
|
|
+ Collection<String> teamPlayers = this.team.getPlayers();
|
|
+ for (String entry : entries) {
|
|
+ if (teamPlayers.remove(entry)) {
|
|
+ anyRemoved = true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ scoreboard.board.removePlayersFromTeam(entries, team);
|
|
+ return anyRemoved;
|
|
+ }
|
|
+ // Slice end
|
|
|
|
@Override
|
|
public boolean hasPlayer(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException {
|
|
diff --git a/src/main/java/wtf/etil/mirai/MiraiConfig.java b/src/main/java/wtf/etil/mirai/MiraiConfig.java
|
|
index ca61a8b5621f6e5d925bcab997950029e56a6813..a0389406b9e2ff343d926581e05361bc9edaac4e 100644
|
|
--- a/src/main/java/wtf/etil/mirai/MiraiConfig.java
|
|
+++ b/src/main/java/wtf/etil/mirai/MiraiConfig.java
|
|
@@ -243,4 +243,13 @@ public class MiraiConfig {
|
|
entitiesCanUsePortals = getBoolean("settings.entities-can-use-portals", entitiesCanUsePortals);
|
|
}
|
|
|
|
+ public static java.util.Set<net.minecraft.world.entity.EntityType<?>> globalBlockedMobSpawnTypes = new java.util.HashSet<>();
|
|
+ private static void globalBlockedMobSpawnTypes() {
|
|
+ java.util.List<String> list = getList("settings.global-blocked-mobspawn-types", java.util.Collections.emptyList());
|
|
+ for (String type : list) {
|
|
+ java.util.Optional<net.minecraft.world.entity.EntityType<?>> entityType = net.minecraft.world.entity.EntityType.byString(type.toLowerCase());
|
|
+ entityType.ifPresent(eType -> globalBlockedMobSpawnTypes.add(eType));
|
|
+ }
|
|
+ }
|
|
+
|
|
}
|
|
\ No newline at end of file
|