Loads of minor internal changes regarding static/final classes and variables (#89)

This commit is contained in:
Artemis-the-gr8 2022-07-12 00:29:41 +02:00
parent 3fe8afe216
commit bc0918c4f6
21 changed files with 199 additions and 153 deletions

View File

@ -4,13 +4,11 @@ import com.gmail.artemis.the.gr8.playerstats.commands.ReloadCommand;
import com.gmail.artemis.the.gr8.playerstats.commands.ShareCommand;
import com.gmail.artemis.the.gr8.playerstats.commands.StatCommand;
import com.gmail.artemis.the.gr8.playerstats.commands.TabCompleter;
import com.gmail.artemis.the.gr8.playerstats.commands.cmdutils.TabCompleteHelper;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.enums.DebugLevel;
import com.gmail.artemis.the.gr8.playerstats.listeners.JoinListener;
import com.gmail.artemis.the.gr8.playerstats.msg.MessageWriter;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import com.gmail.artemis.the.gr8.playerstats.statistic.ShareManager;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
@ -19,9 +17,9 @@ import org.jetbrains.annotations.NotNull;
public class Main extends JavaPlugin {
private BukkitAudiences adventure;
private static BukkitAudiences adventure;
public @NotNull BukkitAudiences adventure() {
public static @NotNull BukkitAudiences adventure() {
if (adventure == null) {
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
}
@ -33,27 +31,24 @@ public class Main extends JavaPlugin {
//initialize the Adventure library
adventure = BukkitAudiences.create(this);
//first get an instance of all the classes that need to be passed along to different classes
//first get an instance of all the classes that need to be initialized or passed along to different classes
ConfigHandler config = new ConfigHandler(this);
MessageWriter messageWriter = new MessageWriter(config);
ShareManager shareManager = new ShareManager(config);
OfflinePlayerHandler offlinePlayerHandler = new OfflinePlayerHandler();
//initialize the threadManager
ThreadManager threadManager = new ThreadManager(adventure(), config, messageWriter, shareManager);
ThreadManager threadManager = new ThreadManager(adventure(), config, messageWriter, this);
TabCompleteHelper tab = new TabCompleteHelper();
Bukkit.getLogger().info(tab.getEntityKilledSuggestions().toString());
ThreadManager threadManager = ThreadManager.getInstance(config, messageWriter, offlinePlayerHandler);
ShareManager shareManager = ShareManager.getInstance(config);
//register all commands and the tabCompleter
PluginCommand statcmd = this.getCommand("statistic");
if (statcmd != null) {
statcmd.setExecutor(new StatCommand(adventure(), messageWriter, threadManager));
statcmd.setTabCompleter(new TabCompleter());
statcmd.setExecutor(new StatCommand(messageWriter, threadManager, offlinePlayerHandler));
statcmd.setTabCompleter(new TabCompleter(offlinePlayerHandler));
}
PluginCommand reloadcmd = this.getCommand("statisticreload");
if (reloadcmd != null) reloadcmd.setExecutor(new ReloadCommand(threadManager));
PluginCommand sharecmd = this.getCommand("statisticshare");
if (sharecmd != null) sharecmd.setExecutor(new ShareCommand(adventure(), shareManager));
if (sharecmd != null) sharecmd.setExecutor(new ShareCommand(shareManager));
//register the listener
Bukkit.getPluginManager().registerEvents(new JoinListener(threadManager), this);

View File

@ -3,36 +3,38 @@ package com.gmail.artemis.the.gr8.playerstats;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.msg.MessageWriter;
import com.gmail.artemis.the.gr8.playerstats.reload.ReloadThread;
import com.gmail.artemis.the.gr8.playerstats.statistic.ShareManager;
import com.gmail.artemis.the.gr8.playerstats.models.StatRequest;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatThread;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.command.CommandSender;
import java.util.HashMap;
public class ThreadManager {
public final class ThreadManager {
private final int threshold = 10;
private static volatile ThreadManager instance;
private final static int threshold = 10;
private int statThreadID;
private int reloadThreadID;
private final BukkitAudiences adventure;
private static BukkitAudiences adventure;
private static ConfigHandler config;
private static MessageWriter messageWriter;
private final ShareManager shareManager;
private final OfflinePlayerHandler offlinePlayerHandler;
private ReloadThread lastActiveReloadThread;
private StatThread lastActiveStatThread;
private final HashMap<String, Thread> statThreads;
private static long lastRecordedCalcTime;
public ThreadManager(BukkitAudiences a, ConfigHandler c, MessageWriter m, ShareManager s) {
adventure = a;
private ThreadManager(ConfigHandler c, MessageWriter m, OfflinePlayerHandler o) {
adventure = Main.adventure();
config = c;
messageWriter = m;
shareManager = s;
offlinePlayerHandler = o;
statThreads = new HashMap<>();
statThreadID = 0;
@ -42,11 +44,28 @@ public class ThreadManager {
startReloadThread(null);
}
public static ThreadManager getInstance(ConfigHandler config, MessageWriter messageWriter, OfflinePlayerHandler offlinePlayerHandler) {
ThreadManager threadManager = instance;
if (threadManager != null) {
return threadManager;
}
synchronized (ThreadManager.class) {
if (instance == null) {
instance = new ThreadManager(config, messageWriter, offlinePlayerHandler);
}
return instance;
}
}
public static int getTaskThreshold() {
return threshold;
}
public void startReloadThread(CommandSender sender) {
if (lastActiveReloadThread == null || !lastActiveReloadThread.isAlive()) {
reloadThreadID += 1;
lastActiveReloadThread = new ReloadThread(adventure, config, messageWriter, threshold, reloadThreadID, lastActiveStatThread, sender);
lastActiveReloadThread = new ReloadThread(config, messageWriter, offlinePlayerHandler, reloadThreadID, lastActiveStatThread, sender);
lastActiveReloadThread.start();
}
else {
@ -83,7 +102,7 @@ public class ThreadManager {
}
private void startNewStatThread(StatRequest request) {
lastActiveStatThread = new StatThread(adventure, config, messageWriter, statThreadID, threshold, request, lastActiveReloadThread, shareManager);
lastActiveStatThread = new StatThread(config, messageWriter, offlinePlayerHandler, statThreadID, request, lastActiveReloadThread);
statThreads.put(request.getCommandSender().getName(), lastActiveStatThread);
lastActiveStatThread.start();
}

View File

@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
public class ReloadCommand implements CommandExecutor {
private final ThreadManager threadManager;
private static ThreadManager threadManager;
public ReloadCommand(ThreadManager t) {
threadManager = t;

View File

@ -1,5 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.commands;
import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.statistic.ShareManager;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.command.Command;
@ -11,11 +12,11 @@ import java.util.UUID;
public class ShareCommand implements CommandExecutor {
private final BukkitAudiences adventure;
private final ShareManager shareManager;
private static BukkitAudiences adventure;
private static ShareManager shareManager;
public ShareCommand(BukkitAudiences a, ShareManager s) {
adventure = a;
public ShareCommand(ShareManager s) {
adventure = Main.adventure();
shareManager = s;
}

View File

@ -1,5 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.commands;
import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
@ -23,14 +24,16 @@ import org.jetbrains.annotations.Nullable;
public class StatCommand implements CommandExecutor {
private final BukkitAudiences adventure;
private static BukkitAudiences adventure;
private static ThreadManager threadManager;
private final MessageWriter messageWriter;
private final ThreadManager threadManager;
private final OfflinePlayerHandler offlinePlayerHandler;
public StatCommand(BukkitAudiences a, MessageWriter m, ThreadManager t) {
adventure = a;
messageWriter = m;
public StatCommand(MessageWriter m, ThreadManager t, OfflinePlayerHandler o) {
adventure = Main.adventure();
threadManager = t;
messageWriter = m;
offlinePlayerHandler = o;
}
@Override
@ -90,7 +93,7 @@ public class StatCommand implements CommandExecutor {
request.setSelection(Target.SERVER);
}
}
else if (OfflinePlayerHandler.isRelevantPlayer(arg) && request.getPlayerName() == null) {
else if (offlinePlayerHandler.isRelevantPlayer(arg) && request.getPlayerName() == null) {
request.setPlayerName(arg);
request.setSelection(Target.PLAYER);
}

View File

@ -14,18 +14,22 @@ import java.util.stream.Collectors;
public class TabCompleter implements org.bukkit.command.TabCompleter {
private final List<String> commandOptions;
private final OfflinePlayerHandler offlinePlayerHandler;
private final TabCompleteHelper tabCompleteHelper;
private final List<String> commandOptions;
//TODO add "example" to the list
public TabCompleter() {
public TabCompleter(OfflinePlayerHandler o) {
offlinePlayerHandler = o;
tabCompleteHelper = new TabCompleteHelper();
commandOptions = new ArrayList<>();
commandOptions.add("top");
commandOptions.add("player");
commandOptions.add("server");
commandOptions.add("me");
tabCompleteHelper = new TabCompleteHelper();
}
//args[0] = statistic (length = 1)
@ -64,7 +68,7 @@ public class TabCompleter implements org.bukkit.command.TabCompleter {
tabSuggestions = commandOptions;
}
else {
tabSuggestions = getTabSuggestions(OfflinePlayerHandler.getOfflinePlayerNames(), currentArg);
tabSuggestions = getTabSuggestions(offlinePlayerHandler.getOfflinePlayerNames(), currentArg);
}
}

View File

@ -8,7 +8,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class TabCompleteHelper {
public final class TabCompleteHelper {
private static List<String> itemBrokenSuggestions;
private static List<String> entityKilledSuggestions;

View File

@ -12,18 +12,18 @@ import java.io.File;
public class ConfigHandler {
private static Main plugin;
private static double configVersion;
private File configFile;
private FileConfiguration config;
private final Main plugin;
private final double configVersion;
public ConfigHandler(Main p) {
plugin = p;
configVersion = 5;
saveDefaultConfig();
config = YamlConfiguration.loadConfiguration(configFile);
configVersion = 5;
checkConfigVersion();
MyLogger.setDebugLevel(getDebugLevel());

View File

@ -7,7 +7,7 @@ import org.bukkit.event.player.PlayerJoinEvent;
public class JoinListener implements Listener {
private final ThreadManager threadManager;
private static ThreadManager threadManager;
public JoinListener(ThreadManager t) {
threadManager = t;

View File

@ -9,8 +9,7 @@ import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull;
public class StatRequest {
public final class StatRequest {
private final CommandSender sender;
private Statistic statistic;

View File

@ -4,6 +4,5 @@ import net.kyori.adventure.text.TextComponent;
import java.util.UUID;
public record StatResult(String playerName, TextComponent statResult, int ID, UUID uuid) {
}

View File

@ -1,17 +1,19 @@
package com.gmail.artemis.the.gr8.playerstats.msg;
import com.gmail.artemis.the.gr8.playerstats.enums.DebugLevel;
import com.gmail.artemis.the.gr8.playerstats.enums.PluginColor;
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
import com.gmail.artemis.the.gr8.playerstats.msg.msgutils.ExampleMessage;
import com.gmail.artemis.the.gr8.playerstats.msg.msgutils.HelpMessage;
import com.gmail.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler;
import com.gmail.artemis.the.gr8.playerstats.msg.msgutils.*;
import com.gmail.artemis.the.gr8.playerstats.models.StatRequest;
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import org.bukkit.Bukkit;
import org.bukkit.Statistic;
import org.jetbrains.annotations.NotNull;

View File

@ -13,11 +13,10 @@ import java.util.HashMap;
public final class LanguageKeyHandler {
private final HashMap<Statistic, String> statNameKeys;
private static HashMap<Statistic, String> statNameKeys;
public LanguageKeyHandler() {
statNameKeys = new HashMap<>();
generateStatNameKeys();
statNameKeys = generateStatNameKeys();
}
public String getStatKey(@NotNull Statistic statistic) {
@ -72,47 +71,46 @@ public final class LanguageKeyHandler {
}
}
private void generateDefaultKeys() {
Arrays.stream(Statistic.values()).forEach(statistic -> statNameKeys.put(statistic, statistic.toString().toLowerCase()));
}
private void generateStatNameKeys() {
private @NotNull HashMap<Statistic, String> generateStatNameKeys() {
//get the enum names for all statistics first
generateDefaultKeys();
HashMap<Statistic, String> statNames = new HashMap<>(Statistic.values().length);
Arrays.stream(Statistic.values()).forEach(statistic -> statNames.put(statistic, statistic.toString().toLowerCase()));
//replace the ones for which the language key is different from the enum name
statNameKeys.put(Statistic.ARMOR_CLEANED, "clean_armor");
statNameKeys.put(Statistic.BANNER_CLEANED, "clean_banner");
statNameKeys.put(Statistic.DROP_COUNT, "drop");
statNameKeys.put(Statistic.CAKE_SLICES_EATEN, "eat_cake_slice");
statNameKeys.put(Statistic.ITEM_ENCHANTED, "enchant_item");
statNameKeys.put(Statistic.CAULDRON_FILLED, "fill_cauldron");
statNameKeys.put(Statistic.DISPENSER_INSPECTED, "inspect_dispenser");
statNameKeys.put(Statistic.DROPPER_INSPECTED, "inspect_dropper");
statNameKeys.put(Statistic.HOPPER_INSPECTED, "inspect_hopper");
statNameKeys.put(Statistic.BEACON_INTERACTION, "interact_with_beacon");
statNameKeys.put(Statistic.BREWINGSTAND_INTERACTION, "interact_with_brewingstand");
statNameKeys.put(Statistic.CRAFTING_TABLE_INTERACTION, "interact_with_crafting_table");
statNameKeys.put(Statistic.FURNACE_INTERACTION, "interact_with_furnace");
statNameKeys.put(Statistic.CHEST_OPENED, "open_chest");
statNameKeys.put(Statistic.ENDERCHEST_OPENED, "open_enderchest");
statNameKeys.put(Statistic.SHULKER_BOX_OPENED, "open_shulker_box");
statNameKeys.put(Statistic.NOTEBLOCK_PLAYED, "play_noteblock");
statNameKeys.put(Statistic.PLAY_ONE_MINUTE, "play_time");
statNameKeys.put(Statistic.RECORD_PLAYED, "play_record");
statNameKeys.put(Statistic.FLOWER_POTTED, "pot_flower");
statNameKeys.put(Statistic.TRAPPED_CHEST_TRIGGERED, "trigger_trapped_chest");
statNameKeys.put(Statistic.NOTEBLOCK_TUNED, "tune_noteblock");
statNameKeys.put(Statistic.CAULDRON_USED, "use_cauldron");
statNames.put(Statistic.ARMOR_CLEANED, "clean_armor");
statNames.put(Statistic.BANNER_CLEANED, "clean_banner");
statNames.put(Statistic.DROP_COUNT, "drop");
statNames.put(Statistic.CAKE_SLICES_EATEN, "eat_cake_slice");
statNames.put(Statistic.ITEM_ENCHANTED, "enchant_item");
statNames.put(Statistic.CAULDRON_FILLED, "fill_cauldron");
statNames.put(Statistic.DISPENSER_INSPECTED, "inspect_dispenser");
statNames.put(Statistic.DROPPER_INSPECTED, "inspect_dropper");
statNames.put(Statistic.HOPPER_INSPECTED, "inspect_hopper");
statNames.put(Statistic.BEACON_INTERACTION, "interact_with_beacon");
statNames.put(Statistic.BREWINGSTAND_INTERACTION, "interact_with_brewingstand");
statNames.put(Statistic.CRAFTING_TABLE_INTERACTION, "interact_with_crafting_table");
statNames.put(Statistic.FURNACE_INTERACTION, "interact_with_furnace");
statNames.put(Statistic.CHEST_OPENED, "open_chest");
statNames.put(Statistic.ENDERCHEST_OPENED, "open_enderchest");
statNames.put(Statistic.SHULKER_BOX_OPENED, "open_shulker_box");
statNames.put(Statistic.NOTEBLOCK_PLAYED, "play_noteblock");
statNames.put(Statistic.PLAY_ONE_MINUTE, "play_time");
statNames.put(Statistic.RECORD_PLAYED, "play_record");
statNames.put(Statistic.FLOWER_POTTED, "pot_flower");
statNames.put(Statistic.TRAPPED_CHEST_TRIGGERED, "trigger_trapped_chest");
statNames.put(Statistic.NOTEBLOCK_TUNED, "tune_noteblock");
statNames.put(Statistic.CAULDRON_USED, "use_cauldron");
//do the same for the statistics that have a subtype
statNameKeys.put(Statistic.DROP, "dropped");
statNameKeys.put(Statistic.PICKUP, "picked_up");
statNameKeys.put(Statistic.MINE_BLOCK, "mined");
statNameKeys.put(Statistic.USE_ITEM, "used");
statNameKeys.put(Statistic.BREAK_ITEM, "broken");
statNameKeys.put(Statistic.CRAFT_ITEM, "crafted");
statNameKeys.put(Statistic.KILL_ENTITY, "killed");
statNameKeys.put(Statistic.ENTITY_KILLED_BY, "killed_by");
statNames.put(Statistic.DROP, "dropped");
statNames.put(Statistic.PICKUP, "picked_up");
statNames.put(Statistic.MINE_BLOCK, "mined");
statNames.put(Statistic.USE_ITEM, "used");
statNames.put(Statistic.BREAK_ITEM, "broken");
statNames.put(Statistic.CRAFT_ITEM, "crafted");
statNames.put(Statistic.KILL_ENTITY, "killed");
statNames.put(Statistic.ENTITY_KILLED_BY, "killed_by");
return statNames;
}
}

View File

@ -1,5 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.reload;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import com.gmail.artemis.the.gr8.playerstats.utils.UnixTimeHandler;
import org.bukkit.OfflinePlayer;
@ -8,9 +9,9 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.RecursiveAction;
public class ReloadAction extends RecursiveAction {
public final class ReloadAction extends RecursiveAction {
private final int threshold;
private static int threshold;
private final OfflinePlayer[] players;
private final int start;
@ -20,21 +21,20 @@ public class ReloadAction extends RecursiveAction {
private final ConcurrentHashMap<String, UUID> offlinePlayerUUIDs;
/** Fills a ConcurrentHashMap with PlayerNames and UUIDs for all OfflinePlayers that should be included in statistic calculations.
* @param threshold the maximum length of OfflinePlayers to process in one task
* @param players array of all OfflinePlayers (straight from Bukkit)
* @param lastPlayedLimit whether to set a limit based on last-played-date
* @param offlinePlayerUUIDs the ConcurrentHashMap to put resulting playerNames and UUIDs on
*/
public ReloadAction(int threshold, OfflinePlayer[] players,
public ReloadAction(OfflinePlayer[] players,
int lastPlayedLimit, ConcurrentHashMap<String, UUID> offlinePlayerUUIDs) {
this(threshold, players, 0, players.length, lastPlayedLimit, offlinePlayerUUIDs);
this(players, 0, players.length, lastPlayedLimit, offlinePlayerUUIDs);
}
protected ReloadAction(int threshold, OfflinePlayer[] players, int start, int end,
private ReloadAction(OfflinePlayer[] players, int start, int end,
int lastPlayedLimit, ConcurrentHashMap<String, UUID> offlinePlayerUUIDs) {
threshold = ThreadManager.getTaskThreshold();
this.threshold = threshold;
this.players = players;
this.start = start;
this.end = end;
@ -53,9 +53,9 @@ public class ReloadAction extends RecursiveAction {
}
else {
final int split = length / 2;
final ReloadAction subTask1 = new ReloadAction(threshold, players, start, (start + split),
final ReloadAction subTask1 = new ReloadAction(players, start, (start + split),
lastPlayedLimit, offlinePlayerUUIDs);
final ReloadAction subTask2 = new ReloadAction(threshold, players, (start + split), end,
final ReloadAction subTask2 = new ReloadAction(players, (start + split), end,
lastPlayedLimit, offlinePlayerUUIDs);
//queue and compute all subtasks in the right order

View File

@ -1,5 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.reload;
import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.enums.DebugLevel;
@ -22,25 +23,28 @@ import java.util.function.Predicate;
public class ReloadThread extends Thread {
private final int threshold;
private final int reloadThreadID;
private final StatThread statThread;
private final BukkitAudiences adventure;
private static BukkitAudiences adventure;
private static ConfigHandler config;
private static MessageWriter messageWriter;
private final MessageWriter messageWriter;
private final OfflinePlayerHandler offlinePlayerHandler;
private final CommandSender sender;
public ReloadThread(BukkitAudiences a, ConfigHandler c, MessageWriter m, int threshold, int ID, @Nullable StatThread s, @Nullable CommandSender se) {
this.threshold = threshold;
public ReloadThread(ConfigHandler c, MessageWriter m, OfflinePlayerHandler o, int ID, @Nullable StatThread s, @Nullable CommandSender se) {
reloadThreadID = ID;
statThread = s;
adventure = a;
config = c;
messageWriter = m;
sender = se;
adventure = Main.adventure();
offlinePlayerHandler = o;
this.setName("ReloadThread-" + reloadThreadID);
MyLogger.threadCreated(this.getName());
}
@ -112,13 +116,13 @@ public class ReloadThread extends Thread {
int size = offlinePlayers != null ? offlinePlayers.length : 16;
ConcurrentHashMap<String, UUID> playerMap = new ConcurrentHashMap<>(size);
ReloadAction task = new ReloadAction(threshold, offlinePlayers, config.getLastPlayedLimit(), playerMap);
ReloadAction task = new ReloadAction(offlinePlayers, config.getLastPlayedLimit(), playerMap);
MyLogger.actionCreated((offlinePlayers != null) ? offlinePlayers.length : 0);
ForkJoinPool.commonPool().invoke(task);
MyLogger.actionFinished(1);
OfflinePlayerHandler.updateOfflinePlayerList(playerMap);
offlinePlayerHandler.updateOfflinePlayerList(playerMap);
MyLogger.logTimeTaken("ReloadThread",
("loaded " + OfflinePlayerHandler.getOfflinePlayerCount() + " offline players"), time);
("loaded " + offlinePlayerHandler.getOfflinePlayerCount() + " offline players"), time);
}
}

View File

@ -15,6 +15,8 @@ import java.util.concurrent.atomic.AtomicInteger;
public class ShareManager {
private static volatile ShareManager instance;
private boolean isEnabled;
private int waitingTime;
@ -22,9 +24,10 @@ public class ShareManager {
private ConcurrentHashMap<UUID, StatResult> statResults = null;
private ConcurrentHashMap<String, Instant> shareTimeStamp = null;
public ShareManager(ConfigHandler config) {
private ShareManager(ConfigHandler config) {
isEnabled = config.enableStatSharing();
waitingTime = config.getStatShareWaitingTime();
if (isEnabled) {
resultID = new AtomicInteger();
statResults = new ConcurrentHashMap<>();
@ -32,17 +35,37 @@ public class ShareManager {
}
}
public boolean isEnabled() {
return this.isEnabled;
public static ShareManager getInstance(ConfigHandler config) {
ShareManager shareManager = instance;
if (shareManager != null) {
return shareManager;
}
synchronized (ShareManager.class) {
if (instance == null) {
instance = new ShareManager(config);
}
return instance;
}
}
public void updateSettings(ConfigHandler config) {
public synchronized void updateSettings(ConfigHandler config) {
isEnabled = config.enableStatSharing();
waitingTime = config.getStatShareWaitingTime();
//if we went from disabled to enabled, initialize the HashMaps
if (isEnabled && statResults == null) {
statResults = new ConcurrentHashMap<>();
shareTimeStamp = new ConcurrentHashMap<>();
}
//if we went from enabled to disabled, purge the existing data
else if (!isEnabled && statResults != null) {
statResults = null;
shareTimeStamp = null;
}
}
public boolean isEnabled() {
return this.isEnabled;
}
public UUID saveStatResult(String playerName, TextComponent statResult) {

View File

@ -1,5 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.statistic;
import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import com.gmail.artemis.the.gr8.playerstats.models.StatRequest;
import com.gmail.artemis.the.gr8.playerstats.msg.MessageWriter;
@ -22,26 +23,28 @@ import java.util.stream.Collectors;
public class StatThread extends Thread {
private final int threshold;
private final ReloadThread reloadThread;
private final ShareManager shareManager;
private final BukkitAudiences adventure;
private static ConfigHandler config;
private static MessageWriter messageWriter;
private final MessageWriter messageWriter;
private final OfflinePlayerHandler offlinePlayerHandler;
private final ReloadThread reloadThread;
private final StatRequest request;
private static ShareManager shareManager;
private static BukkitAudiences adventure;
public StatThread(BukkitAudiences a, ConfigHandler c, MessageWriter m, int ID, int threshold, StatRequest s, @Nullable ReloadThread r, @Nullable ShareManager sm) {
this.threshold = threshold;
reloadThread = r;
shareManager = sm;
adventure = a;
public StatThread(ConfigHandler c, MessageWriter m, OfflinePlayerHandler o, int ID, StatRequest s, @Nullable ReloadThread r) {
config = c;
messageWriter = m;
offlinePlayerHandler = o;
reloadThread = r;
request = s;
adventure = Main.adventure();
shareManager = ShareManager.getInstance(config);
this.setName("StatThread-" + request.getCommandSender().getName() + "-" + ID);
MyLogger.threadCreated(this.getName());
}
@ -112,11 +115,11 @@ public class StatThread extends Thread {
private @NotNull ConcurrentHashMap<String, Integer> getAllStats() throws ConcurrentModificationException {
long time = System.currentTimeMillis();
int size = OfflinePlayerHandler.getOfflinePlayerCount() != 0 ? OfflinePlayerHandler.getOfflinePlayerCount() : 16;
int size = offlinePlayerHandler.getOfflinePlayerCount() != 0 ? offlinePlayerHandler.getOfflinePlayerCount() : 16;
ConcurrentHashMap<String, Integer> playerStats = new ConcurrentHashMap<>(size);
ImmutableList<String> playerNames = ImmutableList.copyOf(OfflinePlayerHandler.getOfflinePlayerNames());
ImmutableList<String> playerNames = ImmutableList.copyOf(offlinePlayerHandler.getOfflinePlayerNames());
TopStatAction task = new TopStatAction(threshold, playerNames, request, playerStats);
TopStatAction task = new TopStatAction(offlinePlayerHandler, playerNames, request, playerStats);
MyLogger.actionCreated(playerNames.size());
ForkJoinPool commonPool = ForkJoinPool.commonPool();
@ -139,7 +142,7 @@ public class StatThread extends Thread {
/** Gets the statistic data for an individual player. If somehow the player
cannot be found, this returns 0.*/
private int getIndividualStat() {
OfflinePlayer player = OfflinePlayerHandler.getOfflinePlayer(request.getPlayerName());
OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(request.getPlayerName());
if (player != null) {
return switch (request.getStatistic().getType()) {
case UNTYPED -> player.getStatistic(request.getStatistic());

View File

@ -1,5 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.statistic;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.models.StatRequest;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
@ -11,10 +12,11 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.RecursiveAction;
public class TopStatAction extends RecursiveAction {
public final class TopStatAction extends RecursiveAction {
private final int threshold;
private static int threshold;
private final OfflinePlayerHandler offlinePlayerHandler;
private final ImmutableList<String> playerNames;
private final StatRequest request;
private final ConcurrentHashMap<String, Integer> playerStats;
@ -22,15 +24,16 @@ public class TopStatAction extends RecursiveAction {
/**
* Gets the statistic numbers for all players whose name is on the list, puts them in a ConcurrentHashMap
* using the default ForkJoinPool, and returns the ConcurrentHashMap when everything is done
* @param threshold the maximum length of playerNames to process in one task
* @param offlinePlayerHandler the OfflinePlayerHandler to convert playerNames into Players
* @param playerNames ImmutableList of playerNames for players that should be included in stat calculations
* @param statRequest a validated statRequest
* @param playerStats the ConcurrentHashMap to put the results on
*/
public TopStatAction(int threshold, ImmutableList<String> playerNames, StatRequest statRequest, ConcurrentHashMap<String, Integer> playerStats) {
this.threshold = threshold;
this.playerNames = playerNames;
public TopStatAction(OfflinePlayerHandler offlinePlayerHandler, ImmutableList<String> playerNames, StatRequest statRequest, ConcurrentHashMap<String, Integer> playerStats) {
threshold = ThreadManager.getTaskThreshold();
this.offlinePlayerHandler = offlinePlayerHandler;
this.playerNames = playerNames;
this.request = statRequest;
this.playerStats = playerStats;
@ -43,8 +46,8 @@ public class TopStatAction extends RecursiveAction {
getStatsDirectly();
}
else {
final TopStatAction subTask1 = new TopStatAction(threshold, playerNames.subList(0, playerNames.size()/2), request, playerStats);
final TopStatAction subTask2 = new TopStatAction(threshold, playerNames.subList(playerNames.size()/2, playerNames.size()), request, playerStats);
final TopStatAction subTask1 = new TopStatAction(offlinePlayerHandler, playerNames.subList(0, playerNames.size()/2), request, playerStats);
final TopStatAction subTask2 = new TopStatAction(offlinePlayerHandler, playerNames.subList(playerNames.size()/2, playerNames.size()), request, playerStats);
//queue and compute all subtasks in the right order
invokeAll(subTask1, subTask2);
@ -57,7 +60,7 @@ public class TopStatAction extends RecursiveAction {
do {
String playerName = iterator.next();
MyLogger.actionRunning(Thread.currentThread().getName(), playerName, 2);
OfflinePlayer player = OfflinePlayerHandler.getOfflinePlayer(playerName);
OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName);
if (player != null) {
int statistic = 0;
switch (request.getStatistic().getType()) {

View File

@ -12,7 +12,7 @@ import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class EnumHandler {
public final class EnumHandler {
private final static List<String> blockNames;
private final static List<String> entityNames;
@ -50,9 +50,6 @@ public class EnumHandler {
.collect(Collectors.toList());
}
private EnumHandler() {
}
public static List<String> getItemNames() {
return itemNames;
}

View File

@ -12,27 +12,24 @@ public class OfflinePlayerHandler {
private static ConcurrentHashMap<String, UUID> offlinePlayerUUIDs;
private static ArrayList<String> playerNames;
static {
public OfflinePlayerHandler() {
offlinePlayerUUIDs = new ConcurrentHashMap<>();
playerNames = new ArrayList<>();
}
private OfflinePlayerHandler() {
}
/** Checks if a given playerName is on the private HashMap of players that should be included in statistic calculations
@param playerName String, case-sensitive */
public static boolean isRelevantPlayer(String playerName) {
public boolean isRelevantPlayer(String playerName) {
return offlinePlayerUUIDs.containsKey(playerName);
}
/** Returns the number of OfflinePlayers that are included in statistic calculations */
public static int getOfflinePlayerCount() {
public int getOfflinePlayerCount() {
return offlinePlayerUUIDs.size();
}
/** Get an ArrayList of names from all OfflinePlayers that should be included in statistic calculations */
public static ArrayList<String> getOfflinePlayerNames() {
public ArrayList<String> getOfflinePlayerNames() {
return playerNames;
}
@ -41,7 +38,7 @@ public class OfflinePlayerHandler {
* This HashMap is stored as a private variable in OfflinePlayerHandler.
* @param playerList ConcurrentHashMap with keys: playerNames and values: UUIDs
*/
public static void updateOfflinePlayerList(ConcurrentHashMap<String, UUID> playerList) {
public void updateOfflinePlayerList(ConcurrentHashMap<String, UUID> playerList) {
offlinePlayerUUIDs = playerList;
playerNames = Collections.list(offlinePlayerUUIDs.keys());
}
@ -51,7 +48,7 @@ public class OfflinePlayerHandler {
* @param playerName name of the target player
* @return OfflinePlayer (if this player is on the list, otherwise null)
*/
public static @Nullable OfflinePlayer getOfflinePlayer(String playerName) {
public @Nullable OfflinePlayer getOfflinePlayer(String playerName) {
if (offlinePlayerUUIDs.get(playerName) != null) {
return Bukkit.getOfflinePlayer(offlinePlayerUUIDs.get(playerName));
}

View File

@ -1,7 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.utils;
public class UnixTimeHandler {
public final class UnixTimeHandler {
/** Calculates whether a player has played recently enough to fall within the lastPlayedLimit.
If lastPlayedLimit == 0, this always returns true (since there is no limit).