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
16 changes: 8 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.modularsoft</groupId>
<artifactId>PlayerHeadHunt</artifactId>
<version>1.1.1</version>
<version>1.2.0</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand All @@ -18,15 +18,15 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<version>3.13.0</version>
<configuration>
<release>17</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
Expand All @@ -37,7 +37,7 @@
<relocations>
<relocation>
<pattern>org.apache.hc</pattern>
<shadedPattern> org.modularsoft.PlayerHeadHunt.shaded.org.apache.hc</shadedPattern>
<shadedPattern>org.modularsoft.PlayerHeadHunt.shaded.org.apache.hc</shadedPattern>
</relocation>
</relocations>
</configuration>
Expand Down Expand Up @@ -71,7 +71,7 @@
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.20.4-R0.1-SNAPSHOT</version>
<version>1.21.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
Expand Down Expand Up @@ -111,20 +111,20 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<version>1.18.36</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.0</version>
<version>2.3</version>
</dependency>

<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2</version>
<version>5.4.1</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,22 @@ public void newPlayerJoinsTheHunt(Player player) {
}

public void playersOwnHeadCountResponse(Player player) {
// Use the instance of HeadQuery to call the method
player.sendMessage(plugin.config().getLangHeadCount()
.replace("%FOUNDHEADS%", "" + headQuery.foundHeadsCount(player))
.replace("%NUMBEROFHEADS%", "" + plugin.config().getTotalHeads()));
}

public void targetPlayerHeadCountResponse(org.bukkit.command.CommandSender sender, String targetName, int count) {
if (count == -1) {
sender.sendMessage(ChatColor.RED + "No data found for player: " + targetName);
return;
}
sender.sendMessage(plugin.config().getLangHeadCount()
.replace("%FOUNDHEADS%", "" + count)
.replace("%NUMBEROFHEADS%", "" + plugin.config().getTotalHeads())
.replace("You have", targetName + " has"));
}

public void playerClearedTheirHeadsResponse(Player player) {
player.sendMessage("All heads have been cleared.");
}
Expand Down
83 changes: 67 additions & 16 deletions src/main/java/org/modularsoft/PlayerHeadHunt/HeadQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class HeadQuery {
private final YamlFileManager yamlFileManager;
Expand Down Expand Up @@ -50,24 +51,28 @@ public int foundHeadsCount(Player player) {

public int foundHeadsAlreadyCount(int xCord, int yCord, int zCord) {
Map<String, Object> data = yamlFileManager.getData();
Object headsObject = data.get("heads");
int count = 0;

// Ensure the "heads" object is a list
if (!(headsObject instanceof List<?>)) {
return 0; // Return 0 if the data is not a list
for (Map.Entry<String, Object> entry : data.entrySet()) {
if (!(entry.getValue() instanceof Map<?, ?> playerData)) continue;

Object headsObj = playerData.get("headsCollected");
if (!(headsObj instanceof List<?> heads)) continue;

for (Object head : heads) {
if (!(head instanceof Map<?, ?> headMap)) continue;
Object hx = headMap.get("x");
Object hy = headMap.get("y");
Object hz = headMap.get("z");
if (hx instanceof Integer && hy instanceof Integer && hz instanceof Integer
&& (Integer) hx == xCord && (Integer) hy == yCord && (Integer) hz == zCord) {
count++;
break; // each player counts once per head location
}
}
}

List<?> heads = (List<?>) headsObject;

// Filter and count matching heads
return (int) heads.stream()
.filter(head -> head instanceof Map)
.map(head -> (Map<String, Object>) head)
.filter(head ->
head.get("x") instanceof Integer && head.get("y") instanceof Integer && head.get("z") instanceof Integer &&
head.get("x").equals(xCord) && head.get("y").equals(yCord) && head.get("z").equals(zCord)
)
.count();
return count;
}

public boolean clearHeads(Player player) {
Expand Down Expand Up @@ -108,7 +113,7 @@ public boolean hasAlreadyCollectedHead(Player player, int x, int y, int z) {

// Check if the head coordinates already exist in the list
return headsCollected.stream().anyMatch(head ->
head.get("x") == x && head.get("y") == y && head.get("z") == z);
Objects.equals(head.get("x"), x) && Objects.equals(head.get("y"), y) && Objects.equals(head.get("z"), z));
}

public void insertCollectedHead(Player player, int x, int y, int z) {
Expand Down Expand Up @@ -163,6 +168,52 @@ public boolean addNewHunter(Player player) {
return true;
}

public int foundHeadsCountByName(String playerName) {
Map<String, Object> data = yamlFileManager.getData();
for (Map.Entry<String, Object> entry : data.entrySet()) {
if (!(entry.getValue() instanceof Map<?, ?> playerData)) continue;
String username = (String) playerData.get("username");
if (!playerName.equalsIgnoreCase(username)) continue;
Object headsObj = playerData.get("headsCollected");
if (headsObj instanceof List<?> heads) {
return heads.size();
}
return 0;
}
return -1; // -1 indicates player not found in data
}

public boolean clearHeadsByName(String playerName) {
Map<String, Object> data = yamlFileManager.getData();
for (Map.Entry<String, Object> entry : data.entrySet()) {
if (!(entry.getValue() instanceof Map<?, ?> rawPlayerData)) continue;
String username = (String) rawPlayerData.get("username");
if (!playerName.equalsIgnoreCase(username)) continue;

Map<String, Object> playerData = (Map<String, Object>) entry.getValue();
List<Map<String, Integer>> headsCollected = (List<Map<String, Integer>>) playerData.get("headsCollected");
if (headsCollected != null) headsCollected.clear();
playerData.put("headsCollectedCount", 0);
yamlFileManager.save();
return true;
}
return false;
}

public int getLoadedPlayerCount() {
return yamlFileManager.getData().size();
}

public int getTotalHeadsCollectedAcrossAllPlayers() {
return yamlFileManager.getData().values().stream()
.filter(v -> v instanceof Map<?, ?>)
.mapToInt(v -> {
Object headsObj = ((Map<?, ?>) v).get("headsCollected");
return (headsObj instanceof List<?> list) ? list.size() : 0;
})
.sum();
}

private boolean isPlayerExcluded(UUID uuid, String username) {
return luckPerms.getUserManager().loadUser(uuid)
.thenApply(user -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,13 @@
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.modularsoft.PlayerHeadHunt.helpers.YamlFileManager;

import java.io.File;
import java.util.*;

public class HeadWorldController {
private final PlayerHeadHuntMain plugin;
private final YamlFileManager yamlFileManager;

public HeadWorldController(PlayerHeadHuntMain plugin) {
this.plugin = plugin;
this.yamlFileManager = new YamlFileManager(new File(plugin.getDataFolder(), "player-data.yml"));
}

public void countHeadsInRegion() {
Expand All @@ -55,39 +50,11 @@ public void countHeadsInRegion() {
}

public void playerCollectedHead(Player player, Block block, int x, int y, int z) {
String playerUUID = player.getUniqueId().toString();
Map<String, Object> data = yamlFileManager.getData();
Map<String, Object> playerData = (Map<String, Object>) data.get(playerUUID);

if (playerData == null) {
playerData = new HashMap<>();
playerData.put("headsCollected", new ArrayList<Map<String, Integer>>());
data.put(playerUUID, playerData);
}

List<Map<String, Integer>> collectedHeads = (List<Map<String, Integer>>) playerData.get("headsCollected");
if (collectedHeads == null) {
collectedHeads = new ArrayList<>();
playerData.put("headsCollected", collectedHeads);
}

boolean alreadyCollected = collectedHeads.stream().anyMatch(head ->
head.get("x") == x && head.get("y") == y && head.get("z") == z);

if (alreadyCollected) {
player.sendMessage(plugin.config().getLangHeadAlreadyFound());
return;
}

collectedHeads.add(Map.of("x", x, "y", y, "z", z));
yamlFileManager.save();

// Increment the player's head count
// Record the collection via HeadQuery (single source of truth for player data)
plugin.getHeadQuery().insertCollectedHead(player, x, y, z);

Material blockType = block.getType();
BlockData blockData = block.getBlockData();

int headRespawnTimer = plugin.config().getHeadRespawnTimer();

breakBlock(x, y, z);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.modularsoft.PlayerHeadHunt.commands.*;
import org.modularsoft.PlayerHeadHunt.events.HeadFindEvent;
import org.modularsoft.PlayerHeadHunt.events.HeadHatOnHead;
import org.modularsoft.PlayerHeadHunt.events.HeadHunterFlightControl;
import org.modularsoft.PlayerHeadHunt.events.HeadHunterOnJoin;
import org.bukkit.ChatColor;
import org.bukkit.command.ConsoleCommandSender;
Expand All @@ -27,8 +28,12 @@ public PluginConfig config() {

@Override
public void onEnable() {
// Generate configuration file
// Write default config.yml if it doesn't exist on disk, then enable
// in-memory fallback to bundled defaults for any key not present in
// the server's config.yml. Do NOT call saveConfig() here — merging
// new structured defaults into an old config corrupts the YAML file.
saveDefaultConfig();
getConfig().options().copyDefaults(true);
config = new PluginConfig(this);
console = getServer().getConsoleSender();

Expand All @@ -40,15 +45,23 @@ public void onEnable() {
HeadHatController headHatController = new HeadHatController(this);
HeadScoreboardController headScoreboardController = new HeadScoreboardController(this);

// Log loaded player and head statistics
int playerCount = headQuery.getLoadedPlayerCount();
int totalCollected = headQuery.getTotalHeadsCollectedAcrossAllPlayers();
console.sendMessage(ChatColor.GREEN + "Loaded " + playerCount + " player profile(s) from storage.");
console.sendMessage(ChatColor.GREEN + "Total heads collected across all players: " + totalCollected);

// Do an initial calculation of the number of heads. This can be
// manually recalculated with the relevant command.
headWorldController.countHeadsInRegion();

// Plugin Event Register
HeadHunterFlightControl flightControl = new HeadHunterFlightControl(this);
PluginManager pluginmanager = getServer().getPluginManager();
pluginmanager.registerEvents(new HeadFindEvent(this, headWorldController, headChatController, headHatController, headScoreboardController, headQuery), this);
pluginmanager.registerEvents(new HeadHunterOnJoin(this, headChatController, headScoreboardController, headQuery), this);
pluginmanager.registerEvents(new HeadHunterOnJoin(this, headChatController, headScoreboardController, headQuery, flightControl), this);
pluginmanager.registerEvents(new HeadHatOnHead(), this);
pluginmanager.registerEvents(flightControl, this);

// Command Registry
Objects.requireNonNull(getCommand("heads")).setExecutor(new heads(this, headChatController));
Expand All @@ -69,7 +82,7 @@ public void onEnable() {

@Override
public void onDisable() {
// Plugin Shutdown Message
console.sendMessage(ChatColor.RED + getDescription().getName() + " is now disabled.");
if (console != null)
console.sendMessage(ChatColor.RED + getDescription().getName() + " is now disabled.");
}
}
Loading