How to save a scoreboard in a Minecraft Bukkit 1.20.4 Plugin

103 Views Asked by At

My code is creating a player_data_txt file in the paper plugins folder but it doesn't have any player data in it and the scoreboard isn't saving when players leave and rejoin.

package me.dev.Boost;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Score;
import org.bukkit.scoreboard.Scoreboard;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

public class BoostPlugin extends JavaPlugin implements Listener {

    private final Map<Player, Integer> killstreaks = new HashMap<>();
    private final Map<Player, Scoreboard> playerScoreboards = new HashMap<>();
    private File dataFile;
    private final Logger logger = Logger.getLogger("BoostPlugin");

    @Override
    public void onEnable() {
        Bukkit.getServer().getPluginManager().registerEvents(this, this);
        dataFile = new File(getDataFolder(), "player_data.txt");
        if (!dataFile.exists()) {
            try {
                dataFile.getParentFile().mkdirs();
                dataFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        loadPlayerData();
    }

    @Override
    public void onDisable() {
        savePlayerData();
    }

    @EventHandler
    public void onPlayerDeath(PlayerDeathEvent event) {
        Player victim = event.getEntity();
        Player killer = event.getEntity().getKiller();

        if (killer != null) {
            handleKill(killer);
        }

        resetKillstreak(victim);
    }

    private void handleKill(Player killer) {
        if (killstreaks.containsKey(killer)) {
            int currentStreak = killstreaks.get(killer);
            int newStreak = currentStreak + 1;

            // Apply effects based on killstreak
            applyEffects(killer, newStreak);

            killer.sendMessage(ChatColor.GREEN + "Killstreak: " + newStreak);
            updatePlayerScoreboard(killer, newStreak);
            updatePlayerDisplayName(killer, newStreak);

            killstreaks.put(killer, newStreak);
        } else {
            killstreaks.put(killer, 1);
            applyEffects(killer, 1);

            killer.sendMessage(ChatColor.GREEN + "Killstreak: 1");
            updatePlayerScoreboard(killer, 1);
            updatePlayerDisplayName(killer, 1);
        }
    }

    private void applyEffects(Player player, int streak) {
        // Apply effects based on killstreak
        if (streak == 1) {
            player.addPotionEffect(new PotionEffect(PotionEffectType.HERO_OF_THE_VILLAGE, Integer.MAX_VALUE, 0, true, false));
        } else if (streak == 2) {
            player.addPotionEffect(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, Integer.MAX_VALUE, 0, true, false));
        } else if (streak == 3) {
            player.addPotionEffect(new PotionEffect(PotionEffectType.HEALTH_BOOST, Integer.MAX_VALUE, 0, true, false));
        } else if (streak == 4) {
            player.addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, Integer.MAX_VALUE, 0, true, false));
        } else if (streak == 5) {
            player.addPotionEffect(new PotionEffect(PotionEffectType.DOLPHINS_GRACE, Integer.MAX_VALUE, 0, true, false));
        }

        // Add more conditions and effects as needed
    }

    private void resetKillstreak(Player player) {
        if (killstreaks.containsKey(player)) {
            killstreaks.remove(player);
            player.sendMessage(ChatColor.RED + "Your killstreak has been reset.");
            removePlayerScoreboard(player);
            updatePlayerDisplayName(player, 0);
        }
    }

    private void updatePlayerScoreboard(Player player, int streak) {
        Scoreboard scoreboard = playerScoreboards.computeIfAbsent(player, p -> Bukkit.getScoreboardManager().getNewScoreboard());
        Objective objective = scoreboard.getObjective("killstreak");

        if (objective == null) {
            objective = scoreboard.registerNewObjective("killstreak", "dummy", ChatColor.GREEN + "Killstreak");
            objective.setDisplaySlot(DisplaySlot.BELOW_NAME);
        }

        Score score = objective.getScore(player.getName());
        score.setScore(Math.min(streak, 5)); // Limit the displayed killstreak to 5

        player.setScoreboard(scoreboard);
    }


    private void removePlayerScoreboard(Player player) {
        // Remove player's scoreboard
        player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
        playerScoreboards.remove(player);
    }

    private void updatePlayerDisplayName(Player player, int streak) {
        // Update player display name on TAB screen with killstreak information (limit to 5)
        String displayName = player.getName() + ChatColor.RESET;

        if (streak > 0) {
            displayName += " " + ChatColor.GREEN + "KS:" + Math.min(streak, 5);
        }

        player.setPlayerListName(displayName);
    }

    private void loadPlayerData() {
        try {
            if (!dataFile.exists()) {
                logger.info("Player data file does not exist.");
                return;
            }

            Files.lines(dataFile.toPath()).forEach(line -> {
                String[] parts = line.split(":");
                if (parts.length == 2) {
                    String playerName = parts[0];
                    int streak = Integer.parseInt(parts[1]);
                    Player player = Bukkit.getPlayer(playerName);

                    if (player != null) {
                        killstreaks.put(player, streak);
                        updatePlayerScoreboard(player, streak);
                        updatePlayerDisplayName(player, streak);
                    }
                }
            });
            logger.info("Player data loaded successfully.");
        } catch (IOException e) {
            logger.log(Level.SEVERE, "Error loading player data", e);
        }
    }

    private void savePlayerData() {
        StringBuilder data = new StringBuilder();
        for (Map.Entry<Player, Integer> entry : killstreaks.entrySet()) {
            data.append(entry.getKey().getName()).append(":").append(entry.getValue()).append("\n");
        }
        try {
            Files.write(dataFile.toPath(), data.toString().getBytes());
            logger.info("Player data saved successfully.");
        } catch (IOException e) {
            logger.log(Level.SEVERE, "Error saving player data", e);
        }
    }
}

I tried loading the plugin in a paper 1.20.4 server and the player_data_txt file is created but there's no player data in the file and the scoreboard doesn't save when the player leaves.

0

There are 0 best solutions below