Paper/patches/unapplied/server/0288-Replace-OfflinePlayer-getLastPlayed.patch

165 lines
7.2 KiB
Diff
Raw Normal View History

2021-06-11 14:02:28 +02:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zach Brown <zach@zachbr.io>
Date: Wed, 2 Jan 2019 00:35:43 -0600
Subject: [PATCH] Replace OfflinePlayer#getLastPlayed
2021-06-11 14:02:28 +02:00
Currently OfflinePlayer#getLastPlayed could more accurately be described
as "OfflinePlayer#getLastTimeTheirDataWasSaved".
The API doc says it should return the last time the server "witnessed"
the player, whilst also saying it should return the last time they
logged in. The current implementation does neither.
Given this interesting contradiction in the API documentation and the
current defacto implementation, I've elected to deprecate (with no
intent to remove) and replace it with two new methods, clearly named and
documented as to their purpose.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 08c936288b5ac8738d7cff9fe95b1256ae32cd28..a8de1f58fffe2541478083defc18be949d0c75f1 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
2023-12-05 23:21:44 +01:00
@@ -248,6 +248,7 @@ public class ServerPlayer extends Player {
2023-09-22 00:26:51 +02:00
private int containerCounter;
2021-06-11 14:02:28 +02:00
public boolean wonGame;
private int containerUpdateDelay; // Paper - Configurable container update tick rate
+ public long loginTime; // Paper - Replace OfflinePlayer#getLastPlayed
2021-06-11 14:02:28 +02:00
// Paper start - cancellable death event
public boolean queueHealthUpdatePacket;
2021-06-11 14:02:28 +02:00
public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 7d81334b8bbfc04f1188de777b0cacd6f80131d3..2a0d3319899f0b3f38135e25306b87b1974b3d83 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -180,6 +180,7 @@ public abstract class PlayerList {
2021-06-11 14:02:28 +02:00
2023-09-22 00:26:51 +02:00
public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) {
Rewrite chunk system (#8177) Patch documentation to come Issues with the old system that are fixed now: - World generation does not scale with cpu cores effectively. - Relies on the main thread for scheduling and maintaining chunk state, dropping chunk load/generate rates at lower tps. - Unreliable prioritisation of chunk gen/load calls that block the main thread. - Shutdown logic is utterly unreliable, as it has to wait for all chunks to unload - is it guaranteed that the chunk system is in a state on shutdown that it can reliably do this? Watchdog shutdown also typically failed due to thread checks, which is now resolved. - Saving of data is not unified (i.e can save chunk data without saving entity data, poses problems for desync if shutdown is really abnormal. - Entities are not loaded with chunks. This caused quite a bit of headache for Chunk#getEntities API, but now the new chunk system loads entities with chunks so that they are ready whenever the chunk loads in. Effectively brings the behavior back to 1.16 era, but still storing entities in their own separate regionfiles. The above list is not complete. The patch documentation will complete it. New chunk system hard relies on starlight and dataconverter, and most importantly the new concurrent utilities in ConcurrentUtil. Some of the old async chunk i/o interface (i.e the old file io thread reroutes _some_ calls to the new file io thread) is kept for plugin compat reasons. It will be removed in the next major version of minecraft. The old legacy chunk system patches have been moved to the removed folder in case we need them again.
2022-09-26 10:02:51 +02:00
player.isRealPlayer = true; // Paper
+ player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed
2021-06-11 14:02:28 +02:00
GameProfile gameprofile = player.getGameProfile();
GameProfileCache usercache = this.server.getProfileCache();
String s;
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
index 34925d6448e0ef1d5bb4b24359f732b67aaa4230..0c1b5f625a351905e082b2c2a63bfd737101527e 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
@@ -262,6 +262,61 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
2021-06-13 10:26:58 +02:00
return this.getData() != null;
2021-06-11 14:02:28 +02:00
}
+ // Paper start
+ @Override
+ public long getLastLogin() {
+ Player player = getPlayer();
+ if (player != null) return player.getLastLogin();
+
+ CompoundTag data = getPaperData();
+
+ if (data != null) {
+ if (data.contains("LastLogin")) {
+ return data.getLong("LastLogin");
+ } else {
+ // if the player file cannot provide accurate data, this is probably the closest we can approximate
+ File file = getDataFile();
+ return file.lastModified();
+ }
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public long getLastSeen() {
+ Player player = getPlayer();
+ if (player != null) return player.getLastSeen();
+
+ CompoundTag data = getPaperData();
+
+ if (data != null) {
+ if (data.contains("LastSeen")) {
+ return data.getLong("LastSeen");
+ } else {
+ // if the player file cannot provide accurate data, this is probably the closest we can approximate
+ File file = getDataFile();
+ return file.lastModified();
+ }
+ } else {
+ return 0;
+ }
+ }
+
+ private CompoundTag getPaperData() {
+ CompoundTag result = getData();
+
+ if (result != null) {
+ if (!result.contains("Paper")) {
+ result.put("Paper", new CompoundTag());
+ }
+ result = result.getCompound("Paper");
+ }
+
+ return result;
+ }
+ // Paper end
+
@Override
public Location getLastDeathLocation() {
if (this.getData().contains("LastDeathLocation", 10)) {
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
2024-04-20 15:24:42 +02:00
index 29ede2405a645499e804a2f914a2563ef443f919..0e251c385db7969398eca95e3353de4a3de6d189 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
Updated Upstream (Bukkit/CraftBukkit) (#10242) * Updated Upstream (Bukkit/CraftBukkit) Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: a6a9d2a4 Remove some old ApiStatus.Experimental annotations be72314c SPIGOT-7300, PR-829: Add new DamageSource API providing enhanced information about entity damage b252cf05 SPIGOT-7576, PR-970: Add methods in MushroomCow to change stew effects b1c689bd PR-902: Add Server#isLoggingIPs to get log-ips configuration 08f86d1c PR-971: Add Player methods for client-side potion effects 2e3024a9 PR-963: Add API for in-world structures a23292a7 SPIGOT-7530, PR-948: Improve Resource Pack API with new 1.20.3 functionality 1851857b SPIGOT-3071, PR-969: Add entity spawn method with spawn reason cde4c52a SPIGOT-5553, PR-964: Add EntityKnockbackEvent CraftBukkit Changes: 38fd4bd50 Fix accidentally renamed internal damage method 80f0ce4be SPIGOT-7300, PR-1180: Add new DamageSource API providing enhanced information about entity damage 7e43f3b16 SPIGOT-7581: Fix typo in BlockMushroom ea14b7d90 SPIGOT-7576, PR-1347: Add methods in MushroomCow to change stew effects 4c687f243 PR-1259: Add Server#isLoggingIPs to get log-ips configuration 22a541a29 Improve support for per-world game rules cb7dccce2 PR-1348: Add Player methods for client-side potion effects b8d6109f0 PR-1335: Add API for in-world structures 4398a1b5b SPIGOT-7577: Make CraftWindCharge#explode discard the entity e74107678 Fix Crafter maximum stack size 0bb0f4f6a SPIGOT-7530, PR-1314: Improve Resource Pack API with new 1.20.3 functionality 4949f556d SPIGOT-3071, PR-1345: Add entity spawn method with spawn reason 20ac73ca2 PR-1353: Fix Structure#place not working as documented with 0 palette 3c1b77871 SPIGOT-6911, PR-1349: Change max book length in CraftMetaBook 333701839 SPIGOT-7572: Bee nests generated without bees f48f4174c SPIGOT-5553, PR-1336: Add EntityKnockbackEvent
2024-02-11 22:28:00 +01:00
@@ -197,6 +197,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener();
public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API
2021-06-11 14:02:28 +02:00
private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit
+ private long lastSaveTime; // Paper - getLastPlayed replacement API
2021-06-11 14:02:28 +02:00
public CraftPlayer(CraftServer server, ServerPlayer entity) {
super(server, entity);
2024-04-20 15:24:42 +02:00
@@ -1958,6 +1959,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2021-06-11 14:02:28 +02:00
this.firstPlayed = firstPlayed;
}
+ // Paper start - getLastPlayed replacement API
2021-06-11 14:02:28 +02:00
+ @Override
+ public long getLastLogin() {
+ return this.getHandle().loginTime;
2021-06-11 14:02:28 +02:00
+ }
+
+ @Override
+ public long getLastSeen() {
+ return this.isOnline() ? System.currentTimeMillis() : this.lastSaveTime;
2021-06-11 14:02:28 +02:00
+ }
+ // Paper end - getLastPlayed replacement API
2021-06-11 14:02:28 +02:00
+
public void readExtraData(CompoundTag nbttagcompound) {
2021-06-13 10:26:58 +02:00
this.hasPlayedBefore = true;
2021-06-11 14:02:28 +02:00
if (nbttagcompound.contains("bukkit")) {
2024-04-20 15:24:42 +02:00
@@ -1980,6 +1993,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2021-06-11 14:02:28 +02:00
}
public void setExtraData(CompoundTag nbttagcompound) {
+ this.lastSaveTime = System.currentTimeMillis(); // Paper
+
if (!nbttagcompound.contains("bukkit")) {
nbttagcompound.put("bukkit", new CompoundTag());
}
2024-04-20 15:24:42 +02:00
@@ -1994,6 +2009,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2021-06-13 10:26:58 +02:00
data.putLong("firstPlayed", this.getFirstPlayed());
2021-06-11 14:02:28 +02:00
data.putLong("lastPlayed", System.currentTimeMillis());
data.putString("lastKnownName", handle.getScoreboardName());
+
+ // Paper start - persist for use in offline save data
+ if (!nbttagcompound.contains("Paper")) {
+ nbttagcompound.put("Paper", new CompoundTag());
+ }
+
+ CompoundTag paper = nbttagcompound.getCompound("Paper");
+ paper.putLong("LastLogin", handle.loginTime);
+ paper.putLong("LastSeen", System.currentTimeMillis());
+ // Paper end
}
@Override