From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 2 May 2020 20:55:44 -0500
Subject: [PATCH] Player invulnerabilities


diff --git a/src/main/java/net/minecraft/server/level/EntityPlayer.java b/src/main/java/net/minecraft/server/level/EntityPlayer.java
index 7e388dcca2d4e78b49d5fc5fce0b962e74839fa3..e875671ce985199bc37de131280935a859253954 100644
--- a/src/main/java/net/minecraft/server/level/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/level/EntityPlayer.java
@@ -284,6 +284,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         this.canPickUpLoot = true;
         this.maxHealthCache = this.getMaxHealth();
         this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper
+
+        this.invulnerableTicks = world.purpurConfig.playerSpawnInvulnerableTicks; // Purpur
     }
     // Paper start
     public BlockPosition getPointInFront(double inFront) {
@@ -1119,6 +1121,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
 
     }
 
+    // Purpur start
+    public boolean isSpawnInvulnerable() {
+        return invulnerableTicks > 0 || frozen;
+    }
+    // Purpur end
+
     @Override
     public boolean damageEntity(DamageSource damagesource, float f) {
         if (this.isInvulnerable(damagesource)) {
@@ -1126,7 +1134,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         } else {
             boolean flag = this.server.j() && this.canPvP() && "fall".equals(damagesource.translationIndex);
 
-            if (!flag && this.invulnerableTicks > 0 && damagesource != DamageSource.OUT_OF_WORLD) {
+            if (!flag && isSpawnInvulnerable() && damagesource != DamageSource.OUT_OF_WORLD) { // Purpur
                 return false;
             } else {
                 if (damagesource instanceof EntityDamageSource) {
@@ -1302,6 +1310,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
             }
             // Paper end
 
+            this.invulnerableTicks = worldserver.purpurConfig.playerSpawnInvulnerableTicks; // Purpur
             return this;
         }
     }
@@ -2488,9 +2497,17 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
 
     @Override
     public boolean isFrozen() { // Paper - protected > public
-        return super.isFrozen() || (this.playerConnection != null && this.playerConnection.isDisconnected()); // Paper
+        return super.isFrozen() || frozen || (this.playerConnection != null && this.playerConnection.isDisconnected()); // Paper // Purpur
     }
 
+    // Purpur start
+    private boolean frozen = false;
+
+    public void setFrozen(boolean frozen) {
+        this.frozen = frozen;
+    }
+    // Purpur end
+
     @Override
     public Scoreboard getScoreboard() {
         return getBukkitEntity().getScoreboard().getHandle();
diff --git a/src/main/java/net/minecraft/server/network/PlayerConnection.java b/src/main/java/net/minecraft/server/network/PlayerConnection.java
index e58bbd4c1b59293ddf58d0f7cf37a629f5cc96d6..7955d1d8cbb836be55d194d66152eb49fee27e49 100644
--- a/src/main/java/net/minecraft/server/network/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/network/PlayerConnection.java
@@ -1896,6 +1896,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
         PlayerConnectionUtils.ensureMainThread(packetplayinresourcepackstatus, this, this.player.getWorldServer());
         // Paper start
         PlayerResourcePackStatusEvent.Status packStatus = PlayerResourcePackStatusEvent.Status.values()[packetplayinresourcepackstatus.status.ordinal()];
+        player.setFrozen(packStatus == PlayerResourcePackStatusEvent.Status.ACCEPTED); // Purpur
         player.getBukkitEntity().setResourcePackStatus(packStatus);
         this.server.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getPlayer(), packStatus));
         // Paper end
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 0b5cf23932c3c626d8805d4db97d2bbab63634cf..a285d0594e61190a751a96f22afeb12d2dcce3fe 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1007,6 +1007,8 @@ public abstract class PlayerList {
         }
         // Paper end
 
+        entityplayer1.invulnerableTicks = entityplayer1.world.purpurConfig.playerSpawnInvulnerableTicks; // Purpur
+
         // CraftBukkit end
         return entityplayer1;
     }
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 2578a4677d1ee060f687be531e696b7c7be89e84..c441fcea9b2b5a77b801c8a69541cf42050927dc 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -67,4 +67,11 @@ public class PurpurWorldConfig {
         idleTimeoutCountAsSleeping = getBoolean("gameplay-mechanics.player.idle-timeout.count-as-sleeping", idleTimeoutCountAsSleeping);
         idleTimeoutUpdateTabList = getBoolean("gameplay-mechanics.player.idle-timeout.update-tab-list", idleTimeoutUpdateTabList);
     }
+
+    public int playerSpawnInvulnerableTicks = 60;
+    public boolean playerInvulnerableWhileAcceptingResourcePack = false;
+    private void playerInvulnerabilities() {
+        playerSpawnInvulnerableTicks = getInt("gameplay-mechanics.player.spawn-invulnerable-ticks", playerSpawnInvulnerableTicks);
+        playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack);
+    }
 }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index f4052aaa2235894b996d65c569a083f1a09b59a3..1ff48eae5e5b732fbd1e720c55e08a30669bebfa 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2507,5 +2507,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
     public void resetIdleTimer() {
         getHandle().resetIdleTimer();
     }
+
+    @Override
+    public boolean isSpawnInvulnerable() {
+        return getHandle().isSpawnInvulnerable();
+    }
+
+    @Override
+    public int getSpawnInvulnerableTicks() {
+        return getHandle().invulnerableTicks;
+    }
+
+    @Override
+    public void setSpawnInvulnerableTicks(int invulnerableTicks) {
+        getHandle().invulnerableTicks = invulnerableTicks;
+    }
     // Purpur end
 }
