diff --git a/src/com/massivecraft/factions/FPlayer.java b/src/com/massivecraft/factions/FPlayer.java index d73d91dd..a0a67a92 100644 --- a/src/com/massivecraft/factions/FPlayer.java +++ b/src/com/massivecraft/factions/FPlayer.java @@ -1,6 +1,5 @@ package com.massivecraft.factions; -import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -45,6 +44,9 @@ public class FPlayer extends PlayerEntity implements EconomyParticipator public boolean hasFaction() { return ! factionId.equals("0"); } public void setFaction(Faction faction) { + Faction oldFaction = this.getFaction(); + if (oldFaction != null) oldFaction.removeFPlayer(this); + faction.addFPlayer(this); this.factionId = faction.getId(); SpoutFeatures.updateAppearances(this.getPlayer()); } @@ -171,6 +173,7 @@ public class FPlayer extends PlayerEntity implements EconomyParticipator if (Factions.i.exists(this.getFactionId())) { Faction currentFaction = this.getFaction(); + currentFaction.removeFPlayer(this); if (currentFaction.isNormal()) { currentFaction.clearClaimOwnership(this.getId()); @@ -604,8 +607,7 @@ public class FPlayer extends PlayerEntity implements EconomyParticipator } // Am I the last one in the faction? - ArrayList fplayers = myFaction.getFPlayers(); - if (fplayers.size() == 1 && fplayers.get(0) == this) + if (myFaction.getFPlayers().size() == 1) { // Transfer all money if (Econ.shouldBeUsed()) diff --git a/src/com/massivecraft/factions/Faction.java b/src/com/massivecraft/factions/Faction.java index 45472c16..c49c25e5 100644 --- a/src/com/massivecraft/factions/Faction.java +++ b/src/com/massivecraft/factions/Faction.java @@ -27,7 +27,11 @@ public class Faction extends Entity implements EconomyParticipator // FIELD: claimOwnership private Map> claimOwnership = new ConcurrentHashMap>(); - + + // FIELD: fplayers + // speedy lookup of players in faction + private Set fplayers = new HashSet(); + // FIELD: invites // Where string is a lowercase player name private Set invites; @@ -265,7 +269,7 @@ public class Faction extends Entity implements EconomyParticipator } double ret = 0; - for (FPlayer fplayer : this.getFPlayers()) + for (FPlayer fplayer : fplayers) { ret += fplayer.getPower(); } @@ -284,7 +288,7 @@ public class Faction extends Entity implements EconomyParticipator } double ret = 0; - for (FPlayer fplayer : this.getFPlayers()) + for (FPlayer fplayer : fplayers) { ret += fplayer.getPowerMax(); } @@ -322,31 +326,48 @@ public class Faction extends Entity implements EconomyParticipator // ------------------------------- // FPlayers // ------------------------------- - - public ArrayList getFPlayers() + + // maintain the reference list of FPlayers in this faction + public void refreshFPlayers() { - ArrayList ret = new ArrayList(); - if (this.isPlayerFreeType()) return ret; + fplayers.clear(); + if (this.isPlayerFreeType()) return; for (FPlayer fplayer : FPlayers.i.get()) { if (fplayer.getFaction() == this) { - ret.add(fplayer); + fplayers.add(fplayer); } } + } + public boolean addFPlayer(FPlayer fplayer) + { + if (this.isPlayerFreeType()) return false; + return fplayers.add(fplayer); + } + public boolean removeFPlayer(FPlayer fplayer) + { + if (this.isPlayerFreeType()) return false; + + return fplayers.remove(fplayer); + } + + public Set getFPlayers() + { + // return a shallow copy of the FPlayer list, to prevent tampering and concurrency issues + Set ret = new HashSet(fplayers); return ret; } - public ArrayList getFPlayersWhereOnline(boolean online) + public Set getFPlayersWhereOnline(boolean online) { - ArrayList ret = new ArrayList(); - if (this.isPlayerFreeType()) return ret; + Set ret = new HashSet(); - for (FPlayer fplayer : FPlayers.i.get()) + for (FPlayer fplayer : fplayers) { - if (fplayer.getFaction() == this && fplayer.isOnline() == online) + if (fplayer.isOnline() == online) { ret.add(fplayer); } @@ -359,9 +380,9 @@ public class Faction extends Entity implements EconomyParticipator { if ( ! this.isNormal()) return null; - for (FPlayer fplayer : FPlayers.i.get()) + for (FPlayer fplayer : fplayers) { - if (fplayer.getFaction() == this && fplayer.getRole() == Role.ADMIN) + if (fplayer.getRole() == Role.ADMIN) { return fplayer; } @@ -374,9 +395,9 @@ public class Faction extends Entity implements EconomyParticipator ArrayList ret = new ArrayList(); if ( ! this.isNormal()) return ret; - for (FPlayer fplayer : FPlayers.i.get()) + for (FPlayer fplayer : fplayers) { - if (fplayer.getFaction() == this && fplayer.getRole() == role) + if (fplayer.getRole() == role) { ret.add(fplayer); } diff --git a/src/com/massivecraft/factions/Factions.java b/src/com/massivecraft/factions/Factions.java index 250de1c2..dd166eb6 100644 --- a/src/com/massivecraft/factions/Factions.java +++ b/src/com/massivecraft/factions/Factions.java @@ -80,7 +80,13 @@ public class Factions extends EntityCollection if (faction.getTag().contains(" ")) faction.setTag("WarZone"); } - + + // populate all faction player lists + for (Faction faction : i.get()) + { + faction.refreshFPlayers(); + } + return true; }