Solved Get offline player UUID for file check

Discussion in 'Plugin Development' started by xDeeKay, Jan 1, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    xDeeKay

    So I'm creating custom yml player files with the file name as the players UUID. How can I get the players UUID when they are offline? I need to be able to print information from a players UUID file when using a command like /ipcheck <player>, therefor getting the <player>'s UUID, then getting the stuff from that file.

    Here's what I have so far, which only works for online players:

    Code:
    package net.dkcraft.opticore.commands;
    
    import java.io.File;
    import java.util.Arrays;
    import java.util.List;
    import java.util.UUID;
    
    import net.dkcraft.opticore.Main;
    import net.dkcraft.opticore.util.UUIDFetcher;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.entity.Player;
    
    public class Ipcheck implements CommandExecutor {
    
        private Main plugin;
    
        public Ipcheck(Main plugin) {
            this.plugin = plugin;
        }
    
        FileConfiguration userconfig = null;
       
        @SuppressWarnings({ "deprecation", "unused" })
        public boolean onCommand(CommandSender cs, Command cmd, String label, String[] args) {
            if (cmd.getName().equalsIgnoreCase("ipcheck")) {
                if (args.length == 1) {
                    Player player = Bukkit.getPlayer(args[0]);
                    String playerName = player.getName();
                    UUID uuid = player.getUniqueId();
                    File userfile = new File(plugin.getDataFolder() + File.separator + "ip" + File.separator + uuid + ".yml");
                    if (player != null) {
                        if (userfile.exists()) {
                            userconfig = YamlConfiguration.loadConfiguration(userfile);
                            if (!userconfig.getStringList("IP").isEmpty()) {
                                StringBuilder sb = new StringBuilder();
                                List<String> list = userconfig.getStringList("IP");
                                for (String playerlist : list) {
                                    sb.append(playerlist).append(", ");
                                }
                                cs.sendMessage(ChatColor.GREEN + "IP's associated with " + playerName + ": " + sb.toString().substring(0, sb.length()-2));
                            } else {
                                cs.sendMessage("File is empty.");
                            }
                        } else {
                            cs.sendMessage("File does not exist.");
                        }
                    } else {
                        cs.sendMessage("Player is offline.");
                    }
                }
            }
            return false;
        }
    }
    I tried simply creating the files with the players name and it worked fine obviously, but then comes the problem of players changing their names, so I kinda need these as UUID's.
     
  2. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay You can keep track of their names with a different file. Or hope that they don't change their names a lot.
     
  3. Offline

    xDeeKay

    I though about this, but it seems pretty messy and unreliable.

    /ipcheck <player> -> get the player.yml file -> get the UUID from file -> get the uuid.yml file -> get IP's from file

    What if a player changes their name, and then someone else takes that name? There would be a player.yml file with the incorrect UUID stored in it, right? Of course this is a rare occurrence, but things like that can still happen.

    Is there no way to get an offline players UUID without needing anymore files? This would simplify things a lot for me.
     
  4. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay Bukkit.getOfflinePlayer(String name).getUniqueUid() or something like that.
    The chances that somebody changes their name and somebody else takes over right away aren't something worth taking account for in my opinion.
    Your method should do the trick.
     
  5. Offline

    xDeeKay

    @timtower I'm not sure how I'd integrate this into my current code though. Since this code already works for online players, how would I add something if they're offline?
     
  6. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay change the Player classes to OfflinePlayer classes, then put getOfflinePlayer instead getPlayer.
    And use uuid.toString instead of just uuid in the file constructor.
     
    xDeeKay likes this.
  7. Offline

    xDeeKay

    @timtower Huzzah! Thank you very much Tim, works like a charm.

    @timtower
    I've ran into another problem to do with this. I'm running a few necessary checks to see if the file exists, if it's not empty, and if it doesn't already contain the IP of the player connecting. It seems to work fine in 1 session, but as soon as I restart the server and try to connect, I get a NullPointerException.

    Here's the code that's doing it:
    Code:
            if (!userfile.exists()) {
                try {
                    userfile.createNewFile();
                    Bukkit.getConsoleSender().sendMessage("Creating IP config for " + playerName);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                userconfig = YamlConfiguration.loadConfiguration(userfile);
                userconfig.set("IP", null);
                List<String> ipList = userconfig.getStringList("IP");
                ipList.add(IP);
                Bukkit.getConsoleSender().sendMessage("Adding " + IP + " to IP config for " + playerName);
                userconfig.set("IP", ipList);
    
                try {
                    userconfig.save(userfile);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                Bukkit.getConsoleSender().sendMessage("IP config already exists for " + playerName);
                if (!userconfig.getStringList("IP").isEmpty()) {
                    if (!userconfig.getStringList("IP").contains(IP)) {
                        List<String> list = userconfig.getStringList("IP");
                        list.add(IP);
                        Bukkit.getConsoleSender().sendMessage("New IP found. Adding " + IP + " to IP config for " + playerName);
                        userconfig.set("IP", list);
                        try {
                            userconfig.save(userfile);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    } else {
                        Bukkit.getConsoleSender().sendMessage("this IP already exists for " + playerName);
                    }
                }
            }
    I'm getting the error on line 22. Again, only if I restart the server. I've had an issue like this before, but it was solved by using != null instead of .isEmpty() (or something along those lines)
     
    Last edited by a moderator: Jan 1, 2015
    timtower likes this.
  8. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay Probably because of this line:
    Code:
    userconfig.set("IP", null);
    Use this instead:
    Code:
    userconfig.set("IP", new ArrayList<String>());
     
  9. Offline

    xDeeKay

    @timtower I made that change, however the same issue arises. I'm not sure why it would work before a server restart, but not after.
     
  10. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay Could you post the entire class?
     
  11. Offline

    xDeeKay

    @timtower
    Code:
    package net.dkcraft.opticore.listeners;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.UUID;
    
    import net.dkcraft.opticore.Main;
    
    import org.bukkit.Bukkit;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerJoinEvent;
    
    public class PlayerIPConfig implements Listener {
    
        public Main plugin;
    
        public PlayerIPConfig(Main instance) {
            this.plugin = instance;
        }
    
        FileConfiguration userconfig = null;
    
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent event) {
            Player player = event.getPlayer();
            String playerName = player.getName();
            UUID uuid = player.getUniqueId();
            String IP = player.getAddress().getHostString();
            File userfile = new File(plugin.getDataFolder() + File.separator + "ip" + File.separator + uuid + ".yml");
            if (!userfile.exists()) {
                try {
                    userfile.createNewFile();
                    Bukkit.getConsoleSender().sendMessage("Creating IP config for " + playerName);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                userconfig = YamlConfiguration.loadConfiguration(userfile);
                //userconfig.set("Username", null);
                userconfig.set("IP", new ArrayList<String>());
                //List<String> usernameList = userconfig.getStringList("Username");
                List<String> ipList = userconfig.getStringList("IP");
                //usernameList.add(playerName);
                ipList.add(IP);
                Bukkit.getConsoleSender().sendMessage("Adding " + IP + " to IP config for " + playerName);
                //userconfig.set("Username", usernameList);
                userconfig.set("IP", ipList);
    
                try {
                    userconfig.save(userfile);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                Bukkit.getConsoleSender().sendMessage("IP config already exists for " + playerName);
                if (!userconfig.getStringList("IP").isEmpty()) {
                    if (!userconfig.getStringList("IP").contains(IP)) {
                        List<String> list = userconfig.getStringList("IP");
                        list.add(IP);
                        Bukkit.getConsoleSender().sendMessage("New IP found. Adding " + IP + " to IP config for " + playerName);
                        userconfig.set("IP", list);
                        try {
                            userconfig.save(userfile);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    } else {
                        Bukkit.getConsoleSender().sendMessage("this IP already exists for " + playerName);
                    }
                }
            }
        }
    }
     
  12. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay Try to cut back on the code. There are parts in your code that you have twice. You don't need that.
    If file not exists, create file continue code.
    If list not exists, create list continue code.
    Add IP to list.
    Save file.
    Return.
     
  13. Offline

    xDeeKay

    @timtower Lines 36-58 is if the file doesn't exists, and lines 59-78 are if the file does exist, and to update the list of IP's in that file if necessary. If I were to clean up the code, I still won't understand why my current code only works within 1 session.
     
  14. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay Try to clean it up anyways. Makes it easier to expand and for me also understand
     
  15. Offline

    xDeeKay

    @timtower There's not a lot I can clean up though, that's the thing. Where you say I have parts twice is necessary for what I'm trying to achieve.
     
  16. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay
    Code:
    package net.dkcraft.opticore.listeners;
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.UUID;
    import net.dkcraft.opticore.Main;
    import org.bukkit.Bukkit;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerJoinEvent;
    public class PlayerIPConfig implements Listener {
      public Main plugin;
      public PlayerIPConfig(Main instance) {
      this.plugin = instance;
      }
      @EventHandler
      public void onPlayerJoin(PlayerJoinEvent event) {
      Player player = event.getPlayer();
      String playerName = player.getName();
      UUID uuid = player.getUniqueId();
      String IP = player.getAddress().getHostString();
      File userfile = new File(plugin.getDataFolder() + File.separator + "ip" + File.separator + uuid.toString() + ".yml");
         FileConfiguration userconfig = null;
      if (!userfile.exists()) {
      try {
      userfile.createNewFile();
      Bukkit.getConsoleSender().sendMessage("Creating IP config for " + playerName);
      } catch (IOException e) {
      e.printStackTrace();
      }
         }
         userconfig = YamlConfiguration.loadConfiguration(userfile);
         //userconfig.set("Username", null);
         if(!userconfig.contains("IP")){
           userconfig.set("IP", new ArrayList<String>());
         }
         //List<String> usernameList = userconfig.getStringList("Username");
         List<String> ipList = userconfig.getStringList("IP");
         if(!ipList.contains(IP)){
           ipList.add(IP);
           Bukkit.getConsoleSender().sendMessage("Adding " + IP + " to IP config for " + playerName);
         //usernameList.add(playerName);
         }
         //userconfig.set("Username", usernameList);
         userconfig.set("IP", ipList);
         try {
           userconfig.save(userfile);
         } catch (IOException e) {
           e.printStackTrace();
         }
      }
    }
    Pretty much trimmed it in half.
    Also fixed this line for you:
    Code:
    File userfile = new File(plugin.getDataFolder() + File.separator + "ip" + File.separator + uuid.toString() + ".yml");
     
  17. Offline

    xDeeKay

    @timtower Thanks, but the same issue is still occurring; works fine until you restart the server and connect again. Here's the the error log if you need it: http://pastebin.com/sjuA73TR
     
  18. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay Are you sure that you are exporting to the right location?
    Line 53 is e.printStackTrace(), not a line that would throw errors.
     
  19. Offline

    xDeeKay

    @timtower Sorry, ignore that error. It's for a similar class I was using for testing purposes, but never removed.
    This seems to be working, but can you explain what you did differently to my original code besides removing duplicate code? I've still yet to understand why my code wasn't working after a server restart..
     
  20. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay Are you sure that that wasn't that same similar class then?
     
  21. Offline

    xDeeKay

    @timtower Nah it wasn't the test class because the initial error was coming from PlayerIPConfig, not PlayerAliasConfig. But anyway, it appears to be fixed now, no idea what the issue was. Thanks

    @timtower One last question if I may? Offline players don't have IP's obviously, so for one of my commands, I need to grab the players UUID, get the IP string from their UUID.yml file, use that IP for the next file name which is theirIP.yml, then print the username list from that file. I'm not sure how to tackle this, or if it's even possible.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Oct 31, 2016
  22. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay That is why you don't look at the player object anymore.
    Or use MySQL to save all the data.
     
  23. Offline

    xDeeKay

    @timtower Well I don't think MySQL is all that necessary in this case. I only have to store things on player login, and only if it's new information.
     
  24. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay But why not use 2 files instead of the huge amount that you have now?
     
  25. Offline

    xDeeKay

    @timtower
    I have 2 directories, each holding their own set of .yml files for their own purpose.

    Directory 1 called is called "alias" and stores files of IP's that connect to the server, and in those files are string lists of usernames that have connected via that IP. So, if I were to type /ipcheck timtower, and you happened to have played on the same IP as myself, I would get sent "timtower, xDeeKay".

    Directory 2 is called "ip" and stores files of players that connect to the server, via their uuid. In those files are string lists of IP's that players connect with. So if I was on my local server and were to type /ipcheck xDeeKay, I would get sent "127.0.0.1", and any other IP I'd had (if I weren't on a local server).

    I hope that clears some things up.
     
  26. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay But why not use ConfigurationSections for those?
    Would still prefer database though as it supports 2 way lookup.
     
  27. Offline

    xDeeKay

    @timtower I understand there are better ways to do it, but I'd prefer to keep it like this for now because I know what I'm trying to achieve is possible with what I currently have.

    This is still my current problem.
     
  28. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay Lets start with getting the UUID, you can use OfflinePlayer.getUniqueId() for that
    Get file, for each IP in that list get the theirIP file and list the usernames
     
  29. Offline

    xDeeKay

    @timtower

    This is what I've got so far, but it's obviously not right
    Code:
    package net.dkcraft.opticore.commands;
    
    import java.io.File;
    import java.util.List;
    import java.util.UUID;
    
    import net.dkcraft.opticore.Main;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    
    public class Aliases implements CommandExecutor {
    
        private Main plugin;
    
        public Aliases(Main plugin) {
            this.plugin = plugin;
        }
    
        FileConfiguration userconfig = null;
    
        @SuppressWarnings({ "deprecation", "unused" })
        public boolean onCommand(CommandSender cs, Command cmd, String label, String[] args) {
            if (cmd.getName().equalsIgnoreCase("aliases")) {
                if (args.length == 1) {
                    UUID uuid = Bukkit.getOfflinePlayer(args[0]).getUniqueId();
                    File uuidFile = new File(plugin.getDataFolder() + File.separator + "ip" + File.separator + uuid + ".yml");
                    if (uuidFile.exists()) {
                        cs.sendMessage("it exists");
                        userconfig = YamlConfiguration.loadConfiguration(uuidFile);
                        List<String> iplist = userconfig.getStringList("IP");
                        for (String list : iplist) {
                            File ipFile = new File(plugin.getDataFolder() + File.separator + "alias" + File.separator + iplist + ".yml");
                            userconfig = YamlConfiguration.loadConfiguration(ipFile);
                            if (!userconfig.getStringList("Usernames").isEmpty()) {
                                StringBuilder sb = new StringBuilder();
                                List<String> list2 = userconfig.getStringList("Usernames");
                                for (String playerlist : list2) {
                                    sb.append(playerlist).append(", ");
                                }
                                cs.sendMessage(ChatColor.GREEN + "Usernames associated with " + ChatColor.YELLOW + iplist + ChatColor.GREEN + ": " + sb.toString().substring(0, sb.length()-2));
                            }
                        }
                    } else {
                        cs.sendMessage("doesn't exist");
                    }
                }
            }
            return true;
        }
    }
     
  30. Offline

    timtower Administrator Administrator Moderator

    @xDeeKay Again: use uuid.toSting instead of uuid when making the file.
    Try to put the ip in the file constructor instead of the entire ip list.
     
Thread Status:
Not open for further replies.

Share This Page