Rollback UserManager to match master

This commit is contained in:
nossr50 2021-03-16 15:47:49 -07:00
parent f837be8e90
commit 86ba265064

View File

@ -1,76 +1,40 @@
package com.gmail.nossr50.util.player; package com.gmail.nossr50.util.player;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.MMODataSnapshot;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.neetgames.mcmmo.player.MMOPlayerData;
import com.neetgames.mcmmo.player.OnlineMMOPlayer;
import com.gmail.nossr50.datatypes.player.PersistentPlayerData;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.player.PersistentPlayerDataSaveTask;
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.FixedMetadataValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.UUID;
//TODO: Add per world handling
public final class UserManager { public final class UserManager {
private final @NotNull HashSet<OnlineMMOPlayer> playerDataSet; //Used to track players for sync saves on shutdown private static HashSet<McMMOPlayer> playerDataSet; //Used to track players for sync saves on shutdown
public UserManager() { private UserManager() {}
this.playerDataSet = new HashSet<>();
}
/** /**
* Track a new user. * Track a new user.
* *
* @param mmoPlayer the player profile to start tracking * @param mcMMOPlayer the player profile to start tracking
*/ */
public void track(@NotNull McMMOPlayer mmoPlayer) { public static void track(McMMOPlayer mcMMOPlayer) {
mmoPlayer.getPlayer().setMetadata(mcMMO.playerDataKey, new FixedMetadataValue(mcMMO.p, mmoPlayer)); mcMMOPlayer.getPlayer().setMetadata(mcMMO.playerDataKey, new FixedMetadataValue(mcMMO.p, mcMMOPlayer));
playerDataSet.add(mmoPlayer); //for sync saves on shutdown if(playerDataSet == null)
playerDataSet = new HashSet<>();
playerDataSet.add(mcMMOPlayer); //for sync saves on shutdown
} }
/** public static void cleanupPlayer(McMMOPlayer mcMMOPlayer) {
* Cleanup player data if(playerDataSet != null)
* playerDataSet.remove(mcMMOPlayer);
* @param mmoPlayer target player
*/
public void cleanupPlayer(@NotNull OnlineMMOPlayer mmoPlayer) {
playerDataSet.remove(mmoPlayer);
}
/**
* Gets the OnlineMMOPlayer object for a player, this can be null if the player has not yet been loaded.
* @param player target player
* @return OnlineMMOPlayer object for this player, null if Player has not been loaded
*/
public @Nullable McMMOPlayer queryPlayer(@Nullable Player player) {
if(player == null)
return null;
if(player.hasMetadata(mcMMO.playerDataKey))
return (McMMOPlayer) player.getMetadata(mcMMO.playerDataKey).get(0).value();
else
return null;
}
public @Nullable PlayerProfile queryOfflinePlayer(@NotNull String playerName) {
return mcMMO.getDatabaseManager().queryPlayerByName(playerName);
} }
/** /**
@ -78,125 +42,116 @@ public final class UserManager {
* *
* @param player The Player object * @param player The Player object
*/ */
public void remove(@NotNull Player player) { public static void remove(Player player) {
McMMOPlayer mmoPlayer = (McMMOPlayer) queryPlayer(player); McMMOPlayer mcMMOPlayer = getPlayer(player);
mcMMOPlayer.cleanup();
if(mmoPlayer != null) {
mmoPlayer.cleanup();
}
player.removeMetadata(mcMMO.playerDataKey, mcMMO.p); player.removeMetadata(mcMMO.playerDataKey, mcMMO.p);
playerDataSet.remove(mmoPlayer); //Clear sync save tracking
if(playerDataSet != null) {
playerDataSet.remove(mcMMOPlayer); //Clear sync save tracking
}
} }
/** /**
* Clear all users. * Clear all users.
*/ */
public void clearAll() { public static void clearAll() {
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) { for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
remove(player); remove(player);
} }
if(playerDataSet != null)
playerDataSet.clear(); //Clear sync save tracking playerDataSet.clear(); //Clear sync save tracking
} }
public @NotNull Collection<OnlineMMOPlayer> getPlayers() {
Collection<OnlineMMOPlayer> playerCollection = new ArrayList<>();
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
if (hasPlayerDataKey(player)) {
playerCollection.add(queryPlayer(player));
}
}
return playerCollection;
}
public boolean hasPlayerDataKey(Entity entity) {
return entity != null && entity.hasMetadata(mcMMO.playerDataKey);
}
public @NotNull MMODataSnapshot createPlayerDataSnapshot(@NotNull MMOPlayerData mmoPlayerData) {
return new MMODataSnapshot(mmoPlayerData);
}
public void saveUserImmediately(@NotNull MMOPlayerData mmoPlayerData, boolean useSync) {
if(useSync)
scheduleSyncSave(createPlayerDataSnapshot(mmoPlayerData)); //Execute sync saves immediately
else
scheduleAsyncSaveDelay(createPlayerDataSnapshot(mmoPlayerData), 0);
}
public void saveUserWithDelay(@NotNull MMOPlayerData mmoPlayerData, boolean useSync, int delayTicks) {
if(useSync)
scheduleSyncSaveDelay(createPlayerDataSnapshot(mmoPlayerData), delayTicks); //Execute sync saves immediately
else
scheduleAsyncSaveDelay(createPlayerDataSnapshot(mmoPlayerData), delayTicks);
}
/** /**
* Save all users ON THIS THREAD. * Save all users ON THIS THREAD.
*/ */
public void saveAllSync() { public static void saveAll() {
ImmutableList<OnlineMMOPlayer> trackedSyncData = ImmutableList.copyOf(playerDataSet); if(playerDataSet == null)
return;
mcMMO.p.getLogger().info("Saving player data... (" + trackedSyncData.size() + ")"); ImmutableList<McMMOPlayer> trackedSyncData = ImmutableList.copyOf(playerDataSet);
for (OnlineMMOPlayer onlinePlayer : trackedSyncData) { mcMMO.p.getLogger().info("Saving mcMMOPlayers... (" + trackedSyncData.size() + ")");
for (McMMOPlayer playerData : trackedSyncData) {
try try
{ {
mcMMO.p.getLogger().info("Saving data for player: "+onlinePlayer.getPlayerName()); mcMMO.p.getLogger().info("Saving data for player: "+playerData.getPlayerName());
saveUserImmediately(onlinePlayer.getMMOPlayerData(), true); playerData.getProfile().save(true);
} }
catch (Exception e) catch (Exception e)
{ {
mcMMO.p.getLogger().warning("Could not save mcMMO player data for player: " + onlinePlayer.getPlayerName()); mcMMO.p.getLogger().warning("Could not save mcMMO player data for player: " + playerData.getPlayerName());
} }
} }
mcMMO.p.getLogger().info("Finished save operation for "+trackedSyncData.size()+" players!"); mcMMO.p.getLogger().info("Finished save operation for "+trackedSyncData.size()+" players!");
} }
public static Collection<McMMOPlayer> getPlayers() {
Collection<McMMOPlayer> playerCollection = new ArrayList<>();
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
if (hasPlayerDataKey(player)) {
playerCollection.add(getPlayer(player));
}
}
return playerCollection;
}
/** /**
* This method is called by PlayerQuitEvent to tear down the mmoPlayer. * Get the McMMOPlayer of a player by name.
* If syncSave is true, then saving is executed immediately
* *
* @param syncSave if true, data is saved synchronously * @param playerName The name of the player whose McMMOPlayer to retrieve
* @return the player's McMMOPlayer object
*/ */
public void logout(@NotNull McMMOPlayer mmoPlayer, boolean syncSave) { public static McMMOPlayer getPlayer(String playerName) {
BleedTimerTask.bleedOut(mmoPlayer.getPlayer()); return retrieveMcMMOPlayer(playerName, false);
//TODO: There is a possibility that async saves don't execute in time if the server is told to shutdown
if(syncSave) {
saveUserImmediately(mmoPlayer.getPersistentPlayerData(), true);
} else {
saveUserWithDelay(mmoPlayer.getPersistentPlayerData(), false, 20);
} }
cleanupPlayer(mmoPlayer); public static McMMOPlayer getOfflinePlayer(OfflinePlayer player) {
if (player instanceof Player) {
if(Config.getInstance().getScoreboardsEnabled()) return getPlayer((Player) player);
ScoreboardManager.teardownPlayer(mmoPlayer.getPlayer());
//Remove user from cache (SQL)
mcMMO.getDatabaseManager().removeCache(mmoPlayer.getUUID());
} }
return retrieveMcMMOPlayer(player.getName(), true);
public void scheduleAsyncSave(@NotNull MMODataSnapshot mmoDataSnapshot) {
new PersistentPlayerDataSaveTask(mmoDataSnapshot).runTaskAsynchronously(mcMMO.p);
} }
public void scheduleSyncSave(@NotNull MMODataSnapshot mmoDataSnapshot) { public static McMMOPlayer getOfflinePlayer(String playerName) {
new PersistentPlayerDataSaveTask(mmoDataSnapshot).runTask(mcMMO.p); return retrieveMcMMOPlayer(playerName, true);
} }
public void scheduleAsyncSaveDelay(@NotNull MMODataSnapshot mmoDataSnapshot, int delayTicks) { /**
new PersistentPlayerDataSaveTask(mmoDataSnapshot).runTaskLaterAsynchronously(mcMMO.p, delayTicks); * Gets the McMMOPlayer object for a player, this can be null if the player has not yet been loaded.
* @param player target player
* @return McMMOPlayer object for this player, null if Player has not been loaded
*/
public static McMMOPlayer getPlayer(Player player) {
//Avoid Array Index out of bounds
if(player != null && player.hasMetadata(mcMMO.playerDataKey))
return (McMMOPlayer) player.getMetadata(mcMMO.playerDataKey).get(0).value();
else
return null;
} }
public void scheduleSyncSaveDelay(@NotNull MMODataSnapshot mmoDataSnapshot, int delayTicks) { private static McMMOPlayer retrieveMcMMOPlayer(String playerName, boolean offlineValid) {
new PersistentPlayerDataSaveTask(mmoDataSnapshot).runTaskLater(mcMMO.p, delayTicks); Player player = mcMMO.p.getServer().getPlayerExact(playerName);
if (player == null) {
if (!offlineValid) {
mcMMO.p.getLogger().warning("A valid mcMMOPlayer object could not be found for " + playerName + ".");
}
return null;
}
return getPlayer(player);
}
public static boolean hasPlayerDataKey(Entity entity) {
return entity != null && entity.hasMetadata(mcMMO.playerDataKey);
} }
} }