Search code examples
javaminecraftbukkit

Saving minecraft data to file on bukkit/spigot plugin not working


I have created a plugin using the Bukkit/Spigot API.

The aim of the plugin is to save player coordinates every second on Minecraft and store this in a '.log' file.

If my username on minecraft is 'abce', then there should be a file in the plugins folder of my server that is saved called 'abce.log' that stores my coordinates.

However, I am unable to find the file 'abce.log' file in my plugins folder on my server.

I have the following code :

package newestfile.here.newestplugin;

import java.io.IOException;
import java.util.UUID;
import java.io.PrintWriter;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.io.File;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.entity.Player;
import org.bukkit.Location;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.Bukkit;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;

public class Main extends JavaPlugin implements Listener
{
    boolean stopRepeater;
    HashMap<UUID, BukkitTask> tasks = new HashMap<>();
 
    public void onEnable() {
        Bukkit.getServer().getPluginManager().registerEvents(this,this);
        getLogger().info("HELLO! WELCOME TO THE TRACKER PLUGIN");
        if(!this.getDataFolder().exists())
        {
            this.getDataFolder().mkdir();
        }
    }
    
    public void onDisable() {
        getLogger().info("SHUTTING DOWN!");
    }
    
    @EventHandler
    public void onLogin(final PlayerJoinEvent event) {
        final Player thePlayer = event.getPlayer();
        this.stopRepeater = true;
        final Location playerSpawnLocation = thePlayer.getLocation();
        getLogger().info(String.valueOf(thePlayer.getName()) + " is logging in!");
        getLogger().info("Welcome " + thePlayer.getName() + ". Your current position is: " + playerSpawnLocation);  
        BukkitTask task = getServer().getScheduler().runTaskTimer(this, () -> {
            if(this.stopRepeater) {
                this.logToFile(thePlayer, thePlayer.getLocation());
            }
        }, 0L, 20L);
        tasks.put(thePlayer.getUniqueId(),task);}
    
    @EventHandler
    public void onQuit(final PlayerQuitEvent event) {
        Player thePlayer = event.getPlayer(); 
        if(!thePlayer.isOnline()) {
            this.stopRepeater = false;  
            getLogger().info(String.valueOf(event.getPlayer().getName()) + " has left the game");
            BukkitTask task = tasks.remove(thePlayer.getUniqueId()); 
            if(task != null) { 
               task.cancel();
            }
        }
    }
    
    public void logToFile(final Player currentPlayer, final Location playerCurrentLocation) {
        try {
            final File dataFolder = new File(this.getDataFolder() + File.separator + currentPlayer.getName());
            if (!dataFolder.exists()) {
                dataFolder.mkdir();
            }
            final File saveTo = new File(dataFolder, String.valueOf(currentPlayer.getName()) + ".log");
            if (!saveTo.exists()) {
                saveTo.createNewFile();
            }
            final Date nowDate = new Date();
            final SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
            final FileWriter fw = new FileWriter(saveTo, true);
            final PrintWriter pw = new PrintWriter(fw);
            pw.println(String.valueOf(format.format(nowDate)) + " CurrentLocation(x,y,z): " + playerCurrentLocation.getBlockX() + " " + playerCurrentLocation.getBlockY() + " " + playerCurrentLocation.getBlockZ());
            pw.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Solution

  • There is easier way to add content file.

    But, before adding content to file, you should create them. For this, you should do like:

    private File dataFolder;
    
    @Override
    public void onEnable() {
        dataFolder = new File(getDataFolder(), "data"); // get folder "plugins/MyPlugin/data"
        dataFolder.mkdirs(); // create folder if not exists
    }
    

    Then, to edit file, do:

    public void logToFile(final Player currentPlayer, final Location loc) {
       try {
           String content = String.valueOf(new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date()))
                   + " CurrentLocation(x,y,z): " + loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ() + "\n";
      
           File file = new File(dataFolder, currentPlayer.getName() + ".log");
           if(!file.exists()) { // if file is not present
               file.createNewFile(); // create
           }
           // append to file
           Files.write(file.toPath(), content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
    

    Also, actually, if multiple player join then one join, they will all be stopped from checking (because of change of stopRepeater). I think you should change the logic for timers, but it's another discussion which is off-topic for this question.