Kicking players from arraylist.

Discussion in 'Plugin Development' started by Shzylo, Sep 12, 2013.

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

    Shzylo

    I'm running into a problem with the current code:
    Code:java
    1. public ArrayList<Player> playing = new ArrayList<Player>();
    2. public ArrayList<Player> redTeam = new ArrayList<Player>();
    3. public ArrayList<Player> blueTeam = new ArrayList<Player>();
    4.  
    5. ..
    6.  
    7. private void kick() {
    8. if (!(playing.isEmpty())) {
    9. for (Player p : playing) {
    10. if (this.redTeam.contains(p))
    11. this.redTeam.remove(p);
    12. if (this.blueTeam.contains(p))
    13. this.blueTeam.remove(p);
    14.  
    15. this.playing.remove(p);
    16. this.getLogger().info("Player " + p + " has been kicked.");
    17. p.sendMessage(ChatColor.RED + "You have been kicked from the game!");
    18. }
    19. }
    20. }


    What I do is when the plugin/server is reloaded, I will kick everyone from the game, so nothing will mess up, but an exception occurs whenever there is a player in the list at all. The error is a java.util.ConcurrentModificationException which I have not encountered before until now. The error is thrown at for (Player p : playing) and I don't know why.

    Full Stack Trace:
    Code:
    06:13:50 [SEVERE] Error occurred while disabling ExtremePaintball v0.0.1 (Is it
    up to date?)
    java.util.ConcurrentModificationException
            at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
            at java.util.ArrayList$Itr.next(Unknown Source)
            at me.shzylo.extremepaintball.ExtremePaintball.kick(ExtremePaintball.jav
    a:95)
            at me.shzylo.extremepaintball.ExtremePaintball.onDisable(ExtremePaintbal
    l.java:42)
            at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:219)
            at org.bukkit.plugin.java.JavaPluginLoader.disablePlugin(JavaPluginLoade
    r.java:481)
            at org.bukkit.plugin.SimplePluginManager.disablePlugin(SimplePluginManag
    er.java:400)
            at org.bukkit.plugin.SimplePluginManager.disablePlugins(SimplePluginMana
    ger.java:393)
            at org.bukkit.plugin.SimplePluginManager.clearPlugins(SimplePluginManage
    r.java:434)
            at org.bukkit.craftbukkit.v1_6_R2.CraftServer.reload(CraftServer.java:57
    5)
            at org.bukkit.Bukkit.reload(Bukkit.java:275)
            at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:
    23)
            at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:18
    9)
            at org.bukkit.craftbukkit.v1_6_R2.CraftServer.dispatchCommand(CraftServe
    r.java:523)
            at net.minecraft.server.v1_6_R2.PlayerConnection.handleCommand(PlayerCon
    nection.java:964)
            at net.minecraft.server.v1_6_R2.PlayerConnection.chat(PlayerConnection.j
    ava:882)
            at net.minecraft.server.v1_6_R2.PlayerConnection.a(PlayerConnection.java
    :839)
            at net.minecraft.server.v1_6_R2.Packet3Chat.handle(SourceFile:49)
            at net.minecraft.server.v1_6_R2.NetworkManager.b(NetworkManager.java:296
    )
            at net.minecraft.server.v1_6_R2.PlayerConnection.e(PlayerConnection.java
    :118)
            at net.minecraft.server.v1_6_R2.ServerConnection.b(SourceFile:37)
            at net.minecraft.server.v1_6_R2.DedicatedServerConnection.b(SourceFile:3
    0)
            at net.minecraft.server.v1_6_R2.MinecraftServer.t(MinecraftServer.java:5
    90)
            at net.minecraft.server.v1_6_R2.DedicatedServer.t(DedicatedServer.java:2
    26)
            at net.minecraft.server.v1_6_R2.MinecraftServer.s(MinecraftServer.java:4
    86)
            at net.minecraft.server.v1_6_R2.MinecraftServer.run(MinecraftServer.java
    :419)
            at net.minecraft.server.v1_6_R2.ThreadServerApplication.run(SourceFile:5
    82)
    Can anyone explain to me what causes this error, and how to fix it?
     
  2. Offline

    MayoDwarf

    First of all, if you are trying to broadcast this
    Code:
    this.getLogger().info("Player " + p + " has been kicked.");
    to the players on the server then you should make it this:
    Code:
    Bukkit.broadcastMessage("Player " + p + " has been kicked.");
     
  3. Offline

    xTrollxDudex

    Shzylo
    See what happens when you store player objects on a list?
     
  4. Offline

    WauloK

    I think we're gonna need to see the rest of the code to help out :)
     
    MayoDwarf likes this.
  5. Offline

    Shzylo

    MayoDwarf I just use that to post in the console, I am going to be logging information there for when you reload the plugin or disable it, make sure no errors occur.

    Here is my full code of my main class:
    Code:java
    1. package me.shzylo.extremepaintball;
    2.  
    3. import java.util.ArrayList;
    4.  
    5. import me.shzylo.extremepaintball.commands.CmdArena;
    6. import me.shzylo.extremepaintball.commands.CmdWand;
    7. import me.shzylo.extremepaintball.commands.JoinCommand;
    8. import me.shzylo.extremepaintball.commands.LeaveCommand;
    9. import me.shzylo.extremepaintball.events.BlockEvents;
    10. import me.shzylo.extremepaintball.events.SignEvents;
    11. import me.shzylo.extremepaintball.items.Bow;
    12. import me.shzylo.extremepaintball.items.Shop;
    13. import me.shzylo.extremepaintball.wand.Selector;
    14.  
    15. import org.bukkit.ChatColor;
    16. import org.bukkit.command.Command;
    17. import org.bukkit.command.CommandSender;
    18. import org.bukkit.entity.Player;
    19. import org.bukkit.plugin.PluginManager;
    20. import org.bukkit.plugin.java.JavaPlugin;
    21.  
    22. public final class ExtremePaintball extends JavaPlugin {
    23. Selector selector;
    24.  
    25. public final String EPB_MSG = ("[" + ChatColor.AQUA + "Extreme" + ChatColor.RED + "Paintball" + ChatColor.WHITE + "]");
    26. public final String ERR_NOT_PLAYER = EPB_MSG + ChatColor.RED + " You must be a player!";
    27. public final String EPB_JOIN_MSG = EPB_MSG + ChatColor.GOLD + " You have joined the game!";
    28. public final String EPB_LEAVE_MSG = EPB_MSG + ChatColor.GOLD + " You have left the game!";
    29.  
    30. public ArrayList<Player> playing = new ArrayList<Player>();
    31. public ArrayList<Player> redTeam = new ArrayList<Player>();
    32. public ArrayList<Player> blueTeam = new ArrayList<Player>();
    33.  
    34. public void onEnable() {
    35. this.saveDefaultConfig();
    36. selector = new Selector(this, getConfig().getInt("wand-tool"));
    37. initCommands();
    38. initListeners();
    39. }
    40.  
    41. public void onDisable() {
    42. kick();
    43. this.getLogger().info("No players are in-game. Disabled");
    44. }
    45.  
    46. public boolean onCommand(CommandSender sender, Command command, String lbl, String[] args) {
    47. String cmd = command.getName();
    48.  
    49. if (cmd.equalsIgnoreCase("epb")) {
    50. if (args.length == 0) {
    51. sender.sendMessage("[]----------" + EPB_MSG + "----------[]");
    52. sender.sendMessage(ChatColor.GREEN + "Version: " + ChatColor.GOLD + this.getDescription().getVersion());
    53. sender.sendMessage(ChatColor.GREEN + "Idea By: " + ChatColor.GOLD + "theunknownmana");
    54. sender.sendMessage(ChatColor.GREEN + "Code By: " + ChatColor.GOLD + "Shzylo");
    55. sender.sendMessage("");
    56. sender.sendMessage("----[" + ChatColor.AQUA + "Commands" + ChatColor.WHITE + "]----");
    57. sender.sendMessage(ChatColor.GREEN + "/epbjoin" + ChatColor.GOLD + " Join the lobby");
    58. sender.sendMessage(ChatColor.GREEN + "/epbleave" + ChatColor.GOLD + " Leave the lobby");
    59. return true;
    60. } else if (args.length > 0) {
    61. if (args.length == 1) {
    62. if (args[0].equalsIgnoreCase("reload") || args[0].equalsIgnoreCase("rl")) {
    63. this.reloadConfig();
    64. sender.sendMessage(ChatColor.BLUE + "ExtremePaintball has been reloaded!");
    65. kick();
    66. }
    67. } else if (args.length == 2) {
    68.  
    69. }
    70. }
    71. }
    72. return false;
    73. }
    74.  
    75. private void initCommands() {
    76. getCommand("epbwand").setExecutor(new CmdWand(this));
    77. getCommand("epbarena").setExecutor(new CmdArena(this, selector));
    78. getCommand("epbjoin").setExecutor(new JoinCommand(this));
    79. getCommand("epbleave").setExecutor(new LeaveCommand(this));
    80. }
    81.  
    82. private void initListeners() {
    83. PluginManager pm = getServer().getPluginManager();
    84. pm.registerEvents(new BlockEvents(this), this);
    85. pm.registerEvents(new Bow(this), this);
    86. pm.registerEvents(new SignEvents(this), this);
    87. pm.registerEvents(new Shop(this), this);
    88. }
    89.  
    90. private void kick() {
    91. if (!(playing.isEmpty())) {
    92. for
    93. (Player p
    94. : // This was all separated to see where the error was.
    95. playing /* ERROR OCCURS HERE */ ) {
    96. if (this.redTeam.contains(p))
    97. this.redTeam.remove(p);
    98. if (this.blueTeam.contains(p))
    99. this.blueTeam.remove(p);
    100.  
    101. this.playing.remove(p);
    102. this.getLogger().info("Player " + p + " has been kicked.");
    103. p.sendMessage(ChatColor.RED + "You have been kicked from the game!");
    104. }
    105.  
    106. }
    107. }
    108. }
     
  6. Offline

    WauloK

    Hmm. Not sure. I'd rather add player Names to a list than the Player object itself. Don't know if that'd make things better...
     
  7. Offline

    Shzylo

    I have not ever thought about taking a player's name. If I were to do that, how would I get the player? Ex:

    for (String playerName : myList) {
    // send a message to them.
    }
     
  8. Offline

    WauloK

    Code:java
    1. Player player = getServer().getPlayer(playerName);
     
  9. Offline

    Shzylo

    WauloK I tried using strings instead, I get the same error at the same location.
     
  10. Offline

    bobacadodl

    Shzylo
    This error is occurring because you can't remove elements from a list at the same time you are iterating through it! (ConcurrentModificationException! Look it up!!)

    Code:
    for (Player p : playing) {
                if (this.redTeam.contains(p))
                    this.redTeam.remove(p);
                if (this.blueTeam.contains(p))
                    this.blueTeam.remove(p);
     
                this.playing.remove(p);
                this.getLogger().info("Player " + p + " has been kicked.");
                p.sendMessage(ChatColor.RED + "You have been kicked from the game!");
            }
    Instead.. do something like:
    Code:
    List<Player> toRemove = new ArrayList<Player>();
    List<Player> blueToRemove = new ArrayList<Player>();
    List<Player> redToRemove = new ArrayList<Player>();
    for (Player p : playing) {
                if (this.redTeam.contains(p))
                    redToRemove.add(p);
                    //this.redTeam.remove(p);
                if (this.blueTeam.contains(p))
                    blueToRemove.add(p);
                    //this.blueTeam.remove(p);
                toRemove.add(p);
                //this.playing.remove(p);
                this.getLogger().info("Player " + p + " has been kicked.");
                p.sendMessage(ChatColor.RED + "You have been kicked from the game!");
            }
    for(Player p:blueToRemove){
      this.blueTeam.remove(p);
    }
    for(Player p:redToRemove){
      this.redTeam.remove(p);
    }
    for(Player p:toRemove){
      this.playing.remove(p);
    }
     
Thread Status:
Not open for further replies.

Share This Page