Solved Need help with BedwarsPlugin Start

Discussion in 'Plugin Development' started by Daveloper, Feb 25, 2024.

  1. Offline

    Daveloper

    I am currently writing the start method for my bedwars plugin. When I try to write the team of a player to a file, it works perfectly, but when I do that for the next player the team of the first one is deleted. (Sorry for my bad english)

    Here is the file after I set the first team (random uuids):

    Code:
    gadfe6588c-56c9-4aff-8458-8a7fd56741843:
      isInGame: true
      team: GREEN
    8685gt5c-56c9-4aff-5758-8a7fd7ddd475843:
       isInGame: true
    And here is the file after I set the second team:

    Code:
    gadfe6588c-56c9-4aff-8458-8a7fd56741843:
      isInGame: true
    8685gt5c-56c9-4aff-5758-8a7fd7ddd475843:
       isInGame: true
       team: BLUE
    code:

    Code:
    private static void setTeams() {
            List<BedwarsPlayer> players = new ArrayList<BedwarsPlayer>(BedwarsPlayer.getAllInstances());
            System.out.println(players);
            List<Team> teams = Arrays.asList(Team.values());
            System.out.println(teams.toString());
            int size = players.size();
            int j = 0;
            BedwarsPlayer bP = null;
            for(int i=0; i<size; i++) {       
                int e = new Random().nextInt(players.size());
                bP = players.remove(e);
                j = i % teams.size();
                bP.setTeam(teams.get(j));
               
               
            }
           
        }
    and the bP.setTeam Method runs this one:

    Code:
    public static void setValue(File file, String key, String name, Object value) {
            try {
                YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
                config.set(key + name, value);
                config.save(file);
            } catch (Exception e) {}
        }
    Please Help!
     
  2. Online

    timtower Administrator Administrator Moderator

    @Daveloper What does setTeam use as arguments?
     
  3. Offline

    Daveloper

  4. Online

    timtower Administrator Administrator Moderator

    Sure, but there is a file, key, name and value.
    I want to see the code that sets those.
     
  5. Offline

    Daveloper

    I actually extend the class with the setValue method and set "file" and "key" in the super constructor, then i call the non static method setValue

    Code:
    import java.io.File;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.UUID;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.GameMode;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;
    
    import at.daveloper.bedwars.death.DeathType;
    import at.daveloper.bedwars.game.Team;
    import at.daveloper.general.Countdown;
    import at.daveloper.general.Server;
    import at.daveloper.general.ServerFile;
    import at.daveloper.general.ServerSaver;
    
    public class BedwarsPlayer extends ServerSaver{
     
        private static final File file = ServerFile.BEDWARS_PLAYERS.getFile();
        private final Player player;
     
        //constructor
        public BedwarsPlayer(Player player) {
            super(ServerFile.BEDWARS_PLAYERS.getFile(), player.getUniqueId().toString());
            this.player = player;
        }
     
    
        //other getters and setters
    
        public void setTeam(Team team) {
            setValue(".team", team.toString());
        }

    (parts of the) superclass:

    Code:
    package at.daveloper.general;
    
    import java.io.File;
    import java.util.Set;
    import java.util.UUID;
    
    import org.bukkit.Bukkit;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.entity.Player;
    
    import at.daveloper.main.Main;
    
    public class ServerSaver {
     
        String key;
        File file;
        YamlConfiguration config;
     
        public ServerSaver(File file, String key) {
            setFile(file);
            setKey(key);
        }
        public void setFile(File file) {
            this.file = file;
            this.config = YamlConfiguration.loadConfiguration(file);
        }
        public void setKey(String key) {
            this.key = key;
        } 
        public String getKey() {
            return key;
        }
        public File getFile() {
            return file;
        }
    
     
        public void setValue(String name, Object value) {
            try {
                Bukkit.broadcastMessage(this.key + name + " = " + value);
                config.set(this.key + name, value);
                config.save(file);
            } catch (Exception e) {
                Main.getPlugin().getLogger().warning(e.toString());
            }
        }
     
    Last edited: Feb 25, 2024
  6. Offline

    Daveloper

  7. Online

    timtower Administrator Administrator Moderator

    Why are you over complicating things?

    And why have setFile when setValue just gets a new config?
     
  8. Offline

    Daveloper

    Sorry, what do you mean with just a new config? This is because I have multiple classes that write to a .yml file and with the ServerSaver class I don't have to repeat the

    try {
    File file = ....
    YamlConfiguration config = ...
    config.set...
    config.save...
    } catch...

    over and over again. I write

    setValue(".team", Team.BLUE);

    and I am done
     
    Last edited: Feb 26, 2024
  9. Online

    timtower Administrator Administrator Moderator

    @Daveloper And this is why you don't need multiple files.
    You have multiple config instances. One for each player.
    And they don't match.
    That is why you only need 1 config instance.
     
  10. Offline

    Daveloper

    Ok but the file is static and the same for each player and so the configuration
    Code:
     private static final File file = ServerFile.BEDWARS_PLAYERS.getFile();
    or do you mean something else? and how would I do that?
     
  11. Online

    timtower Administrator Administrator Moderator

    But this.config isn't
     
  12. Offline

    Daveloper

    @timtower So what would you write instead?
     
  13. Online

    timtower Administrator Administrator Moderator

    I would use 1 config instance, not an instance per player
     
  14. Offline

    Daveloper

    @timtower So I now coded a method in the enum"ServerFile" (where I also got the file from) to get the configuration for the file but what is the difference? I think I don't get it

    Code:
    private YamlConfiguration getConfig() {
            return YamlConfiguration.loadConfiguration(getFile());
        }
     
    Last edited: Feb 26, 2024
  15. Online

    timtower Administrator Administrator Moderator

    You make a new instance for a player, load the config.
    Then you make instance2, but those are not the same.
    Change config and instance2 stays the same.
    And loading the file every time is silly.
    Make an config instance outside of that save class.
    Pass it along to the save class using the constructor.
    Or don't use the class at all as it only adds the uuid
     
  16. Offline

    Daveloper

    Ok I will try
     
  17. Offline

    Daveloper

    @timtower I think I did it wrong again.
    As far as I understand it is not good to have multiple config instances at the same time that write to the same file.

    But how do I do that without creating a new instance again and again?

    What is your solution to the problem? (should i delete the save class?)
     
  18. Online

    timtower Administrator Administrator Moderator

    @Daveloper I would delete the player specific class and just have a method that sets things based on the player.
     
  19. Offline

    Daveloper

    @timtower Good idea but I also have an "Afk" class where I save the time when the player moved the last time. And since I check it with a scheduler the configuration stays the same the whole time so it doesn't reconize any changes in the file. Would it be a better idea to use the same config instance everywhere in the plugin? How do I do that? With a scheduler that keeps it alive? Does this even work?
     
    Last edited: Feb 28, 2024
  20. Online

    timtower Administrator Administrator Moderator

    @Daveloper Same config instance everywhere.
    And have the scheduler call a function in the main instance
     
  21. Offline

    Daveloper

    @timtower does YamlConfiguration.loadConfig(File file) return a new instance? If yes how should I do this...?
     
    Last edited: Feb 28, 2024
  22. Online

    timtower Administrator Administrator Moderator

    It does, and you only call it once, in your onEnable, and then you move that instance everywhere.
     
  23. Offline

    Daveloper

    @timtower ok, so i need an instance for every file
     
  24. Online

    timtower Administrator Administrator Moderator

    Yes
     
  25. Offline

    Daveloper

    (school was very stressful and I didn't have much time to develop on my plugin) @timtower I did what you said but the problem is still the same. I think the plugin mixes up the uuids from the players and it works when I do this:

    Code:
    BedwarsPlayer.getInstance(Bukkit.getPlayer("name")).setTeam(Team.BLUE);
    BedwarsPlayer.getInstance(Bukkit.getPlayer("name2")).setTeam(Team.GREEN);
    
    but not when I do this:

    Code:
    List<BedwarsPlayer> players = new ArrayList<BedwarsPlayer>(BedwarsPlayer.getAllInstances());
            List<Team> teams = Arrays.asList(Team.values());
            System.out.println(teams.toString());
            int size = players.size();
            int j = 0;
            BedwarsPlayer bP = null;
            for(int i=0; i<size; i++) {           
                int e = new Random().nextInt(players.size());
                bP = players.remove(e);
                j = i % teams.size();
                bP.setTeam(teams.get(j));
            }
     
  26. Online

    timtower Administrator Administrator Moderator

  27. Offline

    Daveloper

    @timtower
    Code:
    public static BedwarsPlayer getInstance(Player p) {
            if(saver.isSection(p.getUniqueId().toString())) return new BedwarsPlayer(p);
            return null;
        }
    constructor:

    Code:
    public class BedwarsPlayer{
      
        private static final ServerSaver saver = new ServerSaver(ServerFile.BEDWARS_PLAYERS);
        private final Player player;
      
      
      
        //constructor
        public BedwarsPlayer(Player player) {
            saver.setDefaultSection(player.getUniqueId().toString());
            this.player = player;
        }
    
    //...
      
        
    btw: i renamed all "key"s to "section"s
     
  28. Online

    timtower Administrator Administrator Moderator

    @Daveloper I am not gonna help with this anymore.
    I said to make a function, you made a different class. There is absolutely no need for that.
     
  29. Offline

    Daveloper

    @timtower so you want me to delete the bedwarsplayer class for data storage but why?
     
  30. Online

    timtower Administrator Administrator Moderator

    This is why.
    You are making things more complicated then it needs to be.
     

Share This Page