PaperMC/patches/server/0292-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch

165 lines
6.9 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] Add APIs to replace OfflinePlayer#getLastPlayed
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
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
index 135e61ffa69a56e7c5edcd9e2066334abf963340..e8ca0d8612e132fac5533b7672d0fccbf1bc9e24 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
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
@@ -230,6 +230,7 @@ public class ServerPlayer extends Player {
2021-06-11 14:02:28 +02:00
public int latency;
public boolean wonGame;
private int containerUpdateDelay; // Paper
+ public long loginTime; // Paper
// Paper start - cancellable death event
public boolean queueHealthUpdatePacket = false;
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
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
index ffa3f9d147a0113d7b8cbf185ca751ed159576c2..97f045ee1af5479b2befe2e03f082933cfe91007 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
@@ -179,6 +179,7 @@ public abstract class PlayerList {
2021-06-11 14:02:28 +02:00
public void placeNewPlayer(Connection connection, ServerPlayer player) {
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
2021-06-11 14:02:28 +02:00
+ player.loginTime = System.currentTimeMillis(); // Paper
GameProfile gameprofile = player.getGameProfile();
GameProfileCache usercache = this.server.getProfileCache();
2021-07-07 08:52:40 +02:00
Optional<GameProfile> optional = usercache.get(gameprofile.getId());
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 e7442952ef1f03969949014492a7ddc6d0796ba5..d7823d7dc88cfba6f6ac9dae220e03dea4a0bcdd 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
@@ -250,6 +250,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
index 0e9538a433e8ef721f29cc7b9f8fac914b876956..e31de5e408b01c2e67d2feec4020796fa74b24d8 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
@@ -174,6 +174,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2021-06-11 14:02:28 +02:00
private org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus;
private String resourcePackHash;
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 end
public CraftPlayer(CraftServer server, ServerPlayer entity) {
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
@@ -1765,6 +1766,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2021-06-11 14:02:28 +02:00
this.firstPlayed = firstPlayed;
}
+ // Paper start
+ @Override
+ public long getLastLogin() {
+ return getHandle().loginTime;
+ }
+
+ @Override
+ public long getLastSeen() {
+ return isOnline() ? System.currentTimeMillis() : this.lastSaveTime;
+ }
+ // Paper end
+
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")) {
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
@@ -1787,6 +1800,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());
}
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
@@ -1801,6 +1816,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