Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 64 additions & 32 deletions src/main/java/hd/sphinx/sync/listener/JoinListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,63 +16,95 @@
import org.bukkit.event.player.PlayerPickupItemEvent;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

public class JoinListener implements Listener {

// Tracks players who are still loading
private static final Set<Player> loadingPlayers = new HashSet<>();

@EventHandler
public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if (ConfigManager.getBoolean("settings.onlySyncPermission") && !player.hasPermission("sync.sync")) return;
MainManageData.loadedPlayerData.add(player);
MainManageData.commandHashMap.put(player, new ArrayList<String>());
if (DeathListener.deadPlayers.contains(player)) {
DeathListener.deadPlayers.remove(player);

// Permission check
if (ConfigManager.getBoolean("settings.onlySyncPermission") && !player.hasPermission("sync.sync")) {
return;
}

// Prepare data structures for this player
MainManageData.commandHashMap.put(player, new ArrayList<>());

// Reset death state
DeathListener.deadPlayers.remove(player);

// Mark the player as loading
loadingPlayers.add(player);

// If new player
if (!MainManageData.isPlayerKnown(player)) {
if (ConfigManager.getBoolean("settings.sending.generated")) {
player.sendMessage(ConfigManager.getColoredString("messages.generated"));
String generatedMessage = ConfigManager.getColoredString("messages.generated");
if (!generatedMessage.trim().isEmpty()) {
player.sendMessage(generatedMessage);
}

MainManageData.generatePlayer(player);
Bukkit.getPluginManager().callEvent(new GeneratingPlayerProfileEvent(player, ConfigManager.getBoolean("settings.usingOldData")));
Bukkit.getPluginManager().callEvent(
new GeneratingPlayerProfileEvent(player, ConfigManager.getBoolean("settings.usingOldData"))
);

if (!ConfigManager.getBoolean("settings.usingOldData")) {
if (ConfigManager.getBoolean("settings.syncing.enderchest")) {
player.getEnderChest().clear();
}
if (ConfigManager.getBoolean("settings.syncing.inventory")) {
player.getInventory().clear();
}
if (ConfigManager.getBoolean("settings.syncing.exp")) {
player.setLevel(0);
}
if (ConfigManager.getBoolean("settings.syncing.enderchest")) player.getEnderChest().clear();
if (ConfigManager.getBoolean("settings.syncing.inventory")) player.getInventory().clear();
if (ConfigManager.getBoolean("settings.syncing.exp")) player.setLevel(0);
}
return;
} else {
if (ConfigManager.getBoolean("settings.syncing.enderchest")) {
player.getEnderChest().clear();
}
if (ConfigManager.getBoolean("settings.syncing.inventory")) {
player.getInventory().clear();
}
if (ConfigManager.getBoolean("settings.syncing.exp")) {
player.setLevel(0);
}
// Known player: clear inventories if needed
if (ConfigManager.getBoolean("settings.syncing.enderchest")) player.getEnderChest().clear();
if (ConfigManager.getBoolean("settings.syncing.inventory")) player.getInventory().clear();
if (ConfigManager.getBoolean("settings.syncing.exp")) player.setLevel(0);
}

// Send loading message
if (ConfigManager.getBoolean("settings.sending.loading")) {
player.sendMessage(ConfigManager.getColoredString("messages.loading"));
String generatedMessage = ConfigManager.getColoredString("messages.loading");
if (!generatedMessage.trim().isEmpty()) {
player.sendMessage(generatedMessage);
}
}

// Trigger loading event
Bukkit.getPluginManager().callEvent(new ProcessingLoadingPlayerDataEvent(player, new SyncSettings()));

// Schedule async join data loading
Main.schedulerManager.getScheduler().scheduleJoin(player);

// When scheduleJoin completes loading, call this:
Bukkit.getScheduler().runTaskLater(Main.getPlugin(Main.class), () -> {
// Player is fully loaded
MainManageData.loadedPlayerData.add(player);
loadingPlayers.remove(player);
}, 40L); // ~2 seconds delay (adjust based on your loading time)
}

@EventHandler
public void onPickup(PlayerPickupItemEvent event) {
if (MainManageData.loadedPlayerData.contains(event.getPlayer())) event.setCancelled(true);
if (DeathListener.deadPlayers.contains(event.getPlayer())) event.setCancelled(true);
Player player = event.getPlayer();
// Cancel only if player is still loading or dead
if (loadingPlayers.contains(player) || DeathListener.deadPlayers.contains(player)) {
event.setCancelled(true);
}
}

@EventHandler
public void onInteract(PlayerInteractEvent event) {
if (!MainManageData.loadedPlayerData.contains(event.getPlayer())) return;
if (event.getClickedBlock() != null && event.getClickedBlock().getType() != Material.AIR) event.setCancelled(true);
Player player = event.getPlayer();
// Cancel if still loading or dead
if (loadingPlayers.contains(player) || DeathListener.deadPlayers.contains(player)) {
if (event.getClickedBlock() != null && event.getClickedBlock().getType() != Material.AIR) {
event.setCancelled(true);
}
}
}
}
5 changes: 4 additions & 1 deletion src/main/java/hd/sphinx/sync/mysql/ManageMySQLData.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ public static void loadPlayer(Player player) {
syncProfile.setRawStatistics(StatisticsManager.loadPlayerStatistics(player, result));
}
} catch (Exception ignored) { }
player.sendMessage(ConfigManager.getColoredString("messages.loaded"));
String generatedMessage = ConfigManager.getColoredString("messages.loaded");
if (!generatedMessage.trim().isEmpty()) {
player.sendMessage(generatedMessage);
}
}
Main.schedulerManager.getScheduler().scheduleExecuteCommands(player);
Main.schedulerManager.getScheduler().scheduleCompleteLoadEvent(player, syncProfile);
Expand Down
73 changes: 60 additions & 13 deletions src/main/java/hd/sphinx/sync/util/StatisticsManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,25 @@ public static HashMap<String, Integer> getStatisticsMap(Player player) {
String drop = Statistic.DROP.toString();
String pickup = Statistic.PICKUP.toString();
for (Material material : Material.values()) {
// MINE_BLOCK only for blocks
if (material.isBlock()) {
returnHashMap.put(material.toString() + "==/=" + mineBlock, player.getStatistic(Statistic.MINE_BLOCK, material));
try {
returnHashMap.put(material + "==/=" + mineBlock, player.getStatistic(Statistic.MINE_BLOCK, material));
} catch (IllegalArgumentException ignored) {}
}

// The following stats must only be called for items
if (!material.isItem()) continue;

try {
returnHashMap.put(material + "==/=" + useItem, player.getStatistic(Statistic.USE_ITEM, material));
returnHashMap.put(material + "==/=" + breakItem, player.getStatistic(Statistic.BREAK_ITEM, material));
returnHashMap.put(material + "==/=" + craftItem, player.getStatistic(Statistic.CRAFT_ITEM, material));
returnHashMap.put(material + "==/=" + drop, player.getStatistic(Statistic.DROP, material));
returnHashMap.put(material + "==/=" + pickup, player.getStatistic(Statistic.PICKUP, material));
} catch (IllegalArgumentException ignored) {
// Skip invalid materials
}
returnHashMap.put(material.toString() + "==/=" + useItem, player.getStatistic(Statistic.USE_ITEM, material));
returnHashMap.put(material.toString() + "==/=" + breakItem, player.getStatistic(Statistic.BREAK_ITEM, material));
returnHashMap.put(material.toString() + "==/=" + craftItem, player.getStatistic(Statistic.CRAFT_ITEM, material));
returnHashMap.put(material.toString() + "==/=" + drop, player.getStatistic(Statistic.DROP, material));
returnHashMap.put(material.toString() + "==/=" + pickup, player.getStatistic(Statistic.PICKUP, material));
}

String killEntity = Statistic.KILL_ENTITY.toString();
Expand All @@ -66,16 +77,52 @@ public static HashMap<String, Integer> loadPlayerStatistics(Player player, Strin
}

for (String statistic : statistics.keySet()) {
if (statistic.contains("==/=") && statistic.contains("entity")) {
String[] statisticArray = statistic.split("==/=");
player.setStatistic(Statistic.valueOf(statisticArray[1]), EntityType.valueOf(statisticArray[0]), statistics.get(statistic));
} else if (statistic.contains("==/=")) {
int value = statistics.get(statistic);

if (statistic.contains("==/=")) {
String[] statisticArray = statistic.split("==/=");
player.setStatistic(Statistic.valueOf(statisticArray[1]), Material.valueOf(statisticArray[0]), statistics.get(statistic));
String key = statisticArray[0];
String statName = statisticArray[1];

try {
Statistic stat = Statistic.valueOf(statName);

if (isEntityStatistic(stat)) {
// Handle Entity statistics
try {
EntityType entityType = EntityType.valueOf(key);
player.setStatistic(stat, entityType, value);
} catch (IllegalArgumentException ignored) { }
} else {
// Handle Material statistics
try {
Material material = Material.valueOf(key);
// Only set item stats for real items
if (requiresItemStatistic(stat) && !material.isItem()) continue;
player.setStatistic(stat, material, value);
} catch (IllegalArgumentException ignored) { }
}
} catch (IllegalArgumentException ignored) { }
} else {
player.setStatistic(Statistic.valueOf(statistic), statistics.get(statistic));
// Handle simple statistics
try {
player.setStatistic(Statistic.valueOf(statistic), value);
} catch (IllegalArgumentException ignored) { }
}
}

return statistics;
}
}

private static boolean isEntityStatistic(Statistic stat) {
return stat == Statistic.KILL_ENTITY || stat == Statistic.ENTITY_KILLED_BY;
}

private static boolean requiresItemStatistic(Statistic stat) {
return stat == Statistic.USE_ITEM ||
stat == Statistic.BREAK_ITEM ||
stat == Statistic.CRAFT_ITEM ||
stat == Statistic.DROP ||
stat == Statistic.PICKUP;
}
}