getWorld form offline player

Discussion in 'Plugin Development' started by T2PO, Nov 17, 2023.

  1. Offline

    T2PO

    Hey,

    i needed a plugin that would show me the current world for all offline players (who were previously on the server). This will probably only be possible with nbt (because Bukkit of type getOfflinePlayers cannot query a current world). Not individually but for all in world/playerdata (for over 100).

    I tried this, but unfortunately it didn't work.

    Code:
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.World;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.command.TabCompleter;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.java.JavaPlugin;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.UUID;
    
    public class Main extends JavaPlugin {
    
        @Override
        public void onEnable() {
            // Plugin-Aktivierung
        }
    
        @Override
        public void onDisable() {
            // Plugin-Deaktivierung
        }
    
        @Override
        public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
            if (command.getName().equalsIgnoreCase("offlineplayers")) {
                List<String> offlinePlayerList = new ArrayList<>();
    
                for (OfflinePlayer offlinePlayer : Bukkit.getOfflinePlayers()) {
                    if (isOffline(offlinePlayer)) {
                        offlinePlayerList.add(offlinePlayer.getName());
                    }
                }
    
                if (offlinePlayerList.isEmpty()) {
                    sender.sendMessage(ChatColor.RED + "Es sind keine Offline-Spieler verfügbar.");
                } else {
                    sender.sendMessage(ChatColor.GREEN + "Liste der Offline-Spieler:");
                    for (String playerName : offlinePlayerList) {
                        String worldName = getOfflinePlayerWorld(playerName);
                        sender.sendMessage(ChatColor.YELLOW + playerName + " ist/war in der Welt: " + worldName);
                    }
                }
    
                return true;
            }
    
            return false;
        }
    
        private boolean isOffline(OfflinePlayer player) {
            return !player.isOnline();
        }
    
        private String getOfflinePlayerWorld(String playerName) {
            OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerName);
            UUID playerId = offlinePlayer.getUniqueId();
    
            for (World world : Bukkit.getWorlds()) {
                if (world.getPlayers().stream().anyMatch(player -> player.getUniqueId().equals(playerId))) {
                    return world.getName();
                }
            }
    
            return ChatColor.RED + "Unbekannte Welt";
        }
    }
     
  2. Offline

    timtower Administrator Administrator Moderator

    @T2PO And why do you need to know in which world?
     
  3. Offline

    T2PO

    Unfortunately I have to change the plugin for separate inventories per world and I want to find out beforehand who is still on a certain world (to inform him if necessary, otherwise the inventory will be lost).
     
  4. Offline

    timtower Administrator Administrator Moderator

    Have you considered opening up the files for that plugin? Probably has storage in the form of YML or a folder structure that is clear to read.
     
  5. Offline

    T2PO

    Mh that's an idea, but there are over 700 files which I would then have to search through.
     
  6. Offline

    timtower Administrator Administrator Moderator

    Which plugin are you gonna remove?
    Please post a link, and not just a name.
     
  7. Offline

    T2PO

  8. Offline

    timtower Administrator Administrator Moderator

  9. Offline

    T2PO

    I have been getting these errors since 1.20.2:

    Code:
    [15:48:50 INFO]: [ACF] Can't read players locale, you will be unable to automatically detect players language. Only Bukkit 1.7+ is supported for this.
    [15:48:50 INFO]: [ACF] java.lang.NoSuchFieldException: locale
    
    [15:48:50 INFO]: [ACF]    at java.base/java.lang.Class.getDeclaredField(Class.java:2642)
    
    [15:48:50 INFO]: [ACF]    at perworldinventory-kt-2.3.2.jar//me.ebonjaeger.perworldinventory.command.acf.BukkitCommandManager.readPlayerLocale(BukkitCommandManager.java:313)
    
    [15:48:50 INFO]: [ACF]    at perworldinventory-kt-2.3.2.jar//me.ebonjaeger.perworldinventory.command.acf.ACFBukkitListener.onPlayerJoin(ACFBukkitListener.java:54)
    
    [15:48:50 INFO]: [ACF]    at com.destroystokyo.paper.event.executor.MethodHandleEventExecutor.execute(MethodHandleEventExecutor.java:40)
    
    [15:48:50 INFO]: [ACF]    at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:81)
    
    [15:48:50 INFO]: [ACF]    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70)
    
    [15:48:50 INFO]: [ACF]    at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54)
    
    [15:48:50 INFO]: [ACF]    at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:126)
    
    [15:48:50 INFO]: [ACF]    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:615)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.server.players.PlayerList.a(PlayerList.java:325)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.server.network.ServerConfigurationPacketListenerImpl.a(ServerConfigurationPacketListenerImpl.java:130)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.network.protocol.configuration.ServerboundFinishConfigurationPacket.a(ServerboundFinishConfigurationPacket.java:18)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.network.protocol.configuration.ServerboundFinishConfigurationPacket.a(ServerboundFinishConfigurationPacket.java:9)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.network.protocol.PlayerConnectionUtils.lambda$ensureRunningOnSameThread$0(PlayerConnectionUtils.java:53)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.server.TickTask.run(TickTask.java:18)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.util.thread.IAsyncTaskHandler.d(IAsyncTaskHandler.java:153)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.util.thread.IAsyncTaskHandlerReentrant.d(IAsyncTaskHandlerReentrant.java:24)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:1324)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.server.MinecraftServer.d(MinecraftServer.java:193)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.util.thread.IAsyncTaskHandler.x(IAsyncTaskHandler.java:126)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.server.MinecraftServer.bg(MinecraftServer.java:1301)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1294)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.util.thread.IAsyncTaskHandler.bp(IAsyncTaskHandler.java:114)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.server.MinecraftServer.a(MinecraftServer.java:1410)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1156)
    
    [15:48:50 INFO]: [ACF]    at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:315)
    
    [15:48:50 INFO]: [ACF]    at java.base/java.lang.Thread.run(Thread.java:833)
    
    
    
    In addition, Paper Timings will be removed very soon:

    Code:
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Commands' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 INFO]: [ACF] Enabled Asynchronous Tab Completion Support!
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory help' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory version' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory reload' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory convert' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory group create' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory group addworld' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory group info' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory group list' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory group delete' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory group removeworld' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory group setrespawn' - this is deprecated behavior, please report it to the authors: EbonJaeger
    [15:45:36 WARN]: Plugin 'PerWorldInventory' is creating timing 'Command: perworldinventory migrate' - this is deprecated behavior, please report it to the authors: EbonJaeger
    
    But it still seems to work. Maybe it's just small things.
     
  10. Offline

    timtower Administrator Administrator Moderator

  11. Offline

    T2PO

  12. Offline

    Tim_M

    You could just save player world locations in a big UUID hashmap, and save it to file when the server stops. (auto saving every once in a while would be a good idea as well in case of crashes)
     
  13. Offline

    T2PO

    Do you have a suggestion for the code?
     
  14. Offline

    Tim_M

    I don't have my pc right now, but it should be as simple as adding a playerquitevent, and saving/loading the hashmap from disk, which is pretty simple with .yml files. Just store world names with UUID as the key. To autosave make a repeating bukkit runnable.
     
  15. Offline

    T2PO

    I don't think you've fully understood the problem. I meant offline players who are not online and have not been online for a long time. Saving the data for the future is not what I meant.
     
  16. Offline

    Tim_M

    Their locations is stored in the world files. In worst case you can make a Python script to extract that data and convert it to the yml file. All future cases can be handled by the plugin.

    Edit: it's pretty strange that this huge API doesn't have a function for offline players to see where they've logged off. So either do the Python thing or integrate the world files reading right into your plugin.
     
    Last edited: Nov 19, 2023
  17. Offline

    T2PO

    It is also incomprehensible to me why there is nothing for this in the API. Unfortunately, I don't know how to convert the player data (nbt) into a yml.
     
  18. Offline

    timtower Administrator Administrator Moderator

    Because the base game does not support having multiple inventories.
    There is no need to check which player has been in which world.

    Why do you want to know this anyways? To tell people to do something about their per world inventories?
    How are you gonna contact them?
     
  19. Offline

    T2PO

    To tell players to come online and change the world. There are several ways to contact players (mail, discord etc).

    There are certainly several reasons to request the location of offline players other than multiple inventories.
     
  20. Offline

    timtower Administrator Administrator Moderator

    Location != has been in a certain world and has an inventory there.
    And most servers don't have ways to contact everybody or anyone at all.
     
  21. Offline

    T2PO

    I am sure that there are other reasons than multiple inventories.
     

Share This Page