Abstract Data storage method for future implementations. Thanks to Ryan from Reactive MC

Also included:
-Heavily optimized loading process
-Optimizations for various commands.
This commit is contained in:
t00thpick1 2014-10-19 01:37:25 -04:00
parent 48e43ceba0
commit ee52016a87
65 changed files with 3229 additions and 2577 deletions

View File

@ -1,145 +1,65 @@
package com.massivecraft.factions;
import com.google.gson.reflect.TypeToken;
import com.massivecraft.factions.struct.Relation;
import com.massivecraft.factions.util.AsciiCompass;
import com.massivecraft.factions.zcore.util.DiscUtil;
import org.bukkit.ChatColor;
import java.io.File;
import java.lang.reflect.Type;
import java.util.*;
import java.util.Map.Entry;
import com.massivecraft.factions.zcore.persist.json.JSONBoard;
public class Board {
private static transient File file = new File(P.p.getDataFolder(), "board.json");
private static transient HashMap<FLocation, String> flocationIds = new HashMap<FLocation, String>();
public abstract class Board {
protected static Board instance = getBoardImpl();
//----------------------------------------------//
// Get and Set
//----------------------------------------------//
public static String getIdAt(FLocation flocation) {
if (!flocationIds.containsKey(flocation)) {
return "0";
public abstract String getIdAt(FLocation flocation);
private static Board getBoardImpl() {
switch (Conf.backEnd) {
case JSON:
return new JSONBoard();
}
return flocationIds.get(flocation);
return null;
}
public static Faction getFactionAt(FLocation flocation) {
return Factions.i.get(getIdAt(flocation));
public static Board getInstance() {
return instance;
}
public static void setIdAt(String id, FLocation flocation) {
clearOwnershipAt(flocation);
public abstract Faction getFactionAt(FLocation flocation);
if (id.equals("0")) {
removeAt(flocation);
}
public abstract void setIdAt(String id, FLocation flocation);
flocationIds.put(flocation, id);
}
public abstract void setFactionAt(Faction faction, FLocation flocation);
public static void setFactionAt(Faction faction, FLocation flocation) {
setIdAt(faction.getId(), flocation);
}
public static void removeAt(FLocation flocation) {
clearOwnershipAt(flocation);
flocationIds.remove(flocation);
}
public abstract void removeAt(FLocation flocation);
// not to be confused with claims, ownership referring to further member-specific ownership of a claim
public static void clearOwnershipAt(FLocation flocation) {
Faction faction = getFactionAt(flocation);
if (faction != null && faction.isNormal()) {
faction.clearClaimOwnership(flocation);
}
}
public abstract void clearOwnershipAt(FLocation flocation);
public static void unclaimAll(String factionId) {
Faction faction = Factions.i.get(factionId);
if (faction != null && faction.isNormal()) {
faction.clearAllClaimOwnership();
}
Iterator<Entry<FLocation, String>> iter = flocationIds.entrySet().iterator();
while (iter.hasNext()) {
Entry<FLocation, String> entry = iter.next();
if (entry.getValue().equals(factionId)) {
iter.remove();
}
}
}
public abstract void unclaimAll(String factionId);
// Is this coord NOT completely surrounded by coords claimed by the same faction?
// Simpler: Is there any nearby coord with a faction other than the faction here?
public static boolean isBorderLocation(FLocation flocation) {
Faction faction = getFactionAt(flocation);
FLocation a = flocation.getRelative(1, 0);
FLocation b = flocation.getRelative(-1, 0);
FLocation c = flocation.getRelative(0, 1);
FLocation d = flocation.getRelative(0, -1);
return faction != getFactionAt(a) || faction != getFactionAt(b) || faction != getFactionAt(c) || faction != getFactionAt(d);
}
public abstract boolean isBorderLocation(FLocation flocation);
// Is this coord connected to any coord claimed by the specified faction?
public static boolean isConnectedLocation(FLocation flocation, Faction faction) {
FLocation a = flocation.getRelative(1, 0);
FLocation b = flocation.getRelative(-1, 0);
FLocation c = flocation.getRelative(0, 1);
FLocation d = flocation.getRelative(0, -1);
return faction == getFactionAt(a) || faction == getFactionAt(b) || faction == getFactionAt(c) || faction == getFactionAt(d);
}
public abstract boolean isConnectedLocation(FLocation flocation, Faction faction);
//----------------------------------------------//
// Cleaner. Remove orphaned foreign keys
//----------------------------------------------//
public static void clean() {
Iterator<Entry<FLocation, String>> iter = flocationIds.entrySet().iterator();
while (iter.hasNext()) {
Entry<FLocation, String> entry = iter.next();
if (!Factions.i.exists(entry.getValue())) {
P.p.log("Board cleaner removed " + entry.getValue() + " from " + entry.getKey());
iter.remove();
}
}
}
public abstract void clean();
//----------------------------------------------//
// Coord count
//----------------------------------------------//
public static int getFactionCoordCount(String factionId) {
int ret = 0;
for (String thatFactionId : flocationIds.values()) {
if (thatFactionId.equals(factionId)) {
ret += 1;
}
}
return ret;
}
public abstract int getFactionCoordCount(String factionId);
public static int getFactionCoordCount(Faction faction) {
return getFactionCoordCount(faction.getId());
}
public abstract int getFactionCoordCount(Faction faction);
public static int getFactionCoordCountInWorld(Faction faction, String worldName) {
String factionId = faction.getId();
int ret = 0;
Iterator<Entry<FLocation, String>> iter = flocationIds.entrySet().iterator();
while (iter.hasNext()) {
Entry<FLocation, String> entry = iter.next();
if (entry.getValue().equals(factionId) && entry.getKey().getWorldName().equals(worldName)) {
ret += 1;
}
}
return ret;
}
public abstract int getFactionCoordCountInWorld(Faction faction, String worldName);
//----------------------------------------------//
// Map generation
@ -149,158 +69,9 @@ public class Board {
* The map is relative to a coord and a faction north is in the direction of decreasing x east is in the direction
* of decreasing z
*/
public static ArrayList<String> getMap(Faction faction, FLocation flocation, double inDegrees) {
ArrayList<String> ret = new ArrayList<String>();
Faction factionLoc = getFactionAt(flocation);
ret.add(P.p.txt.titleize("(" + flocation.getCoordString() + ") " + factionLoc.getTag(faction)));
public abstract ArrayList<String> getMap(Faction faction, FLocation flocation, double inDegrees);
int halfWidth = Conf.mapWidth / 2;
int halfHeight = Conf.mapHeight / 2;
FLocation topLeft = flocation.getRelative(-halfWidth, -halfHeight);
int width = halfWidth * 2 + 1;
int height = halfHeight * 2 + 1;
public abstract boolean forceSave();
if (Conf.showMapFactionKey) {
height--;
}
Map<String, Character> fList = new HashMap<String, Character>();
int chrIdx = 0;
// For each row
for (int dz = 0; dz < height; dz++) {
// Draw and add that row
String row = "";
for (int dx = 0; dx < width; dx++) {
if (dx == halfWidth && dz == halfHeight) {
row += ChatColor.AQUA + "+";
} else {
FLocation flocationHere = topLeft.getRelative(dx, dz);
Faction factionHere = getFactionAt(flocationHere);
Relation relation = faction.getRelationTo(factionHere);
if (factionHere.isNone()) {
row += ChatColor.GRAY + "-";
} else if (factionHere.isSafeZone()) {
row += Conf.colorPeaceful + "+";
} else if (factionHere.isWarZone()) {
row += ChatColor.DARK_RED + "+";
} else if (factionHere == faction ||
factionHere == factionLoc ||
relation.isAtLeast(Relation.ALLY) ||
(Conf.showNeutralFactionsOnMap && relation.equals(Relation.NEUTRAL)) ||
(Conf.showEnemyFactionsOnMap && relation.equals(Relation.ENEMY))) {
if (!fList.containsKey(factionHere.getTag())) {
fList.put(factionHere.getTag(), Conf.mapKeyChrs[chrIdx++]);
}
char tag = fList.get(factionHere.getTag());
row += factionHere.getColorTo(faction) + "" + tag;
} else {
row += ChatColor.GRAY + "-";
}
}
}
ret.add(row);
}
// Get the compass
ArrayList<String> asciiCompass = AsciiCompass.getAsciiCompass(inDegrees, ChatColor.RED, P.p.txt.parse("<a>"));
// Add the compass
ret.set(1, asciiCompass.get(0) + ret.get(1).substring(3 * 3));
ret.set(2, asciiCompass.get(1) + ret.get(2).substring(3 * 3));
ret.set(3, asciiCompass.get(2) + ret.get(3).substring(3 * 3));
// Add the faction key
if (Conf.showMapFactionKey) {
String fRow = "";
for (String key : fList.keySet()) {
fRow += String.format("%s%s: %s ", ChatColor.GRAY, fList.get(key), key);
}
ret.add(fRow);
}
return ret;
}
// -------------------------------------------- //
// Persistance
// -------------------------------------------- //
public static Map<String, Map<String, String>> dumpAsSaveFormat() {
Map<String, Map<String, String>> worldCoordIds = new HashMap<String, Map<String, String>>();
String worldName, coords;
String id;
for (Entry<FLocation, String> entry : flocationIds.entrySet()) {
worldName = entry.getKey().getWorldName();
coords = entry.getKey().getCoordString();
id = entry.getValue();
if (!worldCoordIds.containsKey(worldName)) {
worldCoordIds.put(worldName, new TreeMap<String, String>());
}
worldCoordIds.get(worldName).put(coords, id);
}
return worldCoordIds;
}
public static void loadFromSaveFormat(Map<String, Map<String, String>> worldCoordIds) {
flocationIds.clear();
String worldName;
String[] coords;
int x, z;
String factionId;
for (Entry<String, Map<String, String>> entry : worldCoordIds.entrySet()) {
worldName = entry.getKey();
for (Entry<String, String> entry2 : entry.getValue().entrySet()) {
coords = entry2.getKey().trim().split("[,\\s]+");
x = Integer.parseInt(coords[0]);
z = Integer.parseInt(coords[1]);
factionId = entry2.getValue();
flocationIds.put(new FLocation(worldName, x, z), factionId);
}
}
}
public static boolean save() {
//Factions.log("Saving board to disk");
try {
DiscUtil.write(file, P.p.gson.toJson(dumpAsSaveFormat()));
} catch (Exception e) {
e.printStackTrace();
P.p.log("Failed to save the board to disk.");
return false;
}
return true;
}
public static boolean load() {
P.p.log("Loading board from disk");
if (!file.exists()) {
P.p.log("No board to load from disk. Creating new file.");
save();
return true;
}
try {
Type type = new TypeToken<Map<String, Map<String, String>>>() {
}.getType();
Map<String, Map<String, String>> worldCoordIds = P.p.gson.fromJson(DiscUtil.read(file), type);
loadFromSaveFormat(worldCoordIds);
} catch (Exception e) {
e.printStackTrace();
P.p.log("Failed to load the board from disk.");
return false;
}
return true;
}
public abstract boolean load();
}

View File

@ -260,9 +260,11 @@ public class Conf {
public static Set<String> worldsIgnorePvP = new LinkedHashSet<String>();
public static Set<String> worldsNoWildernessProtection = new LinkedHashSet<String>();
public static Backend backEnd = Backend.JSON;
public static transient int mapHeight = 8;
public static transient int mapWidth = 39;
public static transient char[] mapKeyChrs = "\\/#?$%=&^ABCDEFGHJKLMNOPQRSTUVWXYZ1234567890abcdeghjmnopqrsuvwxyz".toCharArray();
public static transient char[] mapKeyChrs = "\\/#$%=&^ABCDEFGHJKLMNOPQRSTUVWXYZ1234567890abcdeghjmnopqrsuvwxyz?".toCharArray();
static {
baseCommandAliases.add("f");
@ -355,5 +357,11 @@ public class Conf {
public static void save() {
P.p.persist.save(i);
}
public enum Backend {
JSON,
//MYSQL, TODO
;
}
}

View File

@ -1,18 +1,20 @@
package com.massivecraft.factions;
import com.massivecraft.factions.util.MiscUtil;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.io.Serializable;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
public class FLocation {
public class FLocation implements Serializable {
private static final long serialVersionUID = -8292915234027387983L;
private String worldName = "world";
private int x = 0;
private int z = 0;
@ -88,6 +90,17 @@ public class FLocation {
return "[" + this.getWorldName() + "," + this.getCoordString() + "]";
}
public static FLocation fromString(String string) {
int index = string.indexOf(",", 0);
int start = 1;
String worldName = string.substring(start, index);
start = index + 1;
index = string.indexOf(",", start);
int x = Integer.valueOf(string.substring(start, index));
int y = Integer.valueOf(string.substring(index + 1, string.length() - 1));
return new FLocation(worldName, x, y);
}
//----------------------------------------------//
// Block/Chunk/Region Value Transformation
//----------------------------------------------//

View File

@ -1,29 +1,17 @@
package com.massivecraft.factions;
import com.massivecraft.factions.event.FPlayerLeaveEvent;
import com.massivecraft.factions.event.LandClaimEvent;
import java.util.List;
import com.massivecraft.factions.iface.EconomyParticipator;
import com.massivecraft.factions.iface.RelationParticipator;
import com.massivecraft.factions.integration.Econ;
import com.massivecraft.factions.integration.Worldguard;
import com.massivecraft.factions.scoreboards.FScoreboard;
import com.massivecraft.factions.scoreboards.sidebar.FInfoSidebar;
import com.massivecraft.factions.struct.ChatMode;
import com.massivecraft.factions.struct.Permission;
import com.massivecraft.factions.struct.Relation;
import com.massivecraft.factions.struct.Role;
import com.massivecraft.factions.util.RelationUtil;
import com.massivecraft.factions.zcore.persist.PlayerEntity;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* Logged in players always have exactly one FPlayer instance. Logged out players may or may not have an FPlayer
@ -36,520 +24,165 @@ import java.util.UUID;
* necessary.
*/
public class FPlayer extends PlayerEntity implements EconomyParticipator {
//private transient String playerName;
private transient FLocation lastStoodAt = new FLocation(); // Where did this player stand the last time we checked?
public interface FPlayer extends EconomyParticipator {
public Faction getFaction();
// FIELD: factionId
private String factionId;
public String getFactionId();
public Faction getFaction() {
if (this.factionId == null) {
return null;
}
return Factions.i.get(this.factionId);
}
public boolean hasFaction();
public String getFactionId() {
return this.factionId;
}
public void setFaction(Faction faction);
public boolean hasFaction() {
return !factionId.equals("0");
}
public Role getRole();
public void setFaction(Faction faction) {
Faction oldFaction = this.getFaction();
if (oldFaction != null) {
oldFaction.removeFPlayer(this);
}
faction.addFPlayer(this);
this.factionId = faction.getId();
}
public void setRole(Role role);
// FIELD: role
private Role role;
public double getPowerBoost();
public Role getRole() {
return this.role;
}
public void setPowerBoost(double powerBoost);
public void setRole(Role role) {
this.role = role;
}
public Faction getAutoClaimFor();
// FIELD: title
private String title;
public void setAutoClaimFor(Faction faction);
// FIELD: power
private double power;
public boolean isAutoSafeClaimEnabled();
// FIELD: powerBoost
// special increase/decrease to min and max power for this player
private double powerBoost;
public void setIsAutoSafeClaimEnabled(boolean enabled);
public double getPowerBoost() {
return this.powerBoost;
}
public boolean isAutoWarClaimEnabled();
public void setPowerBoost(double powerBoost) {
this.powerBoost = powerBoost;
}
public void setIsAutoWarClaimEnabled(boolean enabled);
// FIELD: lastPowerUpdateTime
private long lastPowerUpdateTime;
public boolean isAdminBypassing();
// FIELD: lastLoginTime
private long lastLoginTime;
public void setIsAdminBypassing(boolean val);
// FIELD: mapAutoUpdating
private transient boolean mapAutoUpdating;
public void setChatMode(ChatMode chatMode);
// FIELD: autoClaimEnabled
private transient Faction autoClaimFor;
public ChatMode getChatMode();
public Faction getAutoClaimFor() {
return autoClaimFor;
}
public void setSpyingChat(boolean chatSpying);
public void setAutoClaimFor(Faction faction) {
this.autoClaimFor = faction;
if (this.autoClaimFor != null) {
// TODO: merge these into same autoclaim
this.autoSafeZoneEnabled = false;
this.autoWarZoneEnabled = false;
}
}
// FIELD: autoSafeZoneEnabled
private transient boolean autoSafeZoneEnabled;
public boolean isAutoSafeClaimEnabled() {
return autoSafeZoneEnabled;
}
public void setIsAutoSafeClaimEnabled(boolean enabled) {
this.autoSafeZoneEnabled = enabled;
if (enabled) {
this.autoClaimFor = null;
this.autoWarZoneEnabled = false;
}
}
// FIELD: autoWarZoneEnabled
private transient boolean autoWarZoneEnabled;
public boolean isAutoWarClaimEnabled() {
return autoWarZoneEnabled;
}
public void setIsAutoWarClaimEnabled(boolean enabled) {
this.autoWarZoneEnabled = enabled;
if (enabled) {
this.autoClaimFor = null;
this.autoSafeZoneEnabled = false;
}
}
private transient boolean isAdminBypassing = false;
public boolean isAdminBypassing() {
return this.isAdminBypassing;
}
public void setIsAdminBypassing(boolean val) {
this.isAdminBypassing = val;
}
// FIELD: loginPvpDisabled
private transient boolean loginPvpDisabled;
// FIELD: deleteMe
private transient boolean deleteMe;
// FIELD: chatMode
private ChatMode chatMode;
public void setChatMode(ChatMode chatMode) {
this.chatMode = chatMode;
}
public ChatMode getChatMode() {
if (this.factionId.equals("0") || !Conf.factionOnlyChat) {
this.chatMode = ChatMode.PUBLIC;
}
return chatMode;
}
// FIELD: chatSpy
private transient boolean spyingChat = false;
public void setSpyingChat(boolean chatSpying) {
this.spyingChat = chatSpying;
}
public boolean isSpyingChat() {
return spyingChat;
}
public boolean isSpyingChat();
// FIELD: account
public String getAccountId() {
return this.getId();
}
public String getAccountId();
// -------------------------------------------- //
// Construct
// -------------------------------------------- //
public void resetFactionData(boolean doSpoutUpdate);
// GSON need this noarg constructor.
public FPlayer() {
this.resetFactionData(false);
this.power = Conf.powerPlayerStarting;
this.lastPowerUpdateTime = System.currentTimeMillis();
this.lastLoginTime = System.currentTimeMillis();
this.mapAutoUpdating = false;
this.autoClaimFor = null;
this.autoSafeZoneEnabled = false;
this.autoWarZoneEnabled = false;
this.loginPvpDisabled = Conf.noPVPDamageToOthersForXSecondsAfterLogin > 0;
this.deleteMe = false;
this.powerBoost = 0.0;
public void resetFactionData();
if (!Conf.newPlayerStartingFactionID.equals("0") && Factions.i.exists(Conf.newPlayerStartingFactionID)) {
this.factionId = Conf.newPlayerStartingFactionID;
}
}
public long getLastLoginTime();
public final void resetFactionData(boolean doSpoutUpdate) {
// clean up any territory ownership in old faction, if there is one
if (Factions.i.exists(this.getFactionId())) {
Faction currentFaction = this.getFaction();
currentFaction.removeFPlayer(this);
if (currentFaction.isNormal()) {
currentFaction.clearClaimOwnership(this);
}
}
public void setLastLoginTime(long lastLoginTime);
this.factionId = "0"; // The default neutral faction
this.chatMode = ChatMode.PUBLIC;
this.role = Role.NORMAL;
this.title = "";
this.autoClaimFor = null;
}
public boolean isMapAutoUpdating();
public void resetFactionData() {
this.resetFactionData(true);
}
public void setMapAutoUpdating(boolean mapAutoUpdating);
// -------------------------------------------- //
// Getters And Setters
// -------------------------------------------- //
public boolean hasLoginPvpDisabled();
public FLocation getLastStoodAt();
public long getLastLoginTime() {
return lastLoginTime;
}
public void setLastStoodAt(FLocation flocation);
public String getTitle();
public void setLastLoginTime(long lastLoginTime) {
losePowerFromBeingOffline();
this.lastLoginTime = lastLoginTime;
this.lastPowerUpdateTime = lastLoginTime;
if (Conf.noPVPDamageToOthersForXSecondsAfterLogin > 0) {
this.loginPvpDisabled = true;
}
}
public void setTitle(String title);
public boolean isMapAutoUpdating() {
return mapAutoUpdating;
}
public String getName();
public void setMapAutoUpdating(boolean mapAutoUpdating) {
this.mapAutoUpdating = mapAutoUpdating;
}
public boolean hasLoginPvpDisabled() {
if (!loginPvpDisabled) {
return false;
}
if (this.lastLoginTime + (Conf.noPVPDamageToOthersForXSecondsAfterLogin * 1000) < System.currentTimeMillis()) {
this.loginPvpDisabled = false;
return false;
}
return true;
}
public FLocation getLastStoodAt() {
return this.lastStoodAt;
}
public void setLastStoodAt(FLocation flocation) {
this.lastStoodAt = flocation;
}
public void markForDeletion(boolean delete) {
deleteMe = delete;
}
//----------------------------------------------//
// Title, Name, Faction Tag and Chat
//----------------------------------------------//
// Base:
public String getTitle() {
return this.hasFaction() ? title : "";
}
public void setTitle(String title) {
this.title = title;
}
public String getName() {
if (isOnline()) {
return getPlayer().getName();
}
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(getId()));
return player.getName() != null ? player.getName() : getId();
}
public String getTag() {
return this.hasFaction() ? this.getFaction().getTag() : "";
}
public String getTag();
// Base concatenations:
public String getNameAndSomething(String something) {
String ret = this.role.getPrefix();
if (something.length() > 0) {
ret += something + " ";
}
ret += this.getName();
return ret;
}
public String getNameAndSomething(String something);
public String getNameAndTitle() {
return this.getNameAndSomething(this.getTitle());
}
public String getNameAndTitle();
public String getNameAndTag() {
return this.getNameAndSomething(this.getTag());
}
public String getNameAndTag();
// Colored concatenations:
// These are used in information messages
public String getNameAndTitle(Faction faction) {
return this.getColorTo(faction) + this.getNameAndTitle();
}
public String getNameAndTitle(Faction faction);
public String getNameAndTitle(FPlayer fplayer) {
return this.getColorTo(fplayer) + this.getNameAndTitle();
}
/*public String getNameAndTag(Faction faction)
{
return this.getRelationColor(faction)+this.getNameAndTag();
}
public String getNameAndTag(FPlayer fplayer)
{
return this.getRelationColor(fplayer)+this.getNameAndTag();
}*/
// TODO: Removed for refactoring.
/*public String getNameAndRelevant(Faction faction)
{
// Which relation?
Relation rel = this.getRelationTo(faction);
// For member we show title
if (rel == Relation.MEMBER) {
return rel.getColor() + this.getNameAndTitle();
}
// For non members we show tag
return rel.getColor() + this.getNameAndTag();
}
public String getNameAndRelevant(FPlayer fplayer)
{
return getNameAndRelevant(fplayer.getFaction());
}*/
public String getNameAndTitle(FPlayer fplayer);
// Chat Tag:
// These are injected into the format of global chat messages.
public String getChatTag() {
return this.hasFaction() ? String.format(Conf.chatTagFormat, this.role.getPrefix() + this.getTag()) : "";
}
public String getChatTag();
// Colored Chat Tag
public String getChatTag(Faction faction) {
return this.hasFaction() ? this.getRelationTo(faction).getColor() + getChatTag() : "";
}
public String getChatTag(Faction faction);
public String getChatTag(FPlayer fplayer) {
return this.hasFaction() ? this.getColorTo(fplayer) + getChatTag() : "";
}
public String getChatTag(FPlayer fplayer);
// -------------------------------
// Relation and relation colors
// -------------------------------
@Override
public String describeTo(RelationParticipator that, boolean ucfirst) {
return RelationUtil.describeThatToMe(this, that, ucfirst);
}
public String describeTo(RelationParticipator that, boolean ucfirst);
@Override
public String describeTo(RelationParticipator that) {
return RelationUtil.describeThatToMe(this, that);
}
public String describeTo(RelationParticipator that);
@Override
public Relation getRelationTo(RelationParticipator rp) {
return RelationUtil.getRelationTo(this, rp);
}
public Relation getRelationTo(RelationParticipator rp);
@Override
public Relation getRelationTo(RelationParticipator rp, boolean ignorePeaceful) {
return RelationUtil.getRelationTo(this, rp, ignorePeaceful);
}
public Relation getRelationTo(RelationParticipator rp, boolean ignorePeaceful);
public Relation getRelationToLocation() {
return Board.getFactionAt(new FLocation(this)).getRelationTo(this);
}
public Relation getRelationToLocation();
@Override
public ChatColor getColorTo(RelationParticipator rp) {
return RelationUtil.getColorOfThatToMe(this, rp);
}
public ChatColor getColorTo(RelationParticipator rp);
//----------------------------------------------//
// Health
//----------------------------------------------//
public void heal(int amnt) {
Player player = this.getPlayer();
if (player == null) {
return;
}
player.setHealth(player.getHealth() + amnt);
}
public void heal(int amnt);
//----------------------------------------------//
// Power
//----------------------------------------------//
public double getPower() {
this.updatePower();
return this.power;
}
public double getPower();
protected void alterPower(double delta) {
this.power += delta;
if (this.power > this.getPowerMax()) {
this.power = this.getPowerMax();
} else if (this.power < this.getPowerMin()) {
this.power = this.getPowerMin();
}
}
public void alterPower(double delta);
public double getPowerMax() {
return Conf.powerPlayerMax + this.powerBoost;
}
public double getPowerMax();
public double getPowerMin() {
return Conf.powerPlayerMin + this.powerBoost;
}
public double getPowerMin();
public int getPowerRounded() {
return (int) Math.round(this.getPower());
}
public int getPowerRounded();
public int getPowerMaxRounded() {
return (int) Math.round(this.getPowerMax());
}
public int getPowerMaxRounded();
public int getPowerMinRounded() {
return (int) Math.round(this.getPowerMin());
}
public int getPowerMinRounded();
protected void updatePower() {
if (this.isOffline()) {
losePowerFromBeingOffline();
if (!Conf.powerRegenOffline) {
return;
}
}
long now = System.currentTimeMillis();
long millisPassed = now - this.lastPowerUpdateTime;
this.lastPowerUpdateTime = now;
public void updatePower();
Player thisPlayer = this.getPlayer();
if (thisPlayer != null && thisPlayer.isDead()) {
return; // don't let dead players regain power until they respawn
}
public void losePowerFromBeingOffline();
int millisPerMinute = 60 * 1000;
this.alterPower(millisPassed * Conf.powerPerMinute / millisPerMinute);
}
protected void losePowerFromBeingOffline() {
if (Conf.powerOfflineLossPerDay > 0.0 && this.power > Conf.powerOfflineLossLimit) {
long now = System.currentTimeMillis();
long millisPassed = now - this.lastPowerUpdateTime;
this.lastPowerUpdateTime = now;
double loss = millisPassed * Conf.powerOfflineLossPerDay / (24 * 60 * 60 * 1000);
if (this.power - loss < Conf.powerOfflineLossLimit) {
loss = this.power;
}
this.alterPower(-loss);
}
}
public void onDeath() {
this.updatePower();
this.alterPower(-Conf.powerPerDeath);
}
public void onDeath();
//----------------------------------------------//
// Territory
//----------------------------------------------//
public boolean isInOwnTerritory() {
return Board.getFactionAt(new FLocation(this)) == this.getFaction();
}
public boolean isInOwnTerritory();
public boolean isInOthersTerritory() {
Faction factionHere = Board.getFactionAt(new FLocation(this));
return factionHere != null && factionHere.isNormal() && factionHere != this.getFaction();
}
public boolean isInOthersTerritory();
public boolean isInAllyTerritory() {
return Board.getFactionAt(new FLocation(this)).getRelationTo(this).isAlly();
}
public boolean isInAllyTerritory();
public boolean isInNeutralTerritory() {
return Board.getFactionAt(new FLocation(this)).getRelationTo(this).isNeutral();
}
public boolean isInNeutralTerritory();
public boolean isInEnemyTerritory() {
return Board.getFactionAt(new FLocation(this)).getRelationTo(this).isEnemy();
}
public boolean isInEnemyTerritory();
public void sendFactionHereMessage() {
Faction toShow = Board.getFactionAt(getLastStoodAt());
if (shouldShowScoreboard(toShow)) {
// Shows them the scoreboard instead of sending a message in chat. Will disappear after a few seconds.
FScoreboard.get(this).setTemporarySidebar(new FInfoSidebar(toShow));
} else {
String msg = P.p.txt.parse("<i>") + " ~ " + toShow.getTag(this);
if (toShow.getDescription().length() > 0) {
msg += " - " + toShow.getDescription();
}
this.sendMessage(msg);
}
}
public void sendFactionHereMessage();
/**
* Check if the scoreboard should be shown. Simple method to be used by above method.
@ -558,227 +191,37 @@ public class FPlayer extends PlayerEntity implements EconomyParticipator {
*
* @return true if should show, otherwise false.
*/
private boolean shouldShowScoreboard(Faction toShow) {
return !toShow.isWarZone() && !toShow.isNone() && !toShow.isSafeZone() && P.p.getConfig().contains("scoreboard.finfo") && P.p.getConfig().getBoolean("scoreboard.finfo-enabled", false) && P.p.cmdBase.cmdSB.showBoard(this);
}
public boolean shouldShowScoreboard(Faction toShow);
// -------------------------------
// Actions
// -------------------------------
public void leave(boolean makePay) {
Faction myFaction = this.getFaction();
makePay = makePay && Econ.shouldBeUsed() && !this.isAdminBypassing();
public void leave(boolean makePay);
if (myFaction == null) {
resetFactionData();
return;
}
public boolean canClaimForFaction(Faction forFaction);
boolean perm = myFaction.isPermanent();
public boolean canClaimForFactionAtLocation(Faction forFaction, Location location, boolean notifyFailure);
if (!perm && this.getRole() == Role.ADMIN && myFaction.getFPlayers().size() > 1) {
msg("<b>You must give the admin role to someone else first.");
return;
}
public boolean attemptClaim(Faction forFaction, Location location, boolean notifyFailure);
if (!Conf.canLeaveWithNegativePower && this.getPower() < 0) {
msg("<b>You cannot leave until your power is positive.");
return;
}
public void msg(String str, Object... args);
// if economy is enabled and they're not on the bypass list, make sure they can pay
if (makePay && !Econ.hasAtLeast(this, Conf.econCostLeave, "to leave your faction.")) {
return;
}
public String getId();
FPlayerLeaveEvent leaveEvent = new FPlayerLeaveEvent(this, myFaction, FPlayerLeaveEvent.PlayerLeaveReason.LEAVE);
Bukkit.getServer().getPluginManager().callEvent(leaveEvent);
if (leaveEvent.isCancelled()) {
return;
}
public Player getPlayer();
// then make 'em pay (if applicable)
if (makePay && !Econ.modifyMoney(this, -Conf.econCostLeave, "to leave your faction.", "for leaving your faction.")) {
return;
}
public boolean isOnline();
// Am I the last one in the faction?
if (myFaction.getFPlayers().size() == 1) {
// Transfer all money
if (Econ.shouldBeUsed()) {
Econ.transferMoney(this, myFaction, this, Econ.getBalance(myFaction.getAccountId()));
}
}
public void sendMessage(String message);
if (myFaction.isNormal()) {
for (FPlayer fplayer : myFaction.getFPlayersWhereOnline(true)) {
fplayer.msg("%s<i> left %s<i>.", this.describeTo(fplayer, true), myFaction.describeTo(fplayer));
}
public void sendMessage(List<String> messages);
if (Conf.logFactionLeave) {
P.p.log(this.getName() + " left the faction: " + myFaction.getTag());
}
}
public boolean isOnlineAndVisibleTo(Player me);
myFaction.removeAnnouncements(this);
this.resetFactionData();
public void remove();
if (myFaction.isNormal() && !perm && myFaction.getFPlayers().isEmpty()) {
// Remove this faction
for (FPlayer fplayer : FPlayers.i.getOnline()) {
fplayer.msg("<i>%s<i> was disbanded.", myFaction.describeTo(fplayer, true));
}
public boolean isOffline();
myFaction.detach();
if (Conf.logFactionDisband) {
P.p.log("The faction " + myFaction.getTag() + " (" + myFaction.getId() + ") was disbanded due to the last player (" + this.getName() + ") leaving.");
}
}
}
public boolean canClaimForFaction(Faction forFaction) {
return !forFaction.isNone() && (this.isAdminBypassing() || (forFaction == this.getFaction() && this.getRole().isAtLeast(Role.MODERATOR)) || (forFaction.isSafeZone() && Permission.MANAGE_SAFE_ZONE.has(getPlayer())) || (forFaction.isWarZone() && Permission.MANAGE_WAR_ZONE.has(getPlayer())));
}
public boolean canClaimForFactionAtLocation(Faction forFaction, Location location, boolean notifyFailure) {
String error = null;
FLocation flocation = new FLocation(location);
Faction myFaction = getFaction();
Faction currentFaction = Board.getFactionAt(flocation);
int ownedLand = forFaction.getLandRounded();
if (Conf.worldGuardChecking && Worldguard.checkForRegionsInChunk(location)) {
// Checks for WorldGuard regions in the chunk attempting to be claimed
error = P.p.txt.parse("<b>This land is protected");
} else if (Conf.worldsNoClaiming.contains(flocation.getWorldName())) {
error = P.p.txt.parse("<b>Sorry, this world has land claiming disabled.");
} else if (this.isAdminBypassing()) {
return true;
} else if (forFaction.isSafeZone() && Permission.MANAGE_SAFE_ZONE.has(getPlayer())) {
return true;
} else if (forFaction.isWarZone() && Permission.MANAGE_WAR_ZONE.has(getPlayer())) {
return true;
} else if (myFaction != forFaction) {
error = P.p.txt.parse("<b>You can't claim land for <h>%s<b>.", forFaction.describeTo(this));
} else if (forFaction == currentFaction) {
error = P.p.txt.parse("%s<i> already own this land.", forFaction.describeTo(this, true));
} else if (this.getRole().value < Role.MODERATOR.value) {
error = P.p.txt.parse("<b>You must be <h>%s<b> to claim land.", Role.MODERATOR.toString());
} else if (forFaction.getFPlayers().size() < Conf.claimsRequireMinFactionMembers) {
error = P.p.txt.parse("Factions must have at least <h>%s<b> members to claim land.", Conf.claimsRequireMinFactionMembers);
} else if (currentFaction.isSafeZone()) {
error = P.p.txt.parse("<b>You can not claim a Safe Zone.");
} else if (currentFaction.isWarZone()) {
error = P.p.txt.parse("<b>You can not claim a War Zone.");
} else if (ownedLand >= forFaction.getPowerRounded()) {
error = P.p.txt.parse("<b>You can't claim more land! You need more power!");
} else if (Conf.claimedLandsMax != 0 && ownedLand >= Conf.claimedLandsMax && forFaction.isNormal()) {
error = P.p.txt.parse("<b>Limit reached. You can't claim more land!");
} else if (currentFaction.getRelationTo(forFaction) == Relation.ALLY) {
error = P.p.txt.parse("<b>You can't claim the land of your allies.");
} else if (Conf.claimsMustBeConnected && !this.isAdminBypassing() && myFaction.getLandRoundedInWorld(flocation.getWorldName()) > 0 && !Board.isConnectedLocation(flocation, myFaction) && (!Conf.claimsCanBeUnconnectedIfOwnedByOtherFaction || !currentFaction.isNormal())) {
if (Conf.claimsCanBeUnconnectedIfOwnedByOtherFaction) {
error = P.p.txt.parse("<b>You can only claim additional land which is connected to your first claim or controlled by another faction!");
} else {
error = P.p.txt.parse("<b>You can only claim additional land which is connected to your first claim!");
}
} else if (currentFaction.isNormal()) {
if (myFaction.isPeaceful()) {
error = P.p.txt.parse("%s<i> owns this land. Your faction is peaceful, so you cannot claim land from other factions.", currentFaction.getTag(this));
} else if (currentFaction.isPeaceful()) {
error = P.p.txt.parse("%s<i> owns this land, and is a peaceful faction. You cannot claim land from them.", currentFaction.getTag(this));
} else if (!currentFaction.hasLandInflation()) {
// TODO more messages WARN current faction most importantly
error = P.p.txt.parse("%s<i> owns this land and is strong enough to keep it.", currentFaction.getTag(this));
} else if (!Board.isBorderLocation(flocation)) {
error = P.p.txt.parse("<b>You must start claiming land at the border of the territory.");
}
}
// TODO: Add more else if statements.
if (notifyFailure && error != null) {
msg(error);
}
return error == null;
}
public boolean attemptClaim(Faction forFaction, Location location, boolean notifyFailure) {
// notifyFailure is false if called by auto-claim; no need to notify on every failure for it
// return value is false on failure, true on success
FLocation flocation = new FLocation(location);
Faction currentFaction = Board.getFactionAt(flocation);
int ownedLand = forFaction.getLandRounded();
if (!this.canClaimForFactionAtLocation(forFaction, location, notifyFailure)) {
return false;
}
// if economy is enabled and they're not on the bypass list, make sure they can pay
boolean mustPay = Econ.shouldBeUsed() && !this.isAdminBypassing() && !forFaction.isSafeZone() && !forFaction.isWarZone();
double cost = 0.0;
EconomyParticipator payee = null;
if (mustPay) {
cost = Econ.calculateClaimCost(ownedLand, currentFaction.isNormal());
if (Conf.econClaimUnconnectedFee != 0.0 && forFaction.getLandRoundedInWorld(flocation.getWorldName()) > 0 && !Board.isConnectedLocation(flocation, forFaction)) {
cost += Conf.econClaimUnconnectedFee;
}
if (Conf.bankEnabled && Conf.bankFactionPaysLandCosts && this.hasFaction()) {
payee = this.getFaction();
} else {
payee = this;
}
if (!Econ.hasAtLeast(payee, cost, "to claim this land")) {
return false;
}
}
LandClaimEvent claimEvent = new LandClaimEvent(flocation, forFaction, this);
Bukkit.getServer().getPluginManager().callEvent(claimEvent);
if (claimEvent.isCancelled()) {
return false;
}
// then make 'em pay (if applicable)
if (mustPay && !Econ.modifyMoney(payee, -cost, "to claim this land", "for claiming this land")) {
return false;
}
// announce success
Set<FPlayer> informTheseFPlayers = new HashSet<FPlayer>();
informTheseFPlayers.add(this);
informTheseFPlayers.addAll(forFaction.getFPlayersWhereOnline(true));
for (FPlayer fp : informTheseFPlayers) {
fp.msg("<h>%s<i> claimed land for <h>%s<i> from <h>%s<i>.", this.describeTo(fp, true), forFaction.describeTo(fp), currentFaction.describeTo(fp));
}
Board.setFactionAt(forFaction, flocation);
if (Conf.logLandClaims) {
P.p.log(this.getName() + " claimed land at (" + flocation.getCoordString() + ") for the faction: " + forFaction.getTag());
}
return true;
}
// -------------------------------------------- //
// Persistence
// -------------------------------------------- //
@Override
public boolean shouldBeSaved() {
if (!this.hasFaction() && (this.getPowerRounded() == this.getPowerMaxRounded() || this.getPowerRounded() == (int) Math.round(Conf.powerPlayerStarting))) {
return false;
}
return !this.deleteMe;
}
public void msg(String str, Object... args) {
this.sendMessage(P.p.txt.parse(str, args));
}
public void setId(String id);
}

View File

@ -1,38 +1,40 @@
package com.massivecraft.factions;
import com.google.gson.reflect.TypeToken;
import com.massivecraft.factions.zcore.persist.PlayerEntityCollection;
import java.util.Collection;
import java.io.File;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
public class FPlayers extends PlayerEntityCollection<FPlayer> {
import com.massivecraft.factions.zcore.persist.json.JSONFPlayers;
public static FPlayers i = new FPlayers();
public abstract class FPlayers {
protected static FPlayers instance = getFPlayersImpl();
P p = P.p;
public abstract void clean();
private FPlayers() {
super(FPlayer.class, new CopyOnWriteArrayList<FPlayer>(), new ConcurrentSkipListMap<String, FPlayer>(String.CASE_INSENSITIVE_ORDER), new File(P.p.getDataFolder(), "players.json"), P.p.gson);
this.setCreative(true);
public static FPlayers getInstance() {
return instance;
}
@Override
public Type getMapType() {
return new TypeToken<Map<String, FPlayer>>() {
}.getType();
}
public void clean() {
for (FPlayer fplayer : this.get()) {
if (!Factions.i.exists(fplayer.getFactionId())) {
p.log("Reset faction data (invalid faction) for player " + fplayer.getName());
fplayer.resetFactionData(false);
}
private static FPlayers getFPlayersImpl() {
switch (Conf.backEnd) {
case JSON:
return new JSONFPlayers();
}
return null;
}
public abstract Collection<FPlayer> getOnlinePlayers();
public abstract FPlayer getByPlayer(Player player);
public abstract Collection<FPlayer> getAllFPlayers();
public abstract void forceSave();
public abstract FPlayer getByOfflinePlayer(OfflinePlayer player);
public abstract FPlayer getById(String string);
public abstract void load();
}

View File

@ -2,733 +2,214 @@ package com.massivecraft.factions;
import com.massivecraft.factions.iface.EconomyParticipator;
import com.massivecraft.factions.iface.RelationParticipator;
import com.massivecraft.factions.integration.Econ;
import com.massivecraft.factions.struct.Permission;
import com.massivecraft.factions.struct.Relation;
import com.massivecraft.factions.struct.Role;
import com.massivecraft.factions.util.LazyLocation;
import com.massivecraft.factions.util.MiscUtil;
import com.massivecraft.factions.util.RelationUtil;
import com.massivecraft.factions.zcore.persist.Entity;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public interface Faction extends EconomyParticipator {
public HashMap<String, List<String>> getAnnouncements();
public class Faction extends Entity implements EconomyParticipator {
public void addAnnouncement(FPlayer fPlayer, String msg);
// FIELD: relationWish
private Map<String, Relation> relationWish;
public void sendUnreadAnnouncements(FPlayer fPlayer);
// FIELD: claimOwnership
private Map<FLocation, Set<String>> claimOwnership = new ConcurrentHashMap<FLocation, Set<String>>();
public void removeAnnouncements(FPlayer fPlayer);
// FIELD: fplayers
// speedy lookup of players in faction
private transient Set<FPlayer> fplayers = new HashSet<FPlayer>();
public Set<String> getInvites();
private HashMap<String, List<String>> announcements;
public String getId();
public HashMap<String, List<String>> getAnnouncements() {
return this.announcements;
}
public void invite(FPlayer fplayer);
public void addAnnouncement(FPlayer fPlayer, String msg) {
List<String> list = announcements.containsKey(fPlayer.getId()) ? announcements.get(fPlayer.getId()) : new ArrayList<String>();
list.add(msg);
announcements.put(fPlayer.getId(), list);
}
public void deinvite(FPlayer fplayer);
public void sendUnreadAnnouncements(FPlayer fPlayer) {
if (!announcements.containsKey(fPlayer.getId())) {
return;
}
fPlayer.sendMessage(ChatColor.LIGHT_PURPLE + "--Unread Faction Announcements--");
for (String s : announcements.get(fPlayer.getPlayer().getUniqueId().toString())) {
fPlayer.sendMessage(s);
}
fPlayer.sendMessage(ChatColor.LIGHT_PURPLE + "--Unread Faction Announcements--");
announcements.remove(fPlayer.getId());
}
public void removeAnnouncements(FPlayer fPlayer) {
if (announcements.containsKey(fPlayer.getId())) {
announcements.remove(fPlayer.getId());
}
}
// FIELD: invites
private Set<String> invites;
public Set<String> getInvites() {
return invites;
}
public void invite(FPlayer fplayer) {
this.invites.add(fplayer.getId());
}
public void deinvite(FPlayer fplayer) {
this.invites.remove(fplayer.getId());
}
public boolean isInvited(FPlayer fplayer) {
return this.invites.contains(fplayer.getId());
}
public boolean isInvited(FPlayer fplayer);
// FIELD: open
private boolean open;
public boolean getOpen() {
return open;
}
public void setOpen(boolean isOpen) {
open = isOpen;
}
// FIELD: peaceful
// "peaceful" status can only be set by server admins/moderators/ops, and prevents PvP and land capture to/from the faction
private boolean peaceful;
public boolean isPeaceful() {
return this.peaceful;
}
public void setPeaceful(boolean isPeaceful) {
this.peaceful = isPeaceful;
}
// FIELD: peacefulExplosionsEnabled
private boolean peacefulExplosionsEnabled;
public void setPeacefulExplosionsEnabled(boolean val) {
peacefulExplosionsEnabled = val;
}
public boolean getPeacefulExplosionsEnabled() {
return this.peacefulExplosionsEnabled;
}
public boolean noExplosionsInTerritory() {
return this.peaceful && !peacefulExplosionsEnabled;
}
// FIELD: permanent
// "permanent" status can only be set by server admins/moderators/ops, and allows the faction to remain even with 0 members
private boolean permanent;
public boolean isPermanent() {
return permanent || !this.isNormal();
}
public void setPermanent(boolean isPermanent) {
permanent = isPermanent;
}
// FIELD: tag
private String tag;
public String getTag() {
return this.tag;
}
public String getTag(String prefix) {
return prefix + this.tag;
}
public String getTag(Faction otherFaction) {
if (otherFaction == null) {
return getTag();
}
return this.getTag(this.getColorTo(otherFaction).toString());
}
public boolean getOpen();
public String getTag(FPlayer otherFplayer) {
if (otherFplayer == null) {
return getTag();
}
return this.getTag(this.getColorTo(otherFplayer).toString());
}
public void setOpen(boolean isOpen);
public void setTag(String str) {
if (Conf.factionTagForceUpperCase) {
str = str.toUpperCase();
}
this.tag = str;
}
public String getComparisonTag() {
return MiscUtil.getComparisonString(this.tag);
}
// FIELD: description
private String description;
public String getDescription() {
return this.description;
}
public void setDescription(String value) {
this.description = value;
}
// FIELD: home
private LazyLocation home;
public void setHome(Location home) {
this.home = new LazyLocation(home);
}
public boolean hasHome() {
return this.getHome() != null;
}
public Location getHome() {
confirmValidHome();
return (this.home != null) ? this.home.getLocation() : null;
}
public void confirmValidHome() {
if (!Conf.homesMustBeInClaimedTerritory || this.home == null || (this.home.getLocation() != null && Board.getFactionAt(new FLocation(this.home.getLocation())) == this)) {
return;
}
msg("<b>Your faction home has been un-set since it is no longer in your territory.");
this.home = null;
}
// FIELD: lastPlayerLoggedOffTime
private transient long lastPlayerLoggedOffTime;
// FIELD: account (fake field)
// Bank functions
public double money;
public String getAccountId() {
String aid = "faction-" + this.getId();
// We need to override the default money given to players.
if (!Econ.hasAccount(aid)) {
Econ.setBalance(aid, 0);
}
return aid;
}
// FIELD: permanentPower
private Integer permanentPower;
public Integer getPermanentPower() {
return this.permanentPower;
}
public void setPermanentPower(Integer permanentPower) {
this.permanentPower = permanentPower;
}
public boolean hasPermanentPower() {
return this.permanentPower != null;
}
// FIELD: powerBoost
// special increase/decrease to default and max power for this faction
private double powerBoost;
public double getPowerBoost() {
return this.powerBoost;
}
public void setPowerBoost(double powerBoost) {
this.powerBoost = powerBoost;
}
// -------------------------------------------- //
// Construct
// -------------------------------------------- //
public Faction() {
this.relationWish = new HashMap<String, Relation>();
this.invites = new HashSet<String>();
this.open = Conf.newFactionsDefaultOpen;
this.tag = "???";
this.description = "Default faction description :(";
this.lastPlayerLoggedOffTime = 0;
this.peaceful = false;
this.peacefulExplosionsEnabled = false;
this.permanent = false;
this.money = 0.0;
this.powerBoost = 0.0;
this.announcements = new HashMap<String, List<String>>();
}
public boolean isPeaceful();
// -------------------------------------------- //
// Extra Getters And Setters
// -------------------------------------------- //
public void setPeaceful(boolean isPeaceful);
public boolean noPvPInTerritory() {
return isSafeZone() || (peaceful && Conf.peacefulTerritoryDisablePVP);
}
public void setPeacefulExplosionsEnabled(boolean val);
public boolean noMonstersInTerritory() {
return isSafeZone() || (peaceful && Conf.peacefulTerritoryDisableMonsters);
}
public boolean getPeacefulExplosionsEnabled();
public boolean noExplosionsInTerritory();
// -------------------------------
// Understand the types
// -------------------------------
public boolean isPermanent();
public boolean isNormal() {
return !(this.isNone() || this.isSafeZone() || this.isWarZone());
}
public void setPermanent(boolean isPermanent);
public boolean isNone() {
return this.getId().equals("0");
}
public String getTag();
public boolean isSafeZone() {
return this.getId().equals("-1");
}
public String getTag(String prefix);
public boolean isWarZone() {
return this.getId().equals("-2");
}
public String getTag(Faction otherFaction);
public boolean isPlayerFreeType() {
return this.isSafeZone() || this.isWarZone();
}
public String getTag(FPlayer otherFplayer);
public void setTag(String str);
public String getComparisonTag();
public String getDescription();
public void setDescription(String value);
public void setHome(Location home);
public boolean hasHome();
public Location getHome();
public void confirmValidHome();
public String getAccountId();
public Integer getPermanentPower();
public void setPermanentPower(Integer permanentPower);
public boolean hasPermanentPower();
public double getPowerBoost();
public void setPowerBoost(double powerBoost);
public boolean noPvPInTerritory();
public boolean noMonstersInTerritory();
public boolean isNormal();
public boolean isNone();
public boolean isSafeZone();
public boolean isWarZone();
public boolean isPlayerFreeType();
// -------------------------------
// Relation and relation colors
// -------------------------------
@Override
public String describeTo(RelationParticipator that, boolean ucfirst) {
return RelationUtil.describeThatToMe(this, that, ucfirst);
}
public String describeTo(RelationParticipator that, boolean ucfirst);
@Override
public String describeTo(RelationParticipator that) {
return RelationUtil.describeThatToMe(this, that);
}
public String describeTo(RelationParticipator that);
@Override
public Relation getRelationTo(RelationParticipator rp) {
return RelationUtil.getRelationTo(this, rp);
}
public Relation getRelationTo(RelationParticipator rp);
@Override
public Relation getRelationTo(RelationParticipator rp, boolean ignorePeaceful) {
return RelationUtil.getRelationTo(this, rp, ignorePeaceful);
}
public Relation getRelationTo(RelationParticipator rp, boolean ignorePeaceful);
@Override
public ChatColor getColorTo(RelationParticipator rp) {
return RelationUtil.getColorOfThatToMe(this, rp);
}
public ChatColor getColorTo(RelationParticipator rp);
public Relation getRelationWish(Faction otherFaction) {
if (this.relationWish.containsKey(otherFaction.getId())) {
return this.relationWish.get(otherFaction.getId());
}
return Relation.NEUTRAL;
}
public Relation getRelationWish(Faction otherFaction);
public void setRelationWish(Faction otherFaction, Relation relation) {
if (this.relationWish.containsKey(otherFaction.getId()) && relation.equals(Relation.NEUTRAL)) {
this.relationWish.remove(otherFaction.getId());
} else {
this.relationWish.put(otherFaction.getId(), relation);
}
}
public void setRelationWish(Faction otherFaction, Relation relation);
//----------------------------------------------//
// ----------------------------------------------//
// Power
//----------------------------------------------//
public double getPower() {
if (this.hasPermanentPower()) {
return this.getPermanentPower();
}
// ----------------------------------------------//
public double getPower();
double ret = 0;
for (FPlayer fplayer : fplayers) {
ret += fplayer.getPower();
}
if (Conf.powerFactionMax > 0 && ret > Conf.powerFactionMax) {
ret = Conf.powerFactionMax;
}
return ret + this.powerBoost;
}
public double getPowerMax();
public double getPowerMax() {
if (this.hasPermanentPower()) {
return this.getPermanentPower();
}
public int getPowerRounded();
double ret = 0;
for (FPlayer fplayer : fplayers) {
ret += fplayer.getPowerMax();
}
if (Conf.powerFactionMax > 0 && ret > Conf.powerFactionMax) {
ret = Conf.powerFactionMax;
}
return ret + this.powerBoost;
}
public int getPowerMaxRounded();
public int getPowerRounded() {
return (int) Math.round(this.getPower());
}
public int getLandRounded();
public int getPowerMaxRounded() {
return (int) Math.round(this.getPowerMax());
}
public int getLandRoundedInWorld(String worldName);
public int getLandRounded() {
return Board.getFactionCoordCount(this);
}
public int getLandRoundedInWorld(String worldName) {
return Board.getFactionCoordCountInWorld(this, worldName);
}
public boolean hasLandInflation() {
return this.getLandRounded() > this.getPowerRounded();
}
public boolean hasLandInflation();
// -------------------------------
// FPlayers
// -------------------------------
// maintain the reference list of FPlayers in this faction
public void refreshFPlayers() {
fplayers.clear();
if (this.isPlayerFreeType()) {
return;
}
public void refreshFPlayers();
for (FPlayer fplayer : FPlayers.i.get()) {
if (fplayer.getFaction() == this) {
fplayers.add(fplayer);
}
}
}
public boolean addFPlayer(FPlayer fplayer);
protected boolean addFPlayer(FPlayer fplayer) {
return !this.isPlayerFreeType() && fplayers.add(fplayer);
public boolean removeFPlayer(FPlayer fplayer);
}
public Set<FPlayer> getFPlayers();
protected boolean removeFPlayer(FPlayer fplayer) {
return !this.isPlayerFreeType() && fplayers.remove(fplayer);
public Set<FPlayer> getFPlayersWhereOnline(boolean online);
}
public FPlayer getFPlayerAdmin();
public Set<FPlayer> getFPlayers() {
// return a shallow copy of the FPlayer list, to prevent tampering and concurrency issues
return new HashSet<FPlayer>(fplayers);
}
public ArrayList<FPlayer> getFPlayersWhereRole(Role role);
public Set<FPlayer> getFPlayersWhereOnline(boolean online) {
Set<FPlayer> ret = new HashSet<FPlayer>();
public ArrayList<Player> getOnlinePlayers();
for (FPlayer fplayer : fplayers) {
if (fplayer.isOnline() == online) {
ret.add(fplayer);
}
}
// slightly faster check than getOnlinePlayers() if you just want to see if
// there are any players online
public boolean hasPlayersOnline();
return ret;
}
public void memberLoggedOff();
public FPlayer getFPlayerAdmin() {
if (!this.isNormal()) {
return null;
}
// used when current leader is about to be removed from the faction;
// promotes new leader, or disbands faction if no other members left
public void promoteNewLeader();
for (FPlayer fplayer : fplayers) {
if (fplayer.getRole() == Role.ADMIN) {
return fplayer;
}
}
return null;
}
public ArrayList<FPlayer> getFPlayersWhereRole(Role role) {
ArrayList<FPlayer> ret = new ArrayList<FPlayer>();
if (!this.isNormal()) {
return ret;
}
for (FPlayer fplayer : fplayers) {
if (fplayer.getRole() == role) {
ret.add(fplayer);
}
}
return ret;
}
public ArrayList<Player> getOnlinePlayers() {
ArrayList<Player> ret = new ArrayList<Player>();
if (this.isPlayerFreeType()) {
return ret;
}
for (Player player : P.p.getServer().getOnlinePlayers()) {
FPlayer fplayer = FPlayers.i.get(player);
if (fplayer.getFaction() == this) {
ret.add(player);
}
}
return ret;
}
// slightly faster check than getOnlinePlayers() if you just want to see if there are any players online
public boolean hasPlayersOnline() {
// only real factions can have players online, not safe zone / war zone
if (this.isPlayerFreeType()) {
return false;
}
for (Player player : P.p.getServer().getOnlinePlayers()) {
FPlayer fplayer = FPlayers.i.get(player);
if (fplayer != null && fplayer.getFaction() == this) {
return true;
}
}
// even if all players are technically logged off, maybe someone was on recently enough to not consider them officially offline yet
return Conf.considerFactionsReallyOfflineAfterXMinutes > 0 && System.currentTimeMillis() < lastPlayerLoggedOffTime + (Conf.considerFactionsReallyOfflineAfterXMinutes * 60000);
}
public void memberLoggedOff() {
if (this.isNormal()) {
lastPlayerLoggedOffTime = System.currentTimeMillis();
}
}
// used when current leader is about to be removed from the faction; promotes new leader, or disbands faction if no other members left
public void promoteNewLeader() {
if (!this.isNormal()) {
return;
}
if (this.isPermanent() && Conf.permanentFactionsDisableLeaderPromotion) {
return;
}
FPlayer oldLeader = this.getFPlayerAdmin();
// get list of moderators, or list of normal members if there are no moderators
ArrayList<FPlayer> replacements = this.getFPlayersWhereRole(Role.MODERATOR);
if (replacements == null || replacements.isEmpty()) {
replacements = this.getFPlayersWhereRole(Role.NORMAL);
}
if (replacements == null || replacements.isEmpty()) { // faction admin is the only member; one-man faction
if (this.isPermanent()) {
if (oldLeader != null) {
oldLeader.setRole(Role.NORMAL);
}
return;
}
// no members left and faction isn't permanent, so disband it
if (Conf.logFactionDisband) {
P.p.log("The faction " + this.getTag() + " (" + this.getId() + ") has been disbanded since it has no members left.");
}
for (FPlayer fplayer : FPlayers.i.getOnline()) {
fplayer.msg("The faction %s<i> was disbanded.", this.getTag(fplayer));
}
this.detach();
} else { // promote new faction admin
if (oldLeader != null) {
oldLeader.setRole(Role.NORMAL);
}
replacements.get(0).setRole(Role.ADMIN);
this.msg("<i>Faction admin <h>%s<i> has been removed. %s<i> has been promoted as the new faction admin.", oldLeader == null ? "" : oldLeader.getName(), replacements.get(0).getName());
P.p.log("Faction " + this.getTag() + " (" + this.getId() + ") admin was removed. Replacement admin: " + replacements.get(0).getName());
}
}
//----------------------------------------------//
// ----------------------------------------------//
// Messages
//----------------------------------------------//
public void msg(String message, Object... args) {
message = P.p.txt.parse(message, args);
// ----------------------------------------------//
public void msg(String message, Object... args);
for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) {
fplayer.sendMessage(message);
}
}
public void sendMessage(String message);
public void sendMessage(String message) {
for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) {
fplayer.sendMessage(message);
}
}
public void sendMessage(List<String> messages);
public void sendMessage(List<String> messages) {
for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) {
fplayer.sendMessage(messages);
}
}
//----------------------------------------------//
// ----------------------------------------------//
// Ownership of specific claims
//----------------------------------------------//
// ----------------------------------------------//
public Map<FLocation, Set<String>> getClaimOwnership() {
return claimOwnership;
}
public Map<FLocation, Set<String>> getClaimOwnership();
public void clearAllClaimOwnership() {
claimOwnership.clear();
}
public void clearAllClaimOwnership();
public void clearClaimOwnership(FLocation loc) {
claimOwnership.remove(loc);
}
public void clearClaimOwnership(FLocation loc);
public void clearClaimOwnership(FPlayer player) {
if (id == null || id.isEmpty()) {
return;
}
public void clearClaimOwnership(FPlayer player);
Set<String> ownerData;
public int getCountOfClaimsWithOwners();
for (Entry<FLocation, Set<String>> entry : claimOwnership.entrySet()) {
ownerData = entry.getValue();
public boolean doesLocationHaveOwnersSet(FLocation loc);
if (ownerData == null) {
continue;
}
public boolean isPlayerInOwnerList(FPlayer player, FLocation loc);
Iterator<String> iter = ownerData.iterator();
while (iter.hasNext()) {
if (iter.next().equals(player.getId())) {
iter.remove();
}
}
public void setPlayerAsOwner(FPlayer player, FLocation loc);
if (ownerData.isEmpty()) {
claimOwnership.remove(entry.getKey());
}
}
}
public void removePlayerAsOwner(FPlayer player, FLocation loc);
public int getCountOfClaimsWithOwners() {
return claimOwnership.isEmpty() ? 0 : claimOwnership.size();
}
public Set<String> getOwnerList(FLocation loc);
public boolean doesLocationHaveOwnersSet(FLocation loc) {
if (claimOwnership.isEmpty() || !claimOwnership.containsKey(loc)) {
return false;
}
public String getOwnerListString(FLocation loc);
Set<String> ownerData = claimOwnership.get(loc);
return ownerData != null && !ownerData.isEmpty();
}
public boolean playerHasOwnershipRights(FPlayer fplayer, FLocation loc);
public boolean isPlayerInOwnerList(FPlayer player, FLocation loc) {
if (claimOwnership.isEmpty()) {
return false;
}
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
return false;
}
return ownerData.contains(player.getId());
}
public void setPlayerAsOwner(FPlayer player, FLocation loc) {
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
ownerData = new HashSet<String>();
}
ownerData.add(player.getId());
claimOwnership.put(loc, ownerData);
}
public void removePlayerAsOwner(FPlayer player, FLocation loc) {
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
return;
}
ownerData.remove(player.getId());
claimOwnership.put(loc, ownerData);
}
public Set<String> getOwnerList(FLocation loc) {
return claimOwnership.get(loc);
}
public String getOwnerListString(FLocation loc) {
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null || ownerData.isEmpty()) {
return "";
}
String ownerList = "";
Iterator<String> iter = ownerData.iterator();
while (iter.hasNext()) {
if (!ownerList.isEmpty()) {
ownerList += ", ";
}
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(UUID.fromString(iter.next()));
ownerList += offlinePlayer != null ? offlinePlayer.getName() : "null player";
}
return ownerList;
}
public boolean playerHasOwnershipRights(FPlayer fplayer, FLocation loc) {
// in own faction, with sufficient role or permission to bypass ownership?
if (fplayer.getFaction() == this && (fplayer.getRole().isAtLeast(Conf.ownedAreaModeratorsBypass ? Role.MODERATOR : Role.ADMIN) || Permission.OWNERSHIP_BYPASS.has(fplayer.getPlayer()))) {
return true;
}
// make sure claimOwnership is initialized
if (claimOwnership.isEmpty()) {
return true;
}
// need to check the ownership list, then
Set<String> ownerData = claimOwnership.get(loc);
// if no owner list, owner list is empty, or player is in owner list, they're allowed
return ownerData == null || ownerData.isEmpty() || ownerData.contains(fplayer.getId());
}
//----------------------------------------------//
// ----------------------------------------------//
// Persistance and entity management
//----------------------------------------------//
// ----------------------------------------------//
public void remove();
@Override
public void postDetach() {
if (Econ.shouldBeUsed()) {
Econ.setBalance(getAccountId(), 0);
}
// Clean the board
Board.clean();
// Clean the fplayers
FPlayers.i.clean();
}
public void setId(String id);
}

View File

@ -1,184 +1,50 @@
package com.massivecraft.factions;
import com.google.gson.reflect.TypeToken;
import com.massivecraft.factions.util.MiscUtil;
import com.massivecraft.factions.zcore.persist.EntityCollection;
import com.massivecraft.factions.zcore.util.TL;
import com.massivecraft.factions.zcore.util.TextUtil;
import org.bukkit.ChatColor;
import java.io.File;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.Set;
public class Factions extends EntityCollection<Faction> {
import com.massivecraft.factions.zcore.persist.json.JSONFactions;
public static Factions i = new Factions();
public abstract class Factions {
protected static Factions instance = getFactionsImpl();
P p = P.p;
public abstract Faction getFactionById(String id);
private Factions() {
super(Faction.class, new CopyOnWriteArrayList<Faction>(), new ConcurrentHashMap<String, Faction>(), new File(P.p.getDataFolder(), "factions.json"), P.p.gson);
public abstract Faction getByTag(String str);
public abstract Faction getBestTagMatch(String start);
public abstract boolean isTagTaken(String str);
public abstract boolean isValidFactionId(String id);
public abstract Faction createFaction();
public abstract void removeFaction(String id);
public abstract Set<String> getFactionTags();
public abstract ArrayList<Faction> getAllFactions();
public abstract Faction getNone();
public abstract Faction getSafeZone();
public abstract Faction getWarZone();
public abstract void forceSave();
public static Factions getInstance() {
return instance;
}
@Override
public Type getMapType() {
return new TypeToken<Map<String, Faction>>() {
}.getType();
}
@Override
public boolean loadFromDisc() {
if (!super.loadFromDisc()) {
return false;
}
// Make sure the default neutral faction exists
if (!this.exists("0")) {
Faction faction = this.create("0");
faction.setTag(TL.WILDERNESS.toString());
faction.setDescription(TL.WILDERNESS_DESCRIPTION.toString());
} else {
if (!this.get("0").getTag().equalsIgnoreCase(TL.WILDERNESS.toString())) {
get("0").setTag(TL.WILDERNESS.toString());
}
if (!this.get("0").getDescription().equalsIgnoreCase(TL.WILDERNESS_DESCRIPTION.toString())) {
get("0").setDescription(TL.WILDERNESS_DESCRIPTION.toString());
}
}
// Make sure the safe zone faction exists
if (!this.exists("-1")) {
Faction faction = this.create("-1");
faction.setTag(TL.SAFEZONE.toString());
faction.setDescription(TL.SAFEZONE_DESCRIPTION.toString());
} else {
if (!getSafeZone().getTag().equalsIgnoreCase(TL.SAFEZONE.toString())) {
getSafeZone().setTag(TL.SAFEZONE.toString());
}
if (!getSafeZone().getDescription().equalsIgnoreCase(TL.SAFEZONE_DESCRIPTION.toString())) {
getSafeZone().setDescription(TL.SAFEZONE_DESCRIPTION.toString());
}
// if SafeZone has old pre-1.6.0 name, rename it to remove troublesome " "
Faction faction = this.getSafeZone();
if (faction.getTag().contains(" ")) {
faction.setTag(TL.SAFEZONE.toString());
}
}
// Make sure the war zone faction exists
if (!this.exists("-2")) {
Faction faction = this.create("-2");
faction.setTag(TL.WARZONE.toString());
faction.setDescription(TL.WARZONE_DESCRIPTION.toString());
} else {
if (!getWarZone().getTag().equalsIgnoreCase(TL.WARZONE.toString())) {
getWarZone().setTag(TL.WARZONE.toString());
}
if (!getWarZone().getDescription().equalsIgnoreCase(TL.WARZONE_DESCRIPTION.toString())) {
getWarZone().setDescription(TL.WARZONE_DESCRIPTION.toString());
}
// if WarZone has old pre-1.6.0 name, rename it to remove troublesome " "
Faction faction = this.getWarZone();
if (faction.getTag().contains(" ")) {
faction.setTag(TL.WARZONE.toString());
}
}
// populate all faction player lists
for (Faction faction : i.get()) {
faction.refreshFPlayers();
}
return true;
}
//----------------------------------------------//
// GET
//----------------------------------------------//
@Override
public Faction get(String id) {
if (!this.exists(id)) {
p.log(Level.WARNING, "Non existing factionId " + id + " requested! Issuing cleaning!");
Board.clean();
FPlayers.i.clean();
}
return super.get(id);
}
public Faction getNone() {
return this.get("0");
}
public Faction getSafeZone() {
return this.get("-1");
}
public Faction getWarZone() {
return this.get("-2");
}
//----------------------------------------------//
// Faction tag
//----------------------------------------------//
public static ArrayList<String> validateTag(String str) {
ArrayList<String> errors = new ArrayList<String>();
if (MiscUtil.getComparisonString(str).length() < Conf.factionTagLengthMin) {
errors.add(P.p.txt.parse("<i>The faction tag can't be shorter than <h>%s<i> chars.", Conf.factionTagLengthMin));
}
if (str.length() > Conf.factionTagLengthMax) {
errors.add(P.p.txt.parse("<i>The faction tag can't be longer than <h>%s<i> chars.", Conf.factionTagLengthMax));
}
for (char c : str.toCharArray()) {
if (!MiscUtil.substanceChars.contains(String.valueOf(c))) {
errors.add(P.p.txt.parse("<i>Faction tag must be alphanumeric. \"<h>%s<i>\" is not allowed.", c));
}
}
return errors;
}
// Loops through all faction tags. Case and color insensitive.
public Faction getByTag(String str) {
String compStr = MiscUtil.getComparisonString(str);
for (Faction faction : this.get()) {
if (faction.getComparisonTag().equals(compStr)) {
return faction;
}
private static Factions getFactionsImpl() {
switch (Conf.backEnd) {
case JSON:
return new JSONFactions();
}
return null;
}
public Faction getBestTagMatch(String searchFor) {
Map<String, Faction> tag2faction = new HashMap<String, Faction>();
// TODO: Slow index building
for (Faction faction : this.get()) {
tag2faction.put(ChatColor.stripColor(faction.getTag()), faction);
}
String tag = TextUtil.getBestStartWithCI(tag2faction.keySet(), searchFor);
if (tag == null) {
return null;
}
return tag2faction.get(tag);
}
public boolean isTagTaken(String str) {
return this.getByTag(str) != null;
}
public abstract void load();
}

View File

@ -12,6 +12,7 @@ import com.massivecraft.factions.struct.ChatMode;
import com.massivecraft.factions.util.*;
import com.massivecraft.factions.zcore.MPlugin;
import com.massivecraft.factions.zcore.util.TextUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -77,9 +78,18 @@ public class P extends MPlugin {
// Load Conf from disk
Conf.load();
Essentials.setup();
FPlayers.i.loadFromDisc();
Factions.i.loadFromDisc();
Board.load();
FPlayers.getInstance().load();
Factions.getInstance().load();
for (FPlayer fPlayer : FPlayers.getInstance().getAllFPlayers()) {
Faction faction = Factions.getInstance().getFactionById(fPlayer.getFactionId());
if (faction == null) {
log("Invalid faction id on " + fPlayer.getName() + ":" + fPlayer.getFactionId());
fPlayer.resetFactionData(false);
continue;
}
faction.addFPlayer(fPlayer);
}
Board.getInstance().load();
// Add Base Commands
this.cmdBase = new FCmdRoot();
@ -122,7 +132,6 @@ public class P extends MPlugin {
public void onDisable() {
// only save data if plugin actually completely loaded successfully
if (this.loadSuccessful) {
Board.save();
Conf.save();
}
if (AutoLeaveTask != null) {
@ -150,7 +159,7 @@ public class P extends MPlugin {
@Override
public void postAutoSave() {
Board.save();
Board.getInstance().forceSave();
Conf.save();
}
@ -204,7 +213,7 @@ public class P extends MPlugin {
if (player == null) {
return false;
}
FPlayer me = FPlayers.i.get(player);
FPlayer me = FPlayers.getInstance().getByPlayer(player);
return me != null && me.getChatMode().isAtLeast(ChatMode.ALLIANCE);
}
@ -230,7 +239,7 @@ public class P extends MPlugin {
return tag;
}
FPlayer me = FPlayers.i.get(speaker);
FPlayer me = FPlayers.getInstance().getByPlayer(speaker);
if (me == null) {
return tag;
}
@ -239,7 +248,7 @@ public class P extends MPlugin {
if (listener == null || !Conf.chatTagRelationColored) {
tag = me.getChatTag().trim();
} else {
FPlayer you = FPlayers.i.get(listener);
FPlayer you = FPlayers.getInstance().getByPlayer(listener);
if (you == null) {
tag = me.getChatTag().trim();
} else // everything checks out, give the colored tag
@ -260,7 +269,7 @@ public class P extends MPlugin {
return "";
}
FPlayer me = FPlayers.i.get(player);
FPlayer me = FPlayers.getInstance().getByPlayer(player);
if (me == null) {
return "";
}
@ -270,17 +279,13 @@ public class P extends MPlugin {
// Get a list of all faction tags (names)
public Set<String> getFactionTags() {
Set<String> tags = new HashSet<String>();
for (Faction faction : Factions.i.get()) {
tags.add(faction.getTag());
}
return tags;
return Factions.getInstance().getFactionTags();
}
// Get a list of all players in the specified faction
public Set<String> getPlayersInFaction(String factionTag) {
Set<String> players = new HashSet<String>();
Faction faction = Factions.i.getByTag(factionTag);
Faction faction = Factions.getInstance().getByTag(factionTag);
if (faction != null) {
for (FPlayer fplayer : faction.getFPlayers()) {
players.add(fplayer.getName());
@ -292,7 +297,7 @@ public class P extends MPlugin {
// Get a list of all online players in the specified faction
public Set<String> getOnlinePlayersInFaction(String factionTag) {
Set<String> players = new HashSet<String>();
Faction faction = Factions.i.getByTag(factionTag);
Faction faction = Factions.getInstance().getByTag(factionTag);
if (faction != null) {
for (FPlayer fplayer : faction.getFPlayersWhereOnline(true)) {
players.add(fplayer.getName());

View File

@ -53,7 +53,7 @@ public class CmdAdmin extends FCommand {
// only perform a FPlayerJoinEvent when newLeader isn't actually in the faction
if (fyou.getFaction() != targetFaction) {
FPlayerJoinEvent event = new FPlayerJoinEvent(FPlayers.i.get(me), targetFaction, FPlayerJoinEvent.PlayerJoinReason.LEADER);
FPlayerJoinEvent event = new FPlayerJoinEvent(FPlayers.getInstance().getByPlayer(me), targetFaction, FPlayerJoinEvent.PlayerJoinReason.LEADER);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
@ -78,7 +78,7 @@ public class CmdAdmin extends FCommand {
msg("<i>You have promoted %s<i> to the position of faction admin.", fyou.describeTo(fme, true));
// Inform all players
for (FPlayer fplayer : FPlayers.i.getOnline()) {
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
fplayer.msg("%s<i> gave %s<i> the leadership of %s<i>.", senderIsConsole ? "A server admin" : fme.describeTo(fplayer, true), fyou.describeTo(fplayer), targetFaction.describeTo(fplayer));
}
}

View File

@ -0,0 +1,39 @@
package com.massivecraft.factions.cmd;
import org.bukkit.command.ConsoleCommandSender;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.Conf.Backend;
import com.massivecraft.factions.zcore.persist.json.FactionsJSON;
public class CmdConvert extends FCommand {
public CmdConvert() {
this.aliases.add("convert");
this.requiredArgs.add("[MYSQL|JSON]");
}
@Override
public void perform() {
if (!(this.sender instanceof ConsoleCommandSender)) {
this.sender.sendMessage("Console only command");
}
Backend nb = Backend.valueOf(this.argAsString(0).toUpperCase());
if (nb == Conf.backEnd) {
this.sender.sendMessage("Already running that backend");
return;
}
switch (nb) {
case JSON:
FactionsJSON.convertTo();
break;
default:
this.sender.sendMessage("Invalid backend");
return;
}
Conf.backEnd = nb;
}
}

View File

@ -5,6 +5,8 @@ import com.massivecraft.factions.event.FPlayerJoinEvent;
import com.massivecraft.factions.event.FactionCreateEvent;
import com.massivecraft.factions.struct.Permission;
import com.massivecraft.factions.struct.Role;
import com.massivecraft.factions.util.MiscUtil;
import org.bukkit.Bukkit;
import java.util.ArrayList;
@ -37,12 +39,12 @@ public class CmdCreate extends FCommand {
return;
}
if (Factions.i.isTagTaken(tag)) {
if (Factions.getInstance().isTagTaken(tag)) {
msg("<b>That tag is already in use.");
return;
}
ArrayList<String> tagValidationErrors = Factions.validateTag(tag);
ArrayList<String> tagValidationErrors = MiscUtil.validateTag(tag);
if (tagValidationErrors.size() > 0) {
sendMessage(tagValidationErrors);
return;
@ -65,7 +67,7 @@ public class CmdCreate extends FCommand {
return;
}
Faction faction = Factions.i.create();
Faction faction = Factions.getInstance().createFaction();
// TODO: Why would this even happen??? Auto increment clash??
if (faction == null) {
@ -77,7 +79,7 @@ public class CmdCreate extends FCommand {
faction.setTag(tag);
// trigger the faction join event for the creator
FPlayerJoinEvent joinEvent = new FPlayerJoinEvent(FPlayers.i.get(me), faction, FPlayerJoinEvent.PlayerJoinReason.CREATE);
FPlayerJoinEvent joinEvent = new FPlayerJoinEvent(FPlayers.getInstance().getByPlayer(me), faction, FPlayerJoinEvent.PlayerJoinReason.CREATE);
Bukkit.getServer().getPluginManager().callEvent(joinEvent);
// join event cannot be cancelled or you'll have an empty faction
@ -85,7 +87,7 @@ public class CmdCreate extends FCommand {
fme.setRole(Role.ADMIN);
fme.setFaction(faction);
for (FPlayer follower : FPlayers.i.getOnline()) {
for (FPlayer follower : FPlayers.getInstance().getOnlinePlayers()) {
follower.msg("%s<i> created a new faction %s", fme.describeTo(follower, true), faction.getTag(follower));
}

View File

@ -41,7 +41,7 @@ public class CmdDescription extends FCommand {
}
// Broadcast the description to everyone
for (FPlayer fplayer : FPlayers.i.getOnline()) {
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
fplayer.msg("<i>The faction %s<i> changed their description to:", myFaction.describeTo(fplayer));
fplayer.sendMessage(myFaction.getDescription()); // players can inject "&" or "`" or "<i>" or whatever in their description; &k is particularly interesting looking
}

View File

@ -68,7 +68,7 @@ public class CmdDisband extends FCommand {
}
// Inform all players
for (FPlayer fplayer : FPlayers.i.getOnline()) {
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
String who = senderIsConsole ? "A server admin" : fme.describeTo(fplayer);
if (fplayer.getFaction() == faction) {
fplayer.msg("<h>%s<i> disbanded your faction.", who);
@ -92,6 +92,6 @@ public class CmdDisband extends FCommand {
}
}
faction.detach();
Factions.getInstance().removeFaction(faction.getId());
}
}

View File

@ -61,7 +61,7 @@ public class CmdHome extends FCommand {
return;
}
Faction faction = Board.getFactionAt(new FLocation(me.getLocation()));
Faction faction = Board.getInstance().getFactionAt(new FLocation(me.getLocation()));
Location loc = me.getLocation().clone();
// if player is not in a safe zone or their own faction territory, only allow teleport if no enemies are nearby
@ -78,7 +78,7 @@ public class CmdHome extends FCommand {
continue;
}
FPlayer fp = FPlayers.i.get(p);
FPlayer fp = FPlayers.getInstance().getByPlayer(p);
if (fme.getRelationTo(fp) != Relation.ENEMY) {
continue;
}

View File

@ -77,7 +77,7 @@ public class CmdJoin extends FCommand {
}
// trigger the join event (cancellable)
FPlayerJoinEvent joinEvent = new FPlayerJoinEvent(FPlayers.i.get(me), faction, FPlayerJoinEvent.PlayerJoinReason.COMMAND);
FPlayerJoinEvent joinEvent = new FPlayerJoinEvent(FPlayers.getInstance().getByPlayer(me), faction, FPlayerJoinEvent.PlayerJoinReason.COMMAND);
Bukkit.getServer().getPluginManager().callEvent(joinEvent);
if (joinEvent.isCancelled()) {
return;

View File

@ -36,10 +36,10 @@ public class CmdList extends FCommand {
return;
}
ArrayList<Faction> factionList = new ArrayList<Faction>(Factions.i.get());
factionList.remove(Factions.i.getNone());
factionList.remove(Factions.i.getSafeZone());
factionList.remove(Factions.i.getWarZone());
ArrayList<Faction> factionList = Factions.getInstance().getAllFactions();
factionList.remove(Factions.getInstance().getNone());
factionList.remove(Factions.getInstance().getSafeZone());
factionList.remove(Factions.getInstance().getWarZone());
// Sort by total followers first
Collections.sort(factionList, new Comparator<Faction>() {
@ -90,7 +90,7 @@ public class CmdList extends FCommand {
sendMessage(p.txt.getPage(lines, this.argAsInt(0, 1), "Faction List"));
*/
factionList.add(0, Factions.i.getNone());
factionList.add(0, Factions.getInstance().getNone());
final int pageheight = 9;
int pagenumber = this.argAsInt(0, 1);
@ -110,7 +110,7 @@ public class CmdList extends FCommand {
for (Faction faction : factionList.subList(start, end)) {
if (faction.isNone()) {
lines.add(p.txt.parse("<i>Factionless<i> %d online", Factions.i.getNone().getFPlayersWhereOnline(true).size()));
lines.add(p.txt.parse("<i>Factionless<i> %d online", Factions.getInstance().getNone().getFPlayersWhereOnline(true).size()));
continue;
}
lines.add(p.txt.parse("%s<i> %d/%d online, %d/%d/%d", faction.getTag(fme), faction.getFPlayersWhereOnline(true).size(), faction.getFPlayers().size(), faction.getLandRounded(), faction.getPowerRounded(), faction.getPowerMaxRounded()));

View File

@ -56,7 +56,7 @@ public class CmdMap extends FCommand {
}
public void showMap() {
sendMessage(Board.getMap(myFaction, new FLocation(fme), fme.getPlayer().getLocation().getYaw()));
sendMessage(Board.getInstance().getMap(myFaction, new FLocation(fme), fme.getPlayer().getLocation().getYaw()));
}
}

View File

@ -1,8 +1,8 @@
package com.massivecraft.factions.cmd;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.struct.Permission;
public class CmdOpen extends FCommand {
@ -35,12 +35,12 @@ public class CmdOpen extends FCommand {
String open = myFaction.getOpen() ? "open" : "closed";
// Inform
myFaction.msg("%s<i> changed the faction to <h>%s<i>.", fme.describeTo(myFaction, true), open);
for (Faction faction : Factions.i.get()) {
if (faction == myFaction) {
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
if (fplayer.getFactionId() == myFaction.getId()) {
fplayer.msg("%s<i> changed the faction to <h>%s<i>.", open);
continue;
}
faction.msg("<i>The faction %s<i> is now %s", myFaction.getTag(faction), open);
fplayer.msg("<i>The faction %s<i> is now %s", myFaction.getTag(fplayer.getFaction()), open);
}
}

View File

@ -49,7 +49,7 @@ public class CmdOwner extends FCommand {
FLocation flocation = new FLocation(fme);
Faction factionHere = Board.getFactionAt(flocation);
Faction factionHere = Board.getInstance().getFactionAt(flocation);
if (factionHere != myFaction) {
if (!hasBypass) {
fme.msg("<b>This land is not claimed by your faction, so you can't set ownership of it.");

View File

@ -39,13 +39,13 @@ public class CmdOwnerList extends FCommand {
FLocation flocation = new FLocation(fme);
if (Board.getFactionAt(flocation) != myFaction) {
if (Board.getInstance().getFactionAt(flocation) != myFaction) {
if (!hasBypass) {
fme.msg("<b>This land is not claimed by your faction.");
return;
}
myFaction = Board.getFactionAt(flocation);
myFaction = Board.getInstance().getFactionAt(flocation);
if (!myFaction.isNormal()) {
fme.msg("<i>This land is not claimed by any faction, thus no owners.");
return;

View File

@ -40,7 +40,7 @@ public class CmdPeaceful extends FCommand {
}
// Inform all players
for (FPlayer fplayer : FPlayers.i.getOnline()) {
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
if (fplayer.getFaction() == faction) {
fplayer.msg((fme == null ? "A server admin" : fme.describeTo(fplayer, true)) + "<i> has " + change + " your faction.");
} else {

View File

@ -44,7 +44,7 @@ public class CmdPermanent extends FCommand {
P.p.log((fme == null ? "A server admin" : fme.getName()) + " " + change + " the faction \"" + faction.getTag() + "\".");
// Inform all players
for (FPlayer fplayer : FPlayers.i.getOnline()) {
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
if (fplayer.getFaction() == faction) {
fplayer.msg((fme == null ? "A server admin" : fme.describeTo(fplayer, true)) + "<i> " + change + " your faction.");
} else {

View File

@ -28,7 +28,7 @@ public class CmdSafeunclaimall extends FCommand {
@Override
public void perform() {
Board.unclaimAll(Factions.i.getSafeZone().getId());
Board.getInstance().unclaimAll(Factions.getInstance().getSafeZone().getId());
msg("<i>You unclaimed ALL safe zone land.");
if (Conf.logLandUnclaims) {

View File

@ -27,9 +27,9 @@ public class CmdSaveAll extends FCommand {
@Override
public void perform() {
FPlayers.i.saveToDisc();
Factions.i.saveToDisc();
Board.save();
FPlayers.getInstance().forceSave();
Factions.getInstance().forceSave();
Board.getInstance().forceSave();
Conf.save();
msg("<i>Factions saved to disk!");
}

View File

@ -50,7 +50,7 @@ public class CmdSethome extends FCommand {
// Can the player set the faction home HERE?
if (!Permission.BYPASS.has(me) &&
Conf.homesMustBeInClaimedTerritory &&
Board.getFactionAt(new FLocation(me)) != faction) {
Board.getInstance().getFactionAt(new FLocation(me)) != faction) {
fme.msg("<b>Sorry, your faction home can only be set inside your own claimed territory.");
return;
}

View File

@ -90,7 +90,7 @@ public class CmdShow extends FCommand {
// List relation
String allyList = p.txt.parse("<a>Allies: ");
String enemyList = p.txt.parse("<a>Enemies: ");
for (Faction otherFaction : Factions.i.get()) {
for (Faction otherFaction : Factions.getInstance().getAllFactions()) {
if (otherFaction == faction) {
continue;
}

View File

@ -19,7 +19,7 @@ public class CmdShowInvites extends FCommand {
public void perform() {
StringBuilder sb = new StringBuilder();
for (String id : myFaction.getInvites()) {
FPlayer fp = FPlayers.i.get(id);
FPlayer fp = FPlayers.getInstance().getById(id);
sb.append(fp != null ? fp.getName() : id).append(" ");
}
msg("<a>Players with pending invites: <i> %s", sb.toString().trim());

View File

@ -1,12 +1,15 @@
package com.massivecraft.factions.cmd;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.event.FactionRenameEvent;
import com.massivecraft.factions.scoreboards.FTeamWrapper;
import com.massivecraft.factions.struct.Permission;
import com.massivecraft.factions.util.MiscUtil;
import org.bukkit.Bukkit;
import java.util.ArrayList;
@ -33,13 +36,12 @@ public class CmdTag extends FCommand {
String tag = this.argAsString(0);
// TODO does not first test cover selfcase?
if (Factions.i.isTagTaken(tag) && !MiscUtil.getComparisonString(tag).equals(myFaction.getComparisonTag())) {
if (Factions.getInstance().isTagTaken(tag) && !MiscUtil.getComparisonString(tag).equals(myFaction.getComparisonTag())) {
msg("<b>That tag is already taken");
return;
}
ArrayList<String> errors = new ArrayList<String>();
errors.addAll(Factions.validateTag(tag));
ArrayList<String> errors = MiscUtil.validateTag(tag);
if (errors.size() > 0) {
sendMessage(errors);
return;
@ -66,12 +68,13 @@ public class CmdTag extends FCommand {
myFaction.setTag(tag);
// Inform
myFaction.msg("%s<i> changed your faction tag to %s", fme.describeTo(myFaction, true), myFaction.getTag(myFaction));
for (Faction faction : Factions.i.get()) {
if (faction == myFaction) {
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
if (fplayer.getFactionId() == myFaction.getId()) {
fplayer.msg("%s<i> changed your faction tag to %s", fme.describeTo(myFaction, true), myFaction.getTag(myFaction));
continue;
}
faction.msg("<i>The faction %s<i> changed their name to %s.", fme.getColorTo(faction) + oldtag, myFaction.getTag(faction));
Faction faction = fplayer.getFaction();
fplayer.msg("<i>The faction %s<i> changed their name to %s.", fme.getColorTo(faction) + oldtag, myFaction.getTag(faction));
}
FTeamWrapper.updatePrefixes(myFaction);

View File

@ -28,11 +28,11 @@ public class CmdUnclaim extends FCommand {
@Override
public void perform() {
FLocation flocation = new FLocation(fme);
Faction otherFaction = Board.getFactionAt(flocation);
Faction otherFaction = Board.getInstance().getFactionAt(flocation);
if (otherFaction.isSafeZone()) {
if (Permission.MANAGE_SAFE_ZONE.has(sender)) {
Board.removeAt(flocation);
Board.getInstance().removeAt(flocation);
msg("<i>Safe zone was unclaimed.");
if (Conf.logLandUnclaims) {
@ -44,7 +44,7 @@ public class CmdUnclaim extends FCommand {
return;
} else if (otherFaction.isWarZone()) {
if (Permission.MANAGE_WAR_ZONE.has(sender)) {
Board.removeAt(flocation);
Board.getInstance().removeAt(flocation);
msg("<i>War zone was unclaimed.");
if (Conf.logLandUnclaims) {
@ -57,7 +57,7 @@ public class CmdUnclaim extends FCommand {
}
if (fme.isAdminBypassing()) {
Board.removeAt(flocation);
Board.getInstance().removeAt(flocation);
otherFaction.msg("%s<i> unclaimed some of your land.", fme.describeTo(otherFaction, true));
msg("<i>You unclaimed this land.");
@ -103,7 +103,7 @@ public class CmdUnclaim extends FCommand {
}
}
Board.removeAt(flocation);
Board.getInstance().removeAt(flocation);
myFaction.msg("%s<i> unclaimed some land.", fme.describeTo(myFaction, true));
if (Conf.logLandUnclaims) {

View File

@ -45,7 +45,7 @@ public class CmdUnclaimall extends FCommand {
Bukkit.getServer().getPluginManager().callEvent(unclaimAllEvent);
// this event cannot be cancelled
Board.unclaimAll(myFaction.getId());
Board.getInstance().unclaimAll(myFaction.getId());
myFaction.msg("%s<i> unclaimed ALL of your faction's land.", fme.describeTo(myFaction, true));
if (Conf.logLandUnclaims) {

View File

@ -28,7 +28,7 @@ public class CmdWarunclaimall extends FCommand {
@Override
public void perform() {
Board.unclaimAll(Factions.i.getWarZone().getId());
Board.getInstance().unclaimAll(Factions.getInstance().getWarZone().getId());
msg("<i>You unclaimed ALL war zone land.");
if (Conf.logLandUnclaims) {

View File

@ -56,6 +56,7 @@ public class FCmdRoot extends FCommand {
public CmdShowInvites cmdShowInvites = new CmdShowInvites();
public CmdAnnounce cmdAnnounce = new CmdAnnounce();
public CmdSeeChunk cmdSeeChunk = new CmdSeeChunk();
public CmdConvert cmdConvert = new CmdConvert();
public FCmdRoot() {
super();
@ -128,6 +129,7 @@ public class FCmdRoot extends FCommand {
this.addSubCommand(this.cmdShowInvites);
this.addSubCommand(this.cmdAnnounce);
this.addSubCommand(this.cmdSeeChunk);
this.addSubCommand(this.cmdConvert);
}
@Override

View File

@ -41,7 +41,7 @@ public abstract class FCommand extends MCommand<P> {
@Override
public void execute(CommandSender sender, List<String> args, List<MCommand<?>> commandChain) {
if (sender instanceof Player) {
this.fme = FPlayers.i.get((Player) sender);
this.fme = FPlayers.getInstance().getByPlayer((Player) sender);
this.myFaction = this.fme.getFaction();
} else {
this.fme = null;
@ -85,19 +85,17 @@ public abstract class FCommand extends MCommand<P> {
return false;
}
FPlayer fplayer = FPlayers.i.get((Player) sender);
if (!fplayer.hasFaction()) {
if (!fme.hasFaction()) {
sender.sendMessage(p.txt.parse("<b>You are not member of any faction."));
return false;
}
if (this.senderMustBeModerator && !fplayer.getRole().isAtLeast(Role.MODERATOR)) {
if (this.senderMustBeModerator && !fme.getRole().isAtLeast(Role.MODERATOR)) {
sender.sendMessage(p.txt.parse("<b>Only faction moderators can %s.", this.getHelpShort()));
return false;
}
if (this.senderMustBeAdmin && !fplayer.getRole().isAtLeast(Role.ADMIN)) {
if (this.senderMustBeAdmin && !fme.getRole().isAtLeast(Role.ADMIN)) {
sender.sendMessage(p.txt.parse("<b>Only faction admins can %s.", this.getHelpShort()));
return false;
}
@ -143,7 +141,7 @@ public abstract class FCommand extends MCommand<P> {
if (name != null) {
OfflinePlayer player = Bukkit.getOfflinePlayer(name);
FPlayer fplayer = FPlayers.i.get(player);
FPlayer fplayer = FPlayers.getInstance().getByOfflinePlayer(player);
if (fplayer != null) {
ret = fplayer;
}
@ -194,18 +192,18 @@ public abstract class FCommand extends MCommand<P> {
// First we try an exact match
if (faction == null) {
faction = Factions.i.getByTag(name); // Checks for faction name match.
faction = Factions.getInstance().getByTag(name); // Checks for faction name match.
}
// Next we match faction tags
if (faction == null) {
faction = Factions.i.getBestTagMatch(name);
faction = Factions.getInstance().getBestTagMatch(name);
}
// Next we match player names
if (faction == null) {
OfflinePlayer player = Bukkit.getOfflinePlayer(name);
FPlayer fplayer = FPlayers.i.get(player);
FPlayer fplayer = FPlayers.getInstance().getByOfflinePlayer(player);
if (fplayer != null) {
faction = fplayer.getFaction();
}

View File

@ -2,7 +2,6 @@ package com.massivecraft.factions.event;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.Factions;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
@ -26,11 +25,7 @@ public class FactionCreateEvent extends Event implements Cancellable {
}
public FPlayer getFPlayer() {
return FPlayers.i.get(sender);
}
public String getFactionId() {
return Factions.i.getNextId();
return FPlayers.getInstance().getByPlayer(sender);
}
public String getFactionTag() {

View File

@ -15,12 +15,12 @@ public class FactionDisbandEvent extends FactionEvent implements Cancellable {
private Player sender;
public FactionDisbandEvent(Player sender, String factionId) {
super(Factions.i.get(factionId));
super(Factions.getInstance().getFactionById(factionId));
this.sender = sender;
}
public FPlayer getFPlayer() {
return FPlayers.i.get(sender);
return FPlayers.getInstance().getByPlayer(sender);
}
public Player getPlayer() {

View File

@ -47,8 +47,6 @@ public class Econ {
}
P.p.cmdBase.cmdHelp.updateHelp();
oldMoneyDoTransfer();
}
public static boolean shouldBeUsed() {
@ -330,19 +328,6 @@ public class Econ {
return econ.format(amount);
}
public static void oldMoneyDoTransfer() {
if (!shouldBeUsed()) {
return;
}
for (Faction faction : Factions.i.get()) {
if (faction.money > 0) {
econ.depositPlayer(faction.getAccountId(), faction.money);
faction.money = 0;
}
}
}
// calculate the cost for claiming land
public static double calculateClaimCost(int ownedLand, boolean takingFromAnotherFaction) {
if (!shouldBeUsed()) {

View File

@ -72,7 +72,7 @@ public class FactionsBlockListener implements Listener {
return;
}
Faction pistonFaction = Board.getFactionAt(new FLocation(event.getBlock()));
Faction pistonFaction = Board.getInstance().getFactionAt(new FLocation(event.getBlock()));
// target end-of-the-line empty (air) block which is being pushed into, including if piston itself would extend into air
Block targetBlock = event.getBlock().getRelative(event.getDirection(), event.getLength() + 1);
@ -104,7 +104,7 @@ public class FactionsBlockListener implements Listener {
return;
}
Faction pistonFaction = Board.getFactionAt(new FLocation(event.getBlock()));
Faction pistonFaction = Board.getInstance().getFactionAt(new FLocation(event.getBlock()));
if (!canPistonMoveBlock(pistonFaction, targetLoc)) {
event.setCancelled(true);
@ -114,7 +114,7 @@ public class FactionsBlockListener implements Listener {
private boolean canPistonMoveBlock(Faction pistonFaction, Location target) {
Faction otherFaction = Board.getFactionAt(new FLocation(target));
Faction otherFaction = Board.getInstance().getFactionAt(new FLocation(target));
if (pistonFaction == otherFaction) {
return true;
@ -155,13 +155,13 @@ public class FactionsBlockListener implements Listener {
return true;
}
FPlayer me = FPlayers.i.get(player.getUniqueId().toString());
FPlayer me = FPlayers.getInstance().getById(player.getUniqueId().toString());
if (me.isAdminBypassing()) {
return true;
}
FLocation loc = new FLocation(location);
Faction otherFaction = Board.getFactionAt(loc);
Faction otherFaction = Board.getInstance().getFactionAt(loc);
if (otherFaction.isNone()) {
if (Conf.worldGuardBuildPriority && Worldguard.playerCanBuild(player, location)) {

View File

@ -32,7 +32,7 @@ public class FactionsChatListener implements Listener {
Player talkingPlayer = event.getPlayer();
String msg = event.getMessage();
FPlayer me = FPlayers.i.get(talkingPlayer);
FPlayer me = FPlayers.getInstance().getByPlayer(talkingPlayer);
ChatMode chat = me.getChatMode();
// Is it a faction chat message?
@ -45,7 +45,7 @@ public class FactionsChatListener implements Listener {
Bukkit.getLogger().log(Level.INFO, ChatColor.stripColor("FactionChat " + myFaction.getTag() + ": " + message));
//Send to any players who are spying chat
for (FPlayer fplayer : FPlayers.i.getOnline()) {
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
if (fplayer.isSpyingChat() && fplayer.getFaction() != myFaction) {
fplayer.sendMessage("[FCspy] " + myFaction.getTag() + ": " + message);
}
@ -61,7 +61,7 @@ public class FactionsChatListener implements Listener {
myFaction.sendMessage(message);
//Send to all our allies
for (FPlayer fplayer : FPlayers.i.getOnline()) {
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
if (myFaction.getRelationTo(fplayer) == Relation.ALLY) {
fplayer.sendMessage(message);
}
@ -94,7 +94,7 @@ public class FactionsChatListener implements Listener {
Player talkingPlayer = event.getPlayer();
String msg = event.getMessage();
String eventFormat = event.getFormat();
FPlayer me = FPlayers.i.get(talkingPlayer);
FPlayer me = FPlayers.getInstance().getByPlayer(talkingPlayer);
int InsertIndex;
if (!Conf.chatTagReplaceString.isEmpty() && eventFormat.contains(Conf.chatTagReplaceString)) {
@ -132,7 +132,7 @@ public class FactionsChatListener implements Listener {
event.setCancelled(true);
for (Player listeningPlayer : event.getRecipients()) {
FPlayer you = FPlayers.i.get(listeningPlayer);
FPlayer you = FPlayers.getInstance().getByPlayer(listeningPlayer);
String yourFormat = formatStart + me.getChatTag(you).trim() + formatEnd;
try {
listeningPlayer.sendMessage(String.format(yourFormat, talkingPlayer.getDisplayName(), msg));

View File

@ -40,8 +40,8 @@ public class FactionsEntityListener implements Listener {
}
Player player = (Player) entity;
FPlayer fplayer = FPlayers.i.get(player);
Faction faction = Board.getFactionAt(new FLocation(player.getLocation()));
FPlayer fplayer = FPlayers.getInstance().getByPlayer(player);
Faction faction = Board.getInstance().getFactionAt(new FLocation(player.getLocation()));
PowerLossEvent powerLossEvent = new PowerLossEvent(faction, fplayer);
// Check for no power loss conditions
@ -110,7 +110,7 @@ public class FactionsEntityListener implements Listener {
Location loc = event.getLocation();
Entity boomer = event.getEntity();
Faction faction = Board.getFactionAt(new FLocation(loc));
Faction faction = Board.getInstance().getFactionAt(new FLocation(loc));
if (faction.noExplosionsInTerritory()) {
// faction is peaceful and has explosions set to disabled
@ -207,7 +207,7 @@ public class FactionsEntityListener implements Listener {
if(thrower instanceof Player){
Player player = (Player) thrower;
FPlayer fPlayer = FPlayers.i.get(player);
FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player);
if(badjuju && fPlayer.getFaction().isPeaceful()){
event.setCancelled(true);
return;
@ -230,7 +230,7 @@ public class FactionsEntityListener implements Listener {
if (!(damagee instanceof Player)) {
return false;
}
if (Board.getFactionAt(new FLocation(damagee.getLocation())).isSafeZone()) {
if (Board.getInstance().getFactionAt(new FLocation(damagee.getLocation())).isSafeZone()) {
return true;
}
return false;
@ -249,14 +249,14 @@ public class FactionsEntityListener implements Listener {
return true;
}
FPlayer defender = FPlayers.i.get((Player) damagee);
FPlayer defender = FPlayers.getInstance().getByPlayer((Player) damagee);
if (defender == null || defender.getPlayer() == null) {
return true;
}
Location defenderLoc = defender.getPlayer().getLocation();
Faction defLocFaction = Board.getFactionAt(new FLocation(defenderLoc));
Faction defLocFaction = Board.getInstance().getFactionAt(new FLocation(defenderLoc));
// for damage caused by projectiles, getDamager() returns the projectile... what we need to know is the source
if (damager instanceof Projectile) {
@ -272,7 +272,7 @@ public class FactionsEntityListener implements Listener {
if (defLocFaction.noPvPInTerritory()) {
if (damager instanceof Player) {
if (notify) {
FPlayer attacker = FPlayers.i.get((Player) damager);
FPlayer attacker = FPlayers.getInstance().getByPlayer((Player) damager);
attacker.msg("<i>You can't hurt other players in " + (defLocFaction.isSafeZone() ? "a SafeZone." : "peaceful territory."));
}
return false;
@ -284,7 +284,7 @@ public class FactionsEntityListener implements Listener {
return true;
}
FPlayer attacker = FPlayers.i.get((Player) damager);
FPlayer attacker = FPlayers.getInstance().getByPlayer((Player) damager);
if (attacker == null || attacker.getPlayer() == null) {
return true;
@ -301,7 +301,7 @@ public class FactionsEntityListener implements Listener {
return false;
}
Faction locFaction = Board.getFactionAt(new FLocation(attacker));
Faction locFaction = Board.getInstance().getFactionAt(new FLocation(attacker));
// so we know from above that the defender isn't in a safezone... what about the attacker, sneaky dog that he might be?
if (locFaction.noPvPInTerritory()) {
@ -407,7 +407,7 @@ public class FactionsEntityListener implements Listener {
return;
}
if (Conf.safeZoneNerfedCreatureTypes.contains(event.getEntityType()) && Board.getFactionAt(new FLocation(event.getLocation())).noMonstersInTerritory()) {
if (Conf.safeZoneNerfedCreatureTypes.contains(event.getEntityType()) && Board.getInstance().getFactionAt(new FLocation(event.getLocation())).noMonstersInTerritory()) {
event.setCancelled(true);
}
}
@ -430,7 +430,7 @@ public class FactionsEntityListener implements Listener {
}
// in case the target is in a safe zone.
if (Board.getFactionAt(new FLocation(target.getLocation())).noMonstersInTerritory()) {
if (Board.getInstance().getFactionAt(new FLocation(target.getLocation())).noMonstersInTerritory()) {
event.setCancelled(true);
}
}
@ -442,7 +442,7 @@ public class FactionsEntityListener implements Listener {
}
if (event.getCause() == RemoveCause.EXPLOSION) {
Location loc = event.getEntity().getLocation();
Faction faction = Board.getFactionAt(new FLocation(loc));
Faction faction = Board.getInstance().getFactionAt(new FLocation(loc));
if (faction.noExplosionsInTerritory()) {
// faction is peaceful and has explosions set to disabled
event.setCancelled(true);
@ -505,7 +505,7 @@ public class FactionsEntityListener implements Listener {
event.setCancelled(true);
}
} else if (entity instanceof Wither) {
Faction faction = Board.getFactionAt(new FLocation(loc));
Faction faction = Board.getInstance().getFactionAt(new FLocation(loc));
// it's a bit crude just using fireball protection, but I'd rather not add in a whole new set of xxxBlockWitherExplosion or whatever
if ((faction.isNone() && Conf.wildernessBlockFireballs && !Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName())) ||
(faction.isNormal() && (faction.hasPlayersOnline() ? Conf.territoryBlockFireballs : Conf.territoryBlockFireballsWhenOffline)) ||
@ -530,7 +530,7 @@ public class FactionsEntityListener implements Listener {
}
FLocation fLoc = new FLocation(loc);
Faction claimFaction = Board.getFactionAt(fLoc);
Faction claimFaction = Board.getInstance().getFactionAt(fLoc);
if (claimFaction.isNone()) {
return Conf.wildernessDenyEndermanBlocks;

View File

@ -41,7 +41,7 @@ public class FactionsPlayerListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerJoin(PlayerJoinEvent event) {
// Make sure that all online players do have a fplayer.
final FPlayer me = FPlayers.i.get(event.getPlayer());
final FPlayer me = FPlayers.getInstance().getByPlayer(event.getPlayer());
// Update the lastLoginTime for this fplayer
me.setLastLoginTime(System.currentTimeMillis());
@ -68,7 +68,7 @@ public class FactionsPlayerListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerQuit(PlayerQuitEvent event) {
FPlayer me = FPlayers.i.get(event.getPlayer());
FPlayer me = FPlayers.getInstance().getByPlayer(event.getPlayer());
// Make sure player's power is up to date when they log off.
me.getPower();
@ -103,7 +103,7 @@ public class FactionsPlayerListener implements Listener {
}
Player player = event.getPlayer();
FPlayer me = FPlayers.i.get(player);
FPlayer me = FPlayers.getInstance().getByPlayer(player);
// Did we change coord?
FLocation from = me.getLastStoodAt();
@ -118,8 +118,8 @@ public class FactionsPlayerListener implements Listener {
me.setLastStoodAt(to);
// Did we change "host"(faction)?
Faction factionFrom = Board.getFactionAt(from);
Faction factionTo = Board.getFactionAt(to);
Faction factionFrom = Board.getInstance().getFactionAt(from);
Faction factionTo = Board.getInstance().getFactionAt(to);
boolean changedFaction = (factionFrom != factionTo);
if (me.isMapAutoUpdating()) {
@ -128,7 +128,7 @@ public class FactionsPlayerListener implements Listener {
P.p.log(Level.WARNING, "%s tried to show a faction map too soon and triggered exploit blocker.", player.getName());
}
} else {
me.sendMessage(Board.getMap(me.getFaction(), to, player.getLocation().getYaw()));
me.sendMessage(Board.getInstance().getMap(me.getFaction(), to, player.getLocation().getYaw()));
showTimes.put(player.getUniqueId(), System.currentTimeMillis() + P.p.getConfig().getLong("findfactionsexploit.cooldown", 2000));
}
} else {
@ -158,8 +158,8 @@ public class FactionsPlayerListener implements Listener {
if (!Permission.MANAGE_SAFE_ZONE.has(player)) {
me.setIsAutoSafeClaimEnabled(false);
} else {
if (!Board.getFactionAt(to).isSafeZone()) {
Board.setFactionAt(Factions.i.getSafeZone(), to);
if (!Board.getInstance().getFactionAt(to).isSafeZone()) {
Board.getInstance().setFactionAt(Factions.getInstance().getSafeZone(), to);
me.msg("<i>This land is now a safe zone.");
}
}
@ -167,8 +167,8 @@ public class FactionsPlayerListener implements Listener {
if (!Permission.MANAGE_WAR_ZONE.has(player)) {
me.setIsAutoWarClaimEnabled(false);
} else {
if (!Board.getFactionAt(to).isWarZone()) {
Board.setFactionAt(Factions.i.getWarZone(), to);
if (!Board.getInstance().getFactionAt(to).isWarZone()) {
Board.getInstance().setFactionAt(Factions.getInstance().getWarZone(), to);
me.msg("<i>This land is now a war zone.");
}
}
@ -203,7 +203,7 @@ public class FactionsPlayerListener implements Listener {
}
int count = attempt.increment();
if (count >= 10) {
FPlayer me = FPlayers.i.get(name);
FPlayer me = FPlayers.getInstance().getByPlayer(player);
me.msg("<b>Ouch, that is starting to hurt. You should give it a rest.");
player.damage(NumberConversions.floor((double) count / 10));
}
@ -249,13 +249,13 @@ public class FactionsPlayerListener implements Listener {
return true;
}
FPlayer me = FPlayers.i.get(player);
FPlayer me = FPlayers.getInstance().getByPlayer(player);
if (me.isAdminBypassing()) {
return true;
}
FLocation loc = new FLocation(location);
Faction otherFaction = Board.getFactionAt(loc);
Faction otherFaction = Board.getInstance().getFactionAt(loc);
if (otherFaction.hasPlayersOnline()) {
if (!Conf.territoryDenyUseageMaterials.contains(material)) {
@ -328,14 +328,14 @@ public class FactionsPlayerListener implements Listener {
return true;
}
FPlayer me = FPlayers.i.get(player);
FPlayer me = FPlayers.getInstance().getByPlayer(player);
if (me.isAdminBypassing()) {
return true;
}
Material material = block.getType();
FLocation loc = new FLocation(block);
Faction otherFaction = Board.getFactionAt(loc);
Faction otherFaction = Board.getInstance().getFactionAt(loc);
// no door/chest/whatever protection in wilderness, war zones, or safe zones
if (!otherFaction.isNormal()) {
@ -393,7 +393,7 @@ public class FactionsPlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerRespawn(PlayerRespawnEvent event) {
FPlayer me = FPlayers.i.get(event.getPlayer());
FPlayer me = FPlayers.getInstance().getByPlayer(event.getPlayer());
me.getPower(); // update power, so they won't have gained any while dead
@ -445,7 +445,7 @@ public class FactionsPlayerListener implements Listener {
fullCmd = fullCmd.toLowerCase();
FPlayer me = FPlayers.i.get(player);
FPlayer me = FPlayers.getInstance().getByPlayer(player);
String shortCmd; // command without the slash at the beginning
if (fullCmd.startsWith("/")) {
@ -509,7 +509,7 @@ public class FactionsPlayerListener implements Listener {
return;
}
FPlayer badGuy = FPlayers.i.get(event.getPlayer());
FPlayer badGuy = FPlayers.getInstance().getByPlayer(event.getPlayer());
if (badGuy == null) {
return;
}
@ -521,7 +521,7 @@ public class FactionsPlayerListener implements Listener {
}
badGuy.leave(false);
badGuy.detach();
badGuy.remove();
}
}

View File

@ -49,7 +49,7 @@ public class FScoreboard {
}
public static FScoreboard get(Player player) {
return fscoreboards.get(FPlayers.i.get(player));
return fscoreboards.get(FPlayers.getInstance().getByPlayer(player));
}
private FScoreboard(FPlayer fplayer) {

View File

@ -40,7 +40,7 @@ public class FTeamWrapper {
FTeamWrapper wrapper = wrappers.get(faction);
Set<FPlayer> factionMembers = faction.getFPlayers();
if (wrapper != null && !Factions.i.get().contains(faction)) {
if (wrapper != null && Factions.getInstance().getFactionById(faction.getId()) != null) {
// Faction was disbanded
wrapper.unregister();
wrappers.remove(faction);
@ -53,7 +53,7 @@ public class FTeamWrapper {
}
for (OfflinePlayer player : wrapper.getPlayers()) {
if (!player.isOnline() || !factionMembers.contains(FPlayers.i.get(player))) {
if (!player.isOnline() || !factionMembers.contains(FPlayers.getInstance().getByOfflinePlayer(player))) {
// Player is offline or no longer in faction
wrapper.removePlayer(player);
}

View File

@ -15,7 +15,7 @@ public class AutoLeaveProcessTask extends BukkitRunnable {
private transient double toleranceMillis;
public AutoLeaveProcessTask() {
ArrayList<FPlayer> fplayers = new ArrayList<FPlayer>(FPlayers.i.get());
ArrayList<FPlayer> fplayers = new ArrayList<FPlayer>(FPlayers.getInstance().getAllFPlayers());
this.iterator = fplayers.listIterator();
this.toleranceMillis = Conf.autoLeaveAfterDaysOfInactivity * 24 * 60 * 60 * 1000;
this.readyToGo = true;
@ -61,7 +61,7 @@ public class AutoLeaveProcessTask extends BukkitRunnable {
fplayer.leave(false);
iterator.remove(); // go ahead and remove this list's link to the FPlayer object
fplayer.detach();
fplayer.remove();
}
}

View File

@ -1,5 +1,7 @@
package com.massivecraft.factions.util;
import java.io.Serializable;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
@ -9,9 +11,9 @@ import org.bukkit.World;
* yet when an object of this class is created, only when the Location is first accessed.
*/
public class LazyLocation {
private Location location = null;
public class LazyLocation implements Serializable {
private static final long serialVersionUID = -6049901271320963314L;
private transient Location location = null;
private String worldName;
private double x;
private double y;

View File

@ -5,6 +5,10 @@ import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.P;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@ -55,5 +59,24 @@ public class MiscUtil {
return ret.toLowerCase();
}
public static ArrayList<String> validateTag(String str) {
ArrayList<String> errors = new ArrayList<String>();
if (getComparisonString(str).length() < Conf.factionTagLengthMin) {
errors.add(P.p.txt.parse("<i>The faction tag can't be shorter than <h>%s<i> chars.", Conf.factionTagLengthMin));
}
if (str.length() > Conf.factionTagLengthMax) {
errors.add(P.p.txt.parse("<i>The faction tag can't be longer than <h>%s<i> chars.", Conf.factionTagLengthMax));
}
for (char c : str.toCharArray()) {
if (!substanceChars.contains(String.valueOf(c))) {
errors.add(P.p.txt.parse("<i>Faction tag must be alphanumeric. \"<h>%s<i>\" is not allowed.", c));
}
}
return errors;
}
}

View File

@ -3,13 +3,16 @@ package com.massivecraft.factions.zcore;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.zcore.persist.EM;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.zcore.persist.SaveTask;
import com.massivecraft.factions.zcore.util.PermUtil;
import com.massivecraft.factions.zcore.util.Persist;
import com.massivecraft.factions.zcore.util.TL;
import com.massivecraft.factions.zcore.util.TextUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
@ -180,7 +183,9 @@ public abstract class MPlugin extends JavaPlugin {
}
// only save data if plugin actually loaded successfully
if (loadSuccessful) {
EM.saveAllToDisc();
Factions.getInstance().forceSave();
FPlayers.getInstance().forceSave();
Board.getInstance().forceSave();
}
log("Disabled");
}

View File

@ -1,10 +1,7 @@
package com.massivecraft.factions.zcore;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.listeners.FactionsPlayerListener;
import com.massivecraft.factions.zcore.persist.EM;
import com.massivecraft.factions.zcore.persist.Entity;
import com.massivecraft.factions.zcore.persist.EntityCollection;
import com.massivecraft.factions.zcore.persist.PlayerEntityCollection;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -50,10 +47,6 @@ public class MPluginSecretPlayerListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerPreLogin(PlayerLoginEvent event) {
for (EntityCollection<? extends Entity> ecoll : EM.class2Entities.values()) {
if (ecoll instanceof PlayerEntityCollection) {
ecoll.get(event.getPlayer().getName());
}
}
FPlayers.getInstance().getByPlayer(event.getPlayer());
}
}

View File

@ -1,62 +0,0 @@
package com.massivecraft.factions.zcore.persist;
import java.util.LinkedHashMap;
import java.util.Map;
public class EM {
public static Map<Class<? extends Entity>, EntityCollection<? extends Entity>> class2Entities = new LinkedHashMap<Class<? extends Entity>, EntityCollection<? extends Entity>>();
@SuppressWarnings("unchecked")
public static <T extends Entity> EntityCollection<T> getEntitiesCollectionForEntityClass(Class<T> entityClass) {
return (EntityCollection<T>) class2Entities.get(entityClass);
}
public static void setEntitiesCollectionForEntityClass(Class<? extends Entity> entityClass, EntityCollection<? extends Entity> entities) {
class2Entities.put(entityClass, entities);
}
// -------------------------------------------- //
// ATTACH AND DETACH
// -------------------------------------------- //
@SuppressWarnings("unchecked")
public static <T extends Entity> void attach(T entity) {
EntityCollection<T> ec = (EntityCollection<T>) getEntitiesCollectionForEntityClass(entity.getClass());
ec.attach(entity);
}
@SuppressWarnings("unchecked")
public static <T extends Entity> void detach(T entity) {
EntityCollection<T> ec = (EntityCollection<T>) getEntitiesCollectionForEntityClass(entity.getClass());
ec.detach(entity);
}
@SuppressWarnings("unchecked")
public static <T extends Entity> boolean attached(T entity) {
EntityCollection<T> ec = (EntityCollection<T>) getEntitiesCollectionForEntityClass(entity.getClass());
return ec.attached(entity);
}
@SuppressWarnings("unchecked")
public static <T extends Entity> boolean detached(T entity) {
EntityCollection<T> ec = (EntityCollection<T>) getEntitiesCollectionForEntityClass(entity.getClass());
return ec.detached(entity);
}
// -------------------------------------------- //
// DISC
// -------------------------------------------- //
public static void saveAllToDisc() {
for (EntityCollection<? extends Entity> ec : class2Entities.values()) {
ec.saveToDisc();
}
}
public static void loadAllFromDisc() {
for (EntityCollection<? extends Entity> ec : class2Entities.values()) {
ec.loadFromDisc();
}
}
}

View File

@ -1,54 +0,0 @@
package com.massivecraft.factions.zcore.persist;
public abstract class Entity {
public Entity() {
}
protected transient String id = null;
public String getId() {
return id;
}
protected void setId(String id) {
this.id = id;
}
public boolean shouldBeSaved() {
return true;
}
// -------------------------------------------- //
// ATTACH AND DETACH
// -------------------------------------------- //
public void attach() {
EM.attach(this);
}
public void detach() {
EM.detach(this);
}
public boolean attached() {
return EM.attached(this);
}
public boolean detached() {
return EM.detached(this);
}
// -------------------------------------------- //
// EVENTS
// -------------------------------------------- //
public void preDetach() {
}
public void postDetach() {
}
}

View File

@ -1,467 +0,0 @@
package com.massivecraft.factions.zcore.persist;
import com.google.gson.Gson;
import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.zcore.util.DiscUtil;
import com.massivecraft.factions.zcore.util.TextUtil;
import com.massivecraft.factions.zcore.util.UUIDFetcher;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Level;
public abstract class EntityCollection<E extends Entity> {
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
// These must be instantiated in order to allow for different configuration (orders, comparators etc)
private Collection<E> entities;
protected Map<String, E> id2entity;
// If the entities are creative they will create a new instance if a non existent id was requested
private boolean creative;
public boolean isCreative() {
return creative;
}
public void setCreative(boolean creative) {
this.creative = creative;
}
// This is the auto increment for the primary key "id"
private int nextId;
// This ugly crap is necessary due to java type erasure
private Class<E> entityClass;
public abstract Type getMapType(); // This is special stuff for GSON.
// Info on how to persist
private Gson gson;
public Gson getGson() {
return gson;
}
public void setGson(Gson gson) {
this.gson = gson;
}
private File file;
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
// -------------------------------------------- //
// CONSTRUCTORS
// -------------------------------------------- //
public EntityCollection(Class<E> entityClass, Collection<E> entities, Map<String, E> id2entity, File file, Gson gson, boolean creative) {
this.entityClass = entityClass;
this.entities = entities;
this.id2entity = id2entity;
this.file = file;
this.gson = gson;
this.creative = creative;
this.nextId = 1;
EM.setEntitiesCollectionForEntityClass(this.entityClass, this);
}
public EntityCollection(Class<E> entityClass, Collection<E> entities, Map<String, E> id2entity, File file, Gson gson) {
this(entityClass, entities, id2entity, file, gson, false);
}
// -------------------------------------------- //
// GET
// -------------------------------------------- //
public Collection<E> get() {
return entities;
}
public Map<String, E> getMap() {
return this.id2entity;
}
public E get(String id) {
if (this.creative) {
return this.getCreative(id);
}
return id2entity.get(id);
}
public E getCreative(String id) {
E e = id2entity.get(id);
if (e != null) {
return e;
}
return this.create(id);
}
public boolean exists(String id) {
if (id == null) {
return false;
}
return id2entity.get(id) != null;
}
public E getBestIdMatch(String pattern) {
String id = TextUtil.getBestStartWithCI(this.id2entity.keySet(), pattern);
if (id == null) {
return null;
}
return this.id2entity.get(id);
}
// -------------------------------------------- //
// CREATE
// -------------------------------------------- //
public synchronized E create() {
return this.create(this.getNextId());
}
public synchronized E create(String id) {
if (!this.isIdFree(id)) {
return null;
}
E e = null;
try {
e = this.entityClass.newInstance();
} catch (Exception ignored) {
ignored.printStackTrace();
}
e.setId(id);
this.entities.add(e);
this.id2entity.put(e.getId(), e);
this.updateNextIdForId(id);
return e;
}
// -------------------------------------------- //
// ATTACH AND DETACH
// -------------------------------------------- //
public void attach(E entity) {
if (entity.getId() != null) {
return;
}
entity.setId(this.getNextId());
this.entities.add(entity);
this.id2entity.put(entity.getId(), entity);
}
public void detach(E entity) {
entity.preDetach();
this.entities.remove(entity);
this.id2entity.remove(entity.getId());
entity.postDetach();
}
public void detach(String id) {
E entity = this.id2entity.get(id);
if (entity == null) {
return;
}
this.detach(entity);
}
public boolean attached(E entity) {
return this.entities.contains(entity);
}
public boolean detached(E entity) {
return !this.attached(entity);
}
// -------------------------------------------- //
// DISC
// -------------------------------------------- //
// we don't want to let saveToDisc() run multiple iterations simultaneously
private boolean saveIsRunning = false;
public boolean saveToDisc() {
if (saveIsRunning) {
return true;
}
saveIsRunning = true;
Map<String, E> entitiesThatShouldBeSaved = new HashMap<String, E>();
for (E entity : this.entities) {
if (entity.shouldBeSaved()) {
entitiesThatShouldBeSaved.put(entity.getId(), entity);
}
}
saveIsRunning = false;
return this.saveCore(this.file, entitiesThatShouldBeSaved);
}
private boolean saveCore(File target, Map<String, E> entities) {
return DiscUtil.writeCatch(target, this.gson.toJson(entities));
}
public boolean loadFromDisc() {
Map<String, E> id2entity = this.loadCore();
if (id2entity == null) {
return false;
}
this.entities.clear();
this.entities.addAll(id2entity.values());
this.id2entity.clear();
this.id2entity.putAll(id2entity);
this.fillIds();
return true;
}
private Map<String, E> loadCore() {
if (!this.file.exists()) {
return new HashMap<String, E>();
}
String content = DiscUtil.readCatch(this.file);
if (content == null) {
return null;
}
Type type = this.getMapType();
if (type.toString().contains("FPlayer")) {
Map<String, FPlayer> data = this.gson.fromJson(content, type);
Set<String> list = whichKeysNeedMigration(data.keySet());
Set<String> invalidList = whichKeysAreInvalid(list);
list.removeAll(invalidList);
if (list.size() > 0) {
// We've got some converting to do!
Bukkit.getLogger().log(Level.INFO, "Factions is now updating players.json");
// First we'll make a backup, because god forbid anybody heed a warning
File file = new File(this.file.getParentFile(), "players.json.old");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
saveCore(file, (Map<String, E>) data);
Bukkit.getLogger().log(Level.INFO, "Backed up your old data at " + file.getAbsolutePath());
// Start fetching those UUIDs
Bukkit.getLogger().log(Level.INFO, "Please wait while Factions converts " + list.size() + " old player names to UUID. This may take a while.");
UUIDFetcher fetcher = new UUIDFetcher(new ArrayList(list));
try {
Map<String, UUID> response = fetcher.call();
for (String s : list) {
// Are we missing any responses?
if (!response.containsKey(s)) {
// They don't have a UUID so they should just be removed
invalidList.add(s);
}
}
for (String value : response.keySet()) {
// For all the valid responses, let's replace their old named entry with a UUID key
String id = response.get(value).toString();
FPlayer player = data.get(value);
if (player == null) {
// The player never existed here, and shouldn't persist
invalidList.add(value);
continue;
}
player.setId(id); // Update the object so it knows
data.remove(value); // Out with the old...
data.put(id, player); // And in with the new
}
} catch (Exception e) {
e.printStackTrace();
}
if (invalidList.size() > 0) {
for (String name : invalidList) {
// Remove all the invalid names we collected
data.remove(name);
}
Bukkit.getLogger().log(Level.INFO, "While converting we found names that either don't have a UUID or aren't players and removed them from storage.");
Bukkit.getLogger().log(Level.INFO, "The following names were detected as being invalid: " + StringUtils.join(invalidList, ", "));
}
saveCore(this.file, (Map<String, E>) data); // Update the flatfile
Bukkit.getLogger().log(Level.INFO, "Done converting players.json to UUID.");
}
return (Map<String, E>) data;
} else {
Map<String, Faction> data = this.gson.fromJson(content, type);
// Do we have any names that need updating in claims or invites?
int needsUpdate = 0;
for (String string : data.keySet()) {
Faction f = data.get(string);
needsUpdate += whichKeysNeedMigration(f.getInvites()).size();
Map<FLocation, Set<String>> claims = f.getClaimOwnership();
for (FLocation key : f.getClaimOwnership().keySet()) {
needsUpdate += whichKeysNeedMigration(claims.get(key)).size();
}
}
if (needsUpdate > 0) {
// We've got some converting to do!
Bukkit.getLogger().log(Level.INFO, "Factions is now updating factions.json");
// First we'll make a backup, because god forbid anybody heed a warning
File file = new File(this.file.getParentFile(), "factions.json.old");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
saveCore(file, (Map<String, E>) data);
Bukkit.getLogger().log(Level.INFO, "Backed up your old data at " + file.getAbsolutePath());
Bukkit.getLogger().log(Level.INFO, "Please wait while Factions converts " + needsUpdate + " old player names to UUID. This may take a while.");
// Update claim ownership
for (String string : data.keySet()) {
Faction f = data.get(string);
Map<FLocation, Set<String>> claims = f.getClaimOwnership();
for (FLocation key : claims.keySet()) {
Set<String> set = claims.get(key);
Set<String> list = whichKeysNeedMigration(set);
if (list.size() > 0) {
UUIDFetcher fetcher = new UUIDFetcher(new ArrayList(list));
try {
Map<String, UUID> response = fetcher.call();
for (String value : response.keySet()) {
// Let's replace their old named entry with a UUID key
String id = response.get(value).toString();
set.remove(value.toLowerCase()); // Out with the old...
set.add(id); // And in with the new
}
} catch (Exception e) {
e.printStackTrace();
}
claims.put(key, set); // Update
}
}
}
// Update invites
for (String string : data.keySet()) {
Faction f = data.get(string);
Set<String> invites = f.getInvites();
Set<String> list = whichKeysNeedMigration(invites);
if (list.size() > 0) {
UUIDFetcher fetcher = new UUIDFetcher(new ArrayList(list));
try {
Map<String, UUID> response = fetcher.call();
for (String value : response.keySet()) {
// Let's replace their old named entry with a UUID key
String id = response.get(value).toString();
invites.remove(value.toLowerCase()); // Out with the old...
invites.add(id); // And in with the new
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
saveCore(this.file, (Map<String, E>) data); // Update the flatfile
Bukkit.getLogger().log(Level.INFO, "Done converting factions.json to UUID.");
}
return (Map<String, E>) data;
}
}
private Set<String> whichKeysNeedMigration(Set<String> keys) {
HashSet<String> list = new HashSet<String>();
for (String value : keys) {
if (!value.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")) {
// Not a valid UUID..
if (value.matches("[a-zA-Z0-9_]{2,16}")) {
// Valid playername, we'll mark this as one for conversion to UUID
list.add(value);
}
}
}
return list;
}
private Set<String> whichKeysAreInvalid(Set<String> keys) {
Set<String> list = new HashSet<String>();
for (String value : keys) {
if (!value.matches("[a-zA-Z0-9_]{2,16}")) {
// Not a valid player name.. go ahead and mark it for removal
list.add(value);
}
}
return list;
}
// -------------------------------------------- //
// ID MANAGEMENT
// -------------------------------------------- //
public String getNextId() {
while (!isIdFree(this.nextId)) {
this.nextId += 1;
}
return Integer.toString(this.nextId);
}
public boolean isIdFree(String id) {
return !this.id2entity.containsKey(id);
}
public boolean isIdFree(int id) {
return this.isIdFree(Integer.toString(id));
}
protected synchronized void fillIds() {
this.nextId = 1;
for (Entry<String, E> entry : this.id2entity.entrySet()) {
String id = entry.getKey();
E entity = entry.getValue();
entity.id = id;
this.updateNextIdForId(id);
}
}
protected synchronized void updateNextIdForId(int id) {
if (this.nextId < id) {
this.nextId = id + 1;
}
}
protected void updateNextIdForId(String id) {
try {
int idAsInt = Integer.parseInt(id);
this.updateNextIdForId(idAsInt);
} catch (Exception ignored) {
}
}
}

View File

@ -0,0 +1,230 @@
package com.massivecraft.factions.zcore.persist;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.P;
import com.massivecraft.factions.struct.Relation;
import com.massivecraft.factions.util.AsciiCompass;
import org.bukkit.ChatColor;
import java.util.*;
import java.util.Map.Entry;
public abstract class MemoryBoard extends Board {
public HashMap<FLocation, String> flocationIds = new HashMap<FLocation, String>();
//----------------------------------------------//
// Get and Set
//----------------------------------------------//
public String getIdAt(FLocation flocation) {
if (!flocationIds.containsKey(flocation)) {
return "0";
}
return flocationIds.get(flocation);
}
public Faction getFactionAt(FLocation flocation) {
return Factions.getInstance().getFactionById(getIdAt(flocation));
}
public void setIdAt(String id, FLocation flocation) {
clearOwnershipAt(flocation);
if (id.equals("0")) {
removeAt(flocation);
}
flocationIds.put(flocation, id);
}
public void setFactionAt(Faction faction, FLocation flocation) {
setIdAt(faction.getId(), flocation);
}
public void removeAt(FLocation flocation) {
clearOwnershipAt(flocation);
flocationIds.remove(flocation);
}
// not to be confused with claims, ownership referring to further member-specific ownership of a claim
public void clearOwnershipAt(FLocation flocation) {
Faction faction = getFactionAt(flocation);
if (faction != null && faction.isNormal()) {
faction.clearClaimOwnership(flocation);
}
}
public void unclaimAll(String factionId) {
Faction faction = Factions.getInstance().getFactionById(factionId);
if (faction != null && faction.isNormal()) {
faction.clearAllClaimOwnership();
}
clean(factionId);
}
public void clean(String factionId) {
Iterator<Entry<FLocation, String>> iter = flocationIds.entrySet().iterator();
while (iter.hasNext()) {
Entry<FLocation, String> entry = iter.next();
if (entry.getValue().equals(factionId)) {
iter.remove();
}
}
}
// Is this coord NOT completely surrounded by coords claimed by the same faction?
// Simpler: Is there any nearby coord with a faction other than the faction here?
public boolean isBorderLocation(FLocation flocation) {
Faction faction = getFactionAt(flocation);
FLocation a = flocation.getRelative(1, 0);
FLocation b = flocation.getRelative(-1, 0);
FLocation c = flocation.getRelative(0, 1);
FLocation d = flocation.getRelative(0, -1);
return faction != getFactionAt(a) || faction != getFactionAt(b) || faction != getFactionAt(c) || faction != getFactionAt(d);
}
// Is this coord connected to any coord claimed by the specified faction?
public boolean isConnectedLocation(FLocation flocation, Faction faction) {
FLocation a = flocation.getRelative(1, 0);
FLocation b = flocation.getRelative(-1, 0);
FLocation c = flocation.getRelative(0, 1);
FLocation d = flocation.getRelative(0, -1);
return faction == getFactionAt(a) || faction == getFactionAt(b) || faction == getFactionAt(c) || faction == getFactionAt(d);
}
//----------------------------------------------//
// Cleaner. Remove orphaned foreign keys
//----------------------------------------------//
public void clean() {
Iterator<Entry<FLocation, String>> iter = flocationIds.entrySet().iterator();
while (iter.hasNext()) {
Entry<FLocation, String> entry = iter.next();
if (!Factions.getInstance().isValidFactionId(entry.getValue())) {
P.p.log("Board cleaner removed " + entry.getValue() + " from " + entry.getKey());
iter.remove();
}
}
}
//----------------------------------------------//
// Coord count
//----------------------------------------------//
public int getFactionCoordCount(String factionId) {
int ret = 0;
for (String thatFactionId : flocationIds.values()) {
if (thatFactionId.equals(factionId)) {
ret += 1;
}
}
return ret;
}
public int getFactionCoordCount(Faction faction) {
return getFactionCoordCount(faction.getId());
}
public int getFactionCoordCountInWorld(Faction faction, String worldName) {
String factionId = faction.getId();
int ret = 0;
Iterator<Entry<FLocation, String>> iter = flocationIds.entrySet().iterator();
while (iter.hasNext()) {
Entry<FLocation, String> entry = iter.next();
if (entry.getValue().equals(factionId) && entry.getKey().getWorldName().equals(worldName)) {
ret += 1;
}
}
return ret;
}
//----------------------------------------------//
// Map generation
//----------------------------------------------//
/**
* The map is relative to a coord and a faction north is in the direction of decreasing x east is in the direction
* of decreasing z
*/
public ArrayList<String> getMap(Faction faction, FLocation flocation, double inDegrees) {
ArrayList<String> ret = new ArrayList<String>();
Faction factionLoc = getFactionAt(flocation);
ret.add(P.p.txt.titleize("(" + flocation.getCoordString() + ") " + factionLoc.getTag(faction)));
int halfWidth = Conf.mapWidth / 2;
int halfHeight = Conf.mapHeight / 2;
FLocation topLeft = flocation.getRelative(-halfWidth, -halfHeight);
int width = halfWidth * 2 + 1;
int height = halfHeight * 2 + 1;
if (Conf.showMapFactionKey) {
height--;
}
Map<String, Character> fList = new HashMap<String, Character>();
int chrIdx = 0;
// For each row
for (int dz = 0; dz < height; dz++) {
// Draw and add that row
String row = "";
for (int dx = 0; dx < width; dx++) {
if (dx == halfWidth && dz == halfHeight) {
row += ChatColor.AQUA + "+";
} else {
FLocation flocationHere = topLeft.getRelative(dx, dz);
Faction factionHere = getFactionAt(flocationHere);
Relation relation = faction.getRelationTo(factionHere);
if (factionHere.isNone()) {
row += ChatColor.GRAY + "-";
} else if (factionHere.isSafeZone()) {
row += Conf.colorPeaceful + "+";
} else if (factionHere.isWarZone()) {
row += ChatColor.DARK_RED + "+";
} else if (factionHere == faction ||
factionHere == factionLoc ||
relation.isAtLeast(Relation.ALLY) ||
(Conf.showNeutralFactionsOnMap && relation.equals(Relation.NEUTRAL)) ||
(Conf.showEnemyFactionsOnMap && relation.equals(Relation.ENEMY))) {
if (!fList.containsKey(factionHere.getTag())) {
fList.put(factionHere.getTag(), Conf.mapKeyChrs[Math.min(chrIdx++, Conf.mapKeyChrs.length - 1)]);
}
char tag = fList.get(factionHere.getTag());
row += factionHere.getColorTo(faction) + "" + tag;
} else {
row += ChatColor.GRAY + "-";
}
}
}
ret.add(row);
}
// Get the compass
ArrayList<String> asciiCompass = AsciiCompass.getAsciiCompass(inDegrees, ChatColor.RED, P.p.txt.parse("<a>"));
// Add the compass
ret.set(1, asciiCompass.get(0) + ret.get(1).substring(3 * 3));
ret.set(2, asciiCompass.get(1) + ret.get(2).substring(3 * 3));
ret.set(3, asciiCompass.get(2) + ret.get(3).substring(3 * 3));
// Add the faction key
if (Conf.showMapFactionKey) {
String fRow = "";
for (String key : fList.keySet()) {
fRow += String.format("%s%s: %s ", ChatColor.GRAY, fList.get(key), key);
}
ret.add(fRow);
}
return ret;
}
public abstract void convertFrom(MemoryBoard old);
}

View File

@ -0,0 +1,829 @@
package com.massivecraft.factions.zcore.persist;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.P;
import com.massivecraft.factions.event.FPlayerLeaveEvent;
import com.massivecraft.factions.event.LandClaimEvent;
import com.massivecraft.factions.iface.EconomyParticipator;
import com.massivecraft.factions.iface.RelationParticipator;
import com.massivecraft.factions.integration.Econ;
import com.massivecraft.factions.integration.Worldguard;
import com.massivecraft.factions.scoreboards.FScoreboard;
import com.massivecraft.factions.scoreboards.sidebar.FInfoSidebar;
import com.massivecraft.factions.struct.ChatMode;
import com.massivecraft.factions.struct.Permission;
import com.massivecraft.factions.struct.Relation;
import com.massivecraft.factions.struct.Role;
import com.massivecraft.factions.util.RelationUtil;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* Logged in players always have exactly one FPlayer instance. Logged out players may or may not have an FPlayer
* instance. They will always have one if they are part of a faction. This is because only players with a faction are
* saved to disk (in order to not waste disk space).
* <p/>
* The FPlayer is linked to a minecraft player using the player name.
* <p/>
* The same instance is always returned for the same player. This means you can use the == operator. No .equals method
* necessary.
*/
public abstract class MemoryFPlayer implements FPlayer {
// FIELD: factionId
protected String factionId;
// FIELD: role
protected Role role;
// FIELD: title
protected String title;
// FIELD: power
protected double power;
// FIELD: powerBoost
// special increase/decrease to min and max power for this player
protected double powerBoost;
// FIELD: lastPowerUpdateTime
protected long lastPowerUpdateTime;
// FIELD: lastLoginTime
protected long lastLoginTime;
// FIELD: chatMode
protected ChatMode chatMode;
protected String id;
//private transient String playerName;
protected transient FLocation lastStoodAt = new FLocation(); // Where did this player stand the last time we checked?
// FIELD: mapAutoUpdating
protected transient boolean mapAutoUpdating;
// FIELD: autoClaimEnabled
protected transient Faction autoClaimFor;
// FIELD: autoSafeZoneEnabled
protected transient boolean autoSafeZoneEnabled;
// FIELD: autoWarZoneEnabled
protected transient boolean autoWarZoneEnabled;
protected transient boolean isAdminBypassing = false;
// FIELD: loginPvpDisabled
protected transient boolean loginPvpDisabled;
// FIELD: chatSpy
protected transient boolean spyingChat = false;
public Faction getFaction() {
if (this.factionId == null) {
return null;
}
return Factions.getInstance().getFactionById(this.factionId);
}
public String getFactionId() {
return this.factionId;
}
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();
}
public Role getRole() {
return this.role;
}
public void setRole(Role role) {
this.role = role;
}
public double getPowerBoost() {
return this.powerBoost;
}
public void setPowerBoost(double powerBoost) {
this.powerBoost = powerBoost;
}
public Faction getAutoClaimFor() {
return autoClaimFor;
}
public void setAutoClaimFor(Faction faction) {
this.autoClaimFor = faction;
if (this.autoClaimFor != null) {
// TODO: merge these into same autoclaim
this.autoSafeZoneEnabled = false;
this.autoWarZoneEnabled = false;
}
}
public boolean isAutoSafeClaimEnabled() {
return autoSafeZoneEnabled;
}
public void setIsAutoSafeClaimEnabled(boolean enabled) {
this.autoSafeZoneEnabled = enabled;
if (enabled) {
this.autoClaimFor = null;
this.autoWarZoneEnabled = false;
}
}
public boolean isAutoWarClaimEnabled() {
return autoWarZoneEnabled;
}
public void setIsAutoWarClaimEnabled(boolean enabled) {
this.autoWarZoneEnabled = enabled;
if (enabled) {
this.autoClaimFor = null;
this.autoSafeZoneEnabled = false;
}
}
public boolean isAdminBypassing() {
return this.isAdminBypassing;
}
public void setIsAdminBypassing(boolean val) {
this.isAdminBypassing = val;
}
public void setChatMode(ChatMode chatMode) {
this.chatMode = chatMode;
}
public ChatMode getChatMode() {
if (this.factionId.equals("0") || !Conf.factionOnlyChat) {
this.chatMode = ChatMode.PUBLIC;
}
return chatMode;
}
public void setSpyingChat(boolean chatSpying) {
this.spyingChat = chatSpying;
}
public boolean isSpyingChat() {
return spyingChat;
}
// FIELD: account
public String getAccountId() {
return this.getId();
}
public MemoryFPlayer() { }
public MemoryFPlayer(String id) {
this.id = id;
this.resetFactionData(false);
this.power = Conf.powerPlayerStarting;
this.lastPowerUpdateTime = System.currentTimeMillis();
this.lastLoginTime = System.currentTimeMillis();
this.mapAutoUpdating = false;
this.autoClaimFor = null;
this.autoSafeZoneEnabled = false;
this.autoWarZoneEnabled = false;
this.loginPvpDisabled = Conf.noPVPDamageToOthersForXSecondsAfterLogin > 0;
this.powerBoost = 0.0;
if (!Conf.newPlayerStartingFactionID.equals("0") && Factions.getInstance().isValidFactionId(Conf.newPlayerStartingFactionID)) {
this.factionId = Conf.newPlayerStartingFactionID;
}
}
public MemoryFPlayer(MemoryFPlayer other) {
this.factionId = other.factionId;
this.id = other.id;
this.power = other.power;
this.lastLoginTime = other.lastLoginTime;
this.mapAutoUpdating = other.mapAutoUpdating;
this.autoClaimFor = other.autoClaimFor;
this.autoSafeZoneEnabled = other.autoSafeZoneEnabled;
this.autoWarZoneEnabled = other.autoWarZoneEnabled;
this.loginPvpDisabled = other.loginPvpDisabled;
this.powerBoost = other.powerBoost;
this.role = other.role;
this.title = other.title;
this.chatMode = other.chatMode;
this.spyingChat = other.spyingChat;
this.lastStoodAt = other.lastStoodAt;
this.isAdminBypassing = other.isAdminBypassing;
}
public void resetFactionData(boolean doSpoutUpdate) {
// clean up any territory ownership in old faction, if there is one
if (factionId != null && Factions.getInstance().isValidFactionId(this.getFactionId())) {
Faction currentFaction = this.getFaction();
currentFaction.removeFPlayer(this);
if (currentFaction.isNormal()) {
currentFaction.clearClaimOwnership(this);
}
}
this.factionId = "0"; // The default neutral faction
this.chatMode = ChatMode.PUBLIC;
this.role = Role.NORMAL;
this.title = "";
this.autoClaimFor = null;
}
public void resetFactionData() {
this.resetFactionData(true);
}
// -------------------------------------------- //
// Getters And Setters
// -------------------------------------------- //
public long getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(long lastLoginTime) {
losePowerFromBeingOffline();
this.lastLoginTime = lastLoginTime;
this.lastPowerUpdateTime = lastLoginTime;
if (Conf.noPVPDamageToOthersForXSecondsAfterLogin > 0) {
this.loginPvpDisabled = true;
}
}
public boolean isMapAutoUpdating() {
return mapAutoUpdating;
}
public void setMapAutoUpdating(boolean mapAutoUpdating) {
this.mapAutoUpdating = mapAutoUpdating;
}
public boolean hasLoginPvpDisabled() {
if (!loginPvpDisabled) {
return false;
}
if (this.lastLoginTime + (Conf.noPVPDamageToOthersForXSecondsAfterLogin * 1000) < System.currentTimeMillis()) {
this.loginPvpDisabled = false;
return false;
}
return true;
}
public FLocation getLastStoodAt() {
return this.lastStoodAt;
}
public void setLastStoodAt(FLocation flocation) {
this.lastStoodAt = flocation;
}
//----------------------------------------------//
// Title, Name, Faction Tag and Chat
//----------------------------------------------//
// Base:
public String getTitle() {
return this.hasFaction() ? title : "";
}
public void setTitle(String title) {
this.title = title;
}
public String getName() {
if (isOnline()) {
return getPlayer().getName();
}
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(getId()));
return player.getName() != null ? player.getName() : getId();
}
public String getTag() {
return this.hasFaction() ? this.getFaction().getTag() : "";
}
// Base concatenations:
public String getNameAndSomething(String something) {
String ret = this.role.getPrefix();
if (something.length() > 0) {
ret += something + " ";
}
ret += this.getName();
return ret;
}
public String getNameAndTitle() {
return this.getNameAndSomething(this.getTitle());
}
public String getNameAndTag() {
return this.getNameAndSomething(this.getTag());
}
// Colored concatenations:
// These are used in information messages
public String getNameAndTitle(Faction faction) {
return this.getColorTo(faction) + this.getNameAndTitle();
}
public String getNameAndTitle(MemoryFPlayer fplayer) {
return this.getColorTo(fplayer) + this.getNameAndTitle();
}
// Chat Tag:
// These are injected into the format of global chat messages.
public String getChatTag() {
return this.hasFaction() ? String.format(Conf.chatTagFormat, this.role.getPrefix() + this.getTag()) : "";
}
// Colored Chat Tag
public String getChatTag(Faction faction) {
return this.hasFaction() ? this.getRelationTo(faction).getColor() + getChatTag() : "";
}
public String getChatTag(MemoryFPlayer fplayer) {
return this.hasFaction() ? this.getColorTo(fplayer) + getChatTag() : "";
}
// -------------------------------
// Relation and relation colors
// -------------------------------
@Override
public String describeTo(RelationParticipator that, boolean ucfirst) {
return RelationUtil.describeThatToMe(this, that, ucfirst);
}
@Override
public String describeTo(RelationParticipator that) {
return RelationUtil.describeThatToMe(this, that);
}
@Override
public Relation getRelationTo(RelationParticipator rp) {
return RelationUtil.getRelationTo(this, rp);
}
@Override
public Relation getRelationTo(RelationParticipator rp, boolean ignorePeaceful) {
return RelationUtil.getRelationTo(this, rp, ignorePeaceful);
}
public Relation getRelationToLocation() {
return Board.getInstance().getFactionAt(new FLocation(this)).getRelationTo(this);
}
@Override
public ChatColor getColorTo(RelationParticipator rp) {
return RelationUtil.getColorOfThatToMe(this, rp);
}
//----------------------------------------------//
// Health
//----------------------------------------------//
public void heal(int amnt) {
Player player = this.getPlayer();
if (player == null) {
return;
}
player.setHealth(player.getHealth() + amnt);
}
//----------------------------------------------//
// Power
//----------------------------------------------//
public double getPower() {
this.updatePower();
return this.power;
}
public void alterPower(double delta) {
this.power += delta;
if (this.power > this.getPowerMax()) {
this.power = this.getPowerMax();
} else if (this.power < this.getPowerMin()) {
this.power = this.getPowerMin();
}
}
public double getPowerMax() {
return Conf.powerPlayerMax + this.powerBoost;
}
public double getPowerMin() {
return Conf.powerPlayerMin + this.powerBoost;
}
public int getPowerRounded() {
return (int) Math.round(this.getPower());
}
public int getPowerMaxRounded() {
return (int) Math.round(this.getPowerMax());
}
public int getPowerMinRounded() {
return (int) Math.round(this.getPowerMin());
}
public void updatePower() {
if (this.isOffline()) {
losePowerFromBeingOffline();
if (!Conf.powerRegenOffline) {
return;
}
}
long now = System.currentTimeMillis();
long millisPassed = now - this.lastPowerUpdateTime;
this.lastPowerUpdateTime = now;
Player thisPlayer = this.getPlayer();
if (thisPlayer != null && thisPlayer.isDead()) {
return; // don't let dead players regain power until they respawn
}
int millisPerMinute = 60 * 1000;
this.alterPower(millisPassed * Conf.powerPerMinute / millisPerMinute);
}
public void losePowerFromBeingOffline() {
if (Conf.powerOfflineLossPerDay > 0.0 && this.power > Conf.powerOfflineLossLimit) {
long now = System.currentTimeMillis();
long millisPassed = now - this.lastPowerUpdateTime;
this.lastPowerUpdateTime = now;
double loss = millisPassed * Conf.powerOfflineLossPerDay / (24 * 60 * 60 * 1000);
if (this.power - loss < Conf.powerOfflineLossLimit) {
loss = this.power;
}
this.alterPower(-loss);
}
}
public void onDeath() {
this.updatePower();
this.alterPower(-Conf.powerPerDeath);
}
//----------------------------------------------//
// Territory
//----------------------------------------------//
public boolean isInOwnTerritory() {
return Board.getInstance().getFactionAt(new FLocation(this)) == this.getFaction();
}
public boolean isInOthersTerritory() {
Faction factionHere = Board.getInstance().getFactionAt(new FLocation(this));
return factionHere != null && factionHere.isNormal() && factionHere != this.getFaction();
}
public boolean isInAllyTerritory() {
return Board.getInstance().getFactionAt(new FLocation(this)).getRelationTo(this).isAlly();
}
public boolean isInNeutralTerritory() {
return Board.getInstance().getFactionAt(new FLocation(this)).getRelationTo(this).isNeutral();
}
public boolean isInEnemyTerritory() {
return Board.getInstance().getFactionAt(new FLocation(this)).getRelationTo(this).isEnemy();
}
public void sendFactionHereMessage() {
Faction toShow = Board.getInstance().getFactionAt(getLastStoodAt());
if (shouldShowScoreboard(toShow)) {
// Shows them the scoreboard instead of sending a message in chat. Will disappear after a few seconds.
FScoreboard.get(this).setTemporarySidebar(new FInfoSidebar(toShow));
} else {
String msg = P.p.txt.parse("<i>") + " ~ " + toShow.getTag(this);
if (toShow.getDescription().length() > 0) {
msg += " - " + toShow.getDescription();
}
this.sendMessage(msg);
}
}
/**
* Check if the scoreboard should be shown. Simple method to be used by above method.
* @param toShow Faction to be shown.
* @return true if should show, otherwise false.
*/
public boolean shouldShowScoreboard(Faction toShow) {
return !toShow.isWarZone() && !toShow.isNone() && !toShow.isSafeZone() && P.p.getConfig().contains("scoreboard.finfo") && P.p.getConfig().getBoolean("scoreboard.finfo-enabled", false) && P.p.cmdBase.cmdSB.showBoard(this);
}
// -------------------------------
// Actions
// -------------------------------
public void leave(boolean makePay) {
Faction myFaction = this.getFaction();
makePay = makePay && Econ.shouldBeUsed() && !this.isAdminBypassing();
if (myFaction == null) {
resetFactionData();
return;
}
boolean perm = myFaction.isPermanent();
if (!perm && this.getRole() == Role.ADMIN && myFaction.getFPlayers().size() > 1) {
msg("<b>You must give the admin role to someone else first.");
return;
}
if (!Conf.canLeaveWithNegativePower && this.getPower() < 0) {
msg("<b>You cannot leave until your power is positive.");
return;
}
// if economy is enabled and they're not on the bypass list, make sure they can pay
if (makePay && !Econ.hasAtLeast(this, Conf.econCostLeave, "to leave your faction.")) {
return;
}
FPlayerLeaveEvent leaveEvent = new FPlayerLeaveEvent(this, myFaction, FPlayerLeaveEvent.PlayerLeaveReason.LEAVE);
Bukkit.getServer().getPluginManager().callEvent(leaveEvent);
if (leaveEvent.isCancelled()) {
return;
}
// then make 'em pay (if applicable)
if (makePay && !Econ.modifyMoney(this, -Conf.econCostLeave, "to leave your faction.", "for leaving your faction.")) {
return;
}
// Am I the last one in the faction?
if (myFaction.getFPlayers().size() == 1) {
// Transfer all money
if (Econ.shouldBeUsed()) {
Econ.transferMoney(this, myFaction, this, Econ.getBalance(myFaction.getAccountId()));
}
}
if (myFaction.isNormal()) {
for (FPlayer fplayer : myFaction.getFPlayersWhereOnline(true)) {
fplayer.msg("%s<i> left %s<i>.", this.describeTo(fplayer, true), myFaction.describeTo(fplayer));
}
if (Conf.logFactionLeave) {
P.p.log(this.getName() + " left the faction: " + myFaction.getTag());
}
}
myFaction.removeAnnouncements(this);
this.resetFactionData();
if (myFaction.isNormal() && !perm && myFaction.getFPlayers().isEmpty()) {
// Remove this faction
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
fplayer.msg("<i>%s<i> was disbanded.", myFaction.describeTo(fplayer, true));
}
Factions.getInstance().removeFaction(myFaction.getId());
if (Conf.logFactionDisband) {
P.p.log("The faction " + myFaction.getTag() + " (" + myFaction.getId() + ") was disbanded due to the last player (" + this.getName() + ") leaving.");
}
}
}
public boolean canClaimForFaction(Faction forFaction) {
return !forFaction.isNone() && (this.isAdminBypassing() || (forFaction == this.getFaction() && this.getRole().isAtLeast(Role.MODERATOR)) || (forFaction.isSafeZone() && Permission.MANAGE_SAFE_ZONE.has(getPlayer())) || (forFaction.isWarZone() && Permission.MANAGE_WAR_ZONE.has(getPlayer())));
}
public boolean canClaimForFactionAtLocation(Faction forFaction, Location location, boolean notifyFailure) {
String error = null;
FLocation flocation = new FLocation(location);
Faction myFaction = getFaction();
Faction currentFaction = Board.getInstance().getFactionAt(flocation);
int ownedLand = forFaction.getLandRounded();
if (Conf.worldGuardChecking && Worldguard.checkForRegionsInChunk(location)) {
// Checks for WorldGuard regions in the chunk attempting to be claimed
error = P.p.txt.parse("<b>This land is protected");
} else if (Conf.worldsNoClaiming.contains(flocation.getWorldName())) {
error = P.p.txt.parse("<b>Sorry, this world has land claiming disabled.");
} else if (this.isAdminBypassing()) {
return true;
} else if (forFaction.isSafeZone() && Permission.MANAGE_SAFE_ZONE.has(getPlayer())) {
return true;
} else if (forFaction.isWarZone() && Permission.MANAGE_WAR_ZONE.has(getPlayer())) {
return true;
} else if (myFaction != forFaction) {
error = P.p.txt.parse("<b>You can't claim land for <h>%s<b>.", forFaction.describeTo(this));
} else if (forFaction == currentFaction) {
error = P.p.txt.parse("%s<i> already own this land.", forFaction.describeTo(this, true));
} else if (this.getRole().value < Role.MODERATOR.value) {
error = P.p.txt.parse("<b>You must be <h>%s<b> to claim land.", Role.MODERATOR.toString());
} else if (forFaction.getFPlayers().size() < Conf.claimsRequireMinFactionMembers) {
error = P.p.txt.parse("Factions must have at least <h>%s<b> members to claim land.", Conf.claimsRequireMinFactionMembers);
} else if (currentFaction.isSafeZone()) {
error = P.p.txt.parse("<b>You can not claim a Safe Zone.");
} else if (currentFaction.isWarZone()) {
error = P.p.txt.parse("<b>You can not claim a War Zone.");
} else if (ownedLand >= forFaction.getPowerRounded()) {
error = P.p.txt.parse("<b>You can't claim more land! You need more power!");
} else if (Conf.claimedLandsMax != 0 && ownedLand >= Conf.claimedLandsMax && forFaction.isNormal()) {
error = P.p.txt.parse("<b>Limit reached. You can't claim more land!");
} else if (currentFaction.getRelationTo(forFaction) == Relation.ALLY) {
error = P.p.txt.parse("<b>You can't claim the land of your allies.");
} else if (Conf.claimsMustBeConnected && !this.isAdminBypassing() && myFaction.getLandRoundedInWorld(flocation.getWorldName()) > 0 && !Board.getInstance().isConnectedLocation(flocation, myFaction) && (!Conf.claimsCanBeUnconnectedIfOwnedByOtherFaction || !currentFaction.isNormal())) {
if (Conf.claimsCanBeUnconnectedIfOwnedByOtherFaction) {
error = P.p.txt.parse("<b>You can only claim additional land which is connected to your first claim or controlled by another faction!");
} else {
error = P.p.txt.parse("<b>You can only claim additional land which is connected to your first claim!");
}
} else if (currentFaction.isNormal()) {
if (myFaction.isPeaceful()) {
error = P.p.txt.parse("%s<i> owns this land. Your faction is peaceful, so you cannot claim land from other factions.", currentFaction.getTag(this));
} else if (currentFaction.isPeaceful()) {
error = P.p.txt.parse("%s<i> owns this land, and is a peaceful faction. You cannot claim land from them.", currentFaction.getTag(this));
} else if (!currentFaction.hasLandInflation()) {
// TODO more messages WARN current faction most importantly
error = P.p.txt.parse("%s<i> owns this land and is strong enough to keep it.", currentFaction.getTag(this));
} else if (!Board.getInstance().isBorderLocation(flocation)) {
error = P.p.txt.parse("<b>You must start claiming land at the border of the territory.");
}
}
// TODO: Add more else if statements.
if (notifyFailure && error != null) {
msg(error);
}
return error == null;
}
public boolean attemptClaim(Faction forFaction, Location location, boolean notifyFailure) {
// notifyFailure is false if called by auto-claim; no need to notify on every failure for it
// return value is false on failure, true on success
FLocation flocation = new FLocation(location);
Faction currentFaction = Board.getInstance().getFactionAt(flocation);
int ownedLand = forFaction.getLandRounded();
if (!this.canClaimForFactionAtLocation(forFaction, location, notifyFailure)) {
return false;
}
// if economy is enabled and they're not on the bypass list, make sure they can pay
boolean mustPay = Econ.shouldBeUsed() && !this.isAdminBypassing() && !forFaction.isSafeZone() && !forFaction.isWarZone();
double cost = 0.0;
EconomyParticipator payee = null;
if (mustPay) {
cost = Econ.calculateClaimCost(ownedLand, currentFaction.isNormal());
if (Conf.econClaimUnconnectedFee != 0.0 && forFaction.getLandRoundedInWorld(flocation.getWorldName()) > 0 && !Board.getInstance().isConnectedLocation(flocation, forFaction)) {
cost += Conf.econClaimUnconnectedFee;
}
if (Conf.bankEnabled && Conf.bankFactionPaysLandCosts && this.hasFaction()) {
payee = this.getFaction();
} else {
payee = this;
}
if (!Econ.hasAtLeast(payee, cost, "to claim this land")) {
return false;
}
}
LandClaimEvent claimEvent = new LandClaimEvent(flocation, forFaction, this);
Bukkit.getServer().getPluginManager().callEvent(claimEvent);
if (claimEvent.isCancelled()) {
return false;
}
// then make 'em pay (if applicable)
if (mustPay && !Econ.modifyMoney(payee, -cost, "to claim this land", "for claiming this land")) {
return false;
}
// announce success
Set<FPlayer> informTheseFPlayers = new HashSet<FPlayer>();
informTheseFPlayers.add(this);
informTheseFPlayers.addAll(forFaction.getFPlayersWhereOnline(true));
for (FPlayer fp : informTheseFPlayers) {
fp.msg("<h>%s<i> claimed land for <h>%s<i> from <h>%s<i>.", this.describeTo(fp, true), forFaction.describeTo(fp), currentFaction.describeTo(fp));
}
Board.getInstance().setFactionAt(forFaction, flocation);
if (Conf.logLandClaims) {
P.p.log(this.getName() + " claimed land at (" + flocation.getCoordString() + ") for the faction: " + forFaction.getTag());
}
return true;
}
public boolean shouldBeSaved() {
if (!this.hasFaction() && (this.getPowerRounded() == this.getPowerMaxRounded() || this.getPowerRounded() == (int) Math.round(Conf.powerPlayerStarting))) {
return false;
}
return true;
}
public void msg(String str, Object... args) {
this.sendMessage(P.p.txt.parse(str, args));
}
public Player getPlayer() {
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
if (player.getUniqueId().toString().equals(this.getId())) {
return player;
}
}
return null;
}
public boolean isOnline() {
return this.getPlayer() != null;
}
// make sure target player should be able to detect that this player is online
public boolean isOnlineAndVisibleTo(Player player) {
Player target = this.getPlayer();
return target != null && player.canSee(target);
}
public boolean isOffline() {
return !isOnline();
}
// -------------------------------------------- //
// Message Sending Helpers
// -------------------------------------------- //
public void sendMessage(String msg) {
Player player = this.getPlayer();
if (player == null) {
return;
}
player.sendMessage(msg);
}
public void sendMessage(List<String> msgs) {
for (String msg : msgs) {
this.sendMessage(msg);
}
}
public String getNameAndTitle(FPlayer fplayer) {
return this.getColorTo(fplayer) + this.getNameAndTitle();
}
@Override
public String getChatTag(FPlayer fplayer) {
return this.hasFaction() ? this.getRelationTo(fplayer).getColor() + getChatTag() : "";
}
@Override
public String getId() {
return id;
}
public abstract void remove();
@Override
public void setId(String id) {
this.id = id;
}
}

View File

@ -0,0 +1,72 @@
package com.massivecraft.factions.zcore.persist;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.P;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListMap;
public abstract class MemoryFPlayers extends FPlayers {
public Map<String, FPlayer> fPlayers = new ConcurrentSkipListMap<String, FPlayer>(String.CASE_INSENSITIVE_ORDER);
public void clean() {
for (FPlayer fplayer : this.fPlayers.values()) {
if (!Factions.getInstance().isValidFactionId(fplayer.getFactionId())) {
P.p.log("Reset faction data (invalid faction:" + fplayer.getFactionId() + ") for player " + fplayer.getName());
fplayer.resetFactionData(false);
}
}
}
public Collection<FPlayer> getOnlinePlayers() {
Set<FPlayer> entities = new HashSet<FPlayer>();
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
entities.add(this.getByPlayer(player));
}
return entities;
}
@Override
public FPlayer getByPlayer(Player player) {
return getById(player.getUniqueId().toString());
}
@Override
public List<FPlayer> getAllFPlayers() {
return new ArrayList<FPlayer>(fPlayers.values());
}
@Override
public abstract void forceSave();
public abstract void load();
@Override
public FPlayer getByOfflinePlayer(OfflinePlayer player) {
return getById(player.getUniqueId().toString());
}
@Override
public FPlayer getById(String id) {
FPlayer player = fPlayers.get(id);
if (player == null) {
player = generateFPlayer(id);
}
return player;
}
public abstract FPlayer generateFPlayer(String id);
public abstract void convertFrom(MemoryFPlayers old);
}

View File

@ -0,0 +1,733 @@
package com.massivecraft.factions.zcore.persist;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.P;
import com.massivecraft.factions.iface.EconomyParticipator;
import com.massivecraft.factions.iface.RelationParticipator;
import com.massivecraft.factions.integration.Econ;
import com.massivecraft.factions.struct.Permission;
import com.massivecraft.factions.struct.Relation;
import com.massivecraft.factions.struct.Role;
import com.massivecraft.factions.util.LazyLocation;
import com.massivecraft.factions.util.MiscUtil;
import com.massivecraft.factions.util.RelationUtil;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public abstract class MemoryFaction implements Faction, EconomyParticipator {
protected String id = null;
protected boolean peacefulExplosionsEnabled;
protected boolean permanent;
protected String tag;
protected String description;
protected boolean open;
protected boolean peaceful;
protected Integer permanentPower;
protected LazyLocation home;
protected transient long lastPlayerLoggedOffTime;
protected double money;
protected double powerBoost;
protected Map<String, Relation> relationWish;
protected Map<FLocation, Set<String>> claimOwnership = new ConcurrentHashMap<FLocation, Set<String>>();
protected transient Set<FPlayer> fplayers = new HashSet<FPlayer>();
protected Set<String> invites;
protected HashMap<String, List<String>> announcements;
public HashMap<String, List<String>> getAnnouncements() {
return this.announcements;
}
public void addAnnouncement(FPlayer fPlayer, String msg) {
List<String> list = announcements.containsKey(fPlayer.getId()) ? announcements.get(fPlayer.getId()) : new ArrayList<String>();
list.add(msg);
announcements.put(fPlayer.getId(), list);
}
public void sendUnreadAnnouncements(FPlayer fPlayer) {
if (!announcements.containsKey(fPlayer.getId())) {
return;
}
fPlayer.sendMessage(ChatColor.LIGHT_PURPLE + "--Unread Faction Announcements--");
for (String s : announcements.get(fPlayer.getPlayer().getUniqueId().toString())) {
fPlayer.sendMessage(s);
}
fPlayer.sendMessage(ChatColor.LIGHT_PURPLE + "--Unread Faction Announcements--");
announcements.remove(fPlayer.getId());
}
public void removeAnnouncements(FPlayer fPlayer) {
if (announcements.containsKey(fPlayer.getId())) {
announcements.remove(fPlayer.getId());
}
}
public Set<String> getInvites() {
return invites;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void invite(FPlayer fplayer) {
this.invites.add(fplayer.getId());
}
public void deinvite(FPlayer fplayer) {
this.invites.remove(fplayer.getId());
}
public boolean isInvited(FPlayer fplayer) {
return this.invites.contains(fplayer.getId());
}
public boolean getOpen() {
return open;
}
public void setOpen(boolean isOpen) {
open = isOpen;
}
public boolean isPeaceful() {
return this.peaceful;
}
public void setPeaceful(boolean isPeaceful) {
this.peaceful = isPeaceful;
}
public void setPeacefulExplosionsEnabled(boolean val) {
peacefulExplosionsEnabled = val;
}
public boolean getPeacefulExplosionsEnabled() {
return this.peacefulExplosionsEnabled;
}
public boolean noExplosionsInTerritory() {
return this.peaceful && !peacefulExplosionsEnabled;
}
public boolean isPermanent() {
return permanent || !this.isNormal();
}
public void setPermanent(boolean isPermanent) {
permanent = isPermanent;
}
public String getTag() {
return this.tag;
}
public String getTag(String prefix) {
return prefix + this.tag;
}
public String getTag(Faction otherFaction) {
if (otherFaction == null) {
return getTag();
}
return this.getTag(this.getColorTo(otherFaction).toString());
}
public String getTag(FPlayer otherFplayer) {
if (otherFplayer == null) {
return getTag();
}
return this.getTag(this.getColorTo(otherFplayer).toString());
}
public void setTag(String str) {
if (Conf.factionTagForceUpperCase) {
str = str.toUpperCase();
}
this.tag = str;
}
public String getComparisonTag() {
return MiscUtil.getComparisonString(this.tag);
}
public String getDescription() {
return this.description;
}
public void setDescription(String value) {
this.description = value;
}
public void setHome(Location home) {
this.home = new LazyLocation(home);
}
public boolean hasHome() {
return this.getHome() != null;
}
public Location getHome() {
confirmValidHome();
return (this.home != null) ? this.home.getLocation() : null;
}
public void confirmValidHome() {
if (!Conf.homesMustBeInClaimedTerritory || this.home == null || (this.home.getLocation() != null && Board.getInstance().getFactionAt(new FLocation(this.home.getLocation())) == this)) {
return;
}
msg("<b>Your faction home has been un-set since it is no longer in your territory.");
this.home = null;
}
public String getAccountId() {
String aid = "faction-" + this.getId();
// We need to override the default money given to players.
if (!Econ.hasAccount(aid)) {
Econ.setBalance(aid, 0);
}
return aid;
}
public Integer getPermanentPower() {
return this.permanentPower;
}
public void setPermanentPower(Integer permanentPower) {
this.permanentPower = permanentPower;
}
public boolean hasPermanentPower() {
return this.permanentPower != null;
}
public double getPowerBoost() {
return this.powerBoost;
}
public void setPowerBoost(double powerBoost) {
this.powerBoost = powerBoost;
}
// -------------------------------------------- //
// Construct
// -------------------------------------------- //
public MemoryFaction() { }
public MemoryFaction(String id) {
this.id = id;
this.relationWish = new HashMap<String, Relation>();
this.invites = new HashSet<String>();
this.open = Conf.newFactionsDefaultOpen;
this.tag = "???";
this.description = "Default faction description :(";
this.lastPlayerLoggedOffTime = 0;
this.peaceful = false;
this.peacefulExplosionsEnabled = false;
this.permanent = false;
this.money = 0.0;
this.powerBoost = 0.0;
this.announcements = new HashMap<String, List<String>>();
}
public MemoryFaction(MemoryFaction old) {
id = old.id;
peacefulExplosionsEnabled = old.peacefulExplosionsEnabled;
permanent = old.permanent;
tag = old.tag;
description = old.description;
open = old.open;
peaceful = old.peaceful;
permanentPower = old.permanentPower;
home = old.home;
lastPlayerLoggedOffTime = old.lastPlayerLoggedOffTime;
money = old.money;
powerBoost = old.powerBoost;
relationWish = old.relationWish;
claimOwnership = old.claimOwnership;
fplayers = new HashSet<FPlayer>();
invites = old.invites;
announcements = old.announcements;
}
// -------------------------------------------- //
// Extra Getters And Setters
// -------------------------------------------- //
public boolean noPvPInTerritory() {
return isSafeZone() || (peaceful && Conf.peacefulTerritoryDisablePVP);
}
public boolean noMonstersInTerritory() {
return isSafeZone() || (peaceful && Conf.peacefulTerritoryDisableMonsters);
}
// -------------------------------
// Understand the types
// -------------------------------
public boolean isNormal() {
return !(this.isNone() || this.isSafeZone() || this.isWarZone());
}
public boolean isNone() {
return this.getId().equals("0");
}
public boolean isSafeZone() {
return this.getId().equals("-1");
}
public boolean isWarZone() {
return this.getId().equals("-2");
}
public boolean isPlayerFreeType() {
return this.isSafeZone() || this.isWarZone();
}
// -------------------------------
// Relation and relation colors
// -------------------------------
@Override
public String describeTo(RelationParticipator that, boolean ucfirst) {
return RelationUtil.describeThatToMe(this, that, ucfirst);
}
@Override
public String describeTo(RelationParticipator that) {
return RelationUtil.describeThatToMe(this, that);
}
@Override
public Relation getRelationTo(RelationParticipator rp) {
return RelationUtil.getRelationTo(this, rp);
}
@Override
public Relation getRelationTo(RelationParticipator rp, boolean ignorePeaceful) {
return RelationUtil.getRelationTo(this, rp, ignorePeaceful);
}
@Override
public ChatColor getColorTo(RelationParticipator rp) {
return RelationUtil.getColorOfThatToMe(this, rp);
}
public Relation getRelationWish(Faction otherFaction) {
if (this.relationWish.containsKey(otherFaction.getId())) {
return this.relationWish.get(otherFaction.getId());
}
return Relation.NEUTRAL;
}
public void setRelationWish(Faction otherFaction, Relation relation) {
if (this.relationWish.containsKey(otherFaction.getId()) && relation.equals(Relation.NEUTRAL)) {
this.relationWish.remove(otherFaction.getId());
} else {
this.relationWish.put(otherFaction.getId(), relation);
}
}
// ----------------------------------------------//
// Power
// ----------------------------------------------//
public double getPower() {
if (this.hasPermanentPower()) {
return this.getPermanentPower();
}
double ret = 0;
for (FPlayer fplayer : fplayers) {
ret += fplayer.getPower();
}
if (Conf.powerFactionMax > 0 && ret > Conf.powerFactionMax) {
ret = Conf.powerFactionMax;
}
return ret + this.powerBoost;
}
public double getPowerMax() {
if (this.hasPermanentPower()) {
return this.getPermanentPower();
}
double ret = 0;
for (FPlayer fplayer : fplayers) {
ret += fplayer.getPowerMax();
}
if (Conf.powerFactionMax > 0 && ret > Conf.powerFactionMax) {
ret = Conf.powerFactionMax;
}
return ret + this.powerBoost;
}
public int getPowerRounded() {
return (int) Math.round(this.getPower());
}
public int getPowerMaxRounded() {
return (int) Math.round(this.getPowerMax());
}
public int getLandRounded() {
return Board.getInstance().getFactionCoordCount(this);
}
public int getLandRoundedInWorld(String worldName) {
return Board.getInstance().getFactionCoordCountInWorld(this, worldName);
}
public boolean hasLandInflation() {
return this.getLandRounded() > this.getPowerRounded();
}
// -------------------------------
// FPlayers
// -------------------------------
// maintain the reference list of FPlayers in this faction
public void refreshFPlayers() {
fplayers.clear();
if (this.isPlayerFreeType()) {
return;
}
for (FPlayer fplayer : FPlayers.getInstance().getAllFPlayers()) {
if (fplayer.getFactionId().equalsIgnoreCase(id)) {
fplayers.add(fplayer);
}
}
}
public boolean addFPlayer(FPlayer fplayer) {
return !this.isPlayerFreeType() && fplayers.add(fplayer);
}
public boolean removeFPlayer(FPlayer fplayer) {
return !this.isPlayerFreeType() && fplayers.remove(fplayer);
}
public Set<FPlayer> getFPlayers() {
// return a shallow copy of the FPlayer list, to prevent tampering and
// concurrency issues
return new HashSet<FPlayer>(fplayers);
}
public Set<FPlayer> getFPlayersWhereOnline(boolean online) {
Set<FPlayer> ret = new HashSet<FPlayer>();
for (FPlayer fplayer : fplayers) {
if (fplayer.isOnline() == online) {
ret.add(fplayer);
}
}
return ret;
}
public FPlayer getFPlayerAdmin() {
if (!this.isNormal()) {
return null;
}
for (FPlayer fplayer : fplayers) {
if (fplayer.getRole() == Role.ADMIN) {
return fplayer;
}
}
return null;
}
public ArrayList<FPlayer> getFPlayersWhereRole(Role role) {
ArrayList<FPlayer> ret = new ArrayList<FPlayer>();
if (!this.isNormal()) {
return ret;
}
for (FPlayer fplayer : fplayers) {
if (fplayer.getRole() == role) {
ret.add(fplayer);
}
}
return ret;
}
public ArrayList<Player> getOnlinePlayers() {
ArrayList<Player> ret = new ArrayList<Player>();
if (this.isPlayerFreeType()) {
return ret;
}
for (Player player : P.p.getServer().getOnlinePlayers()) {
FPlayer fplayer = FPlayers.getInstance().getByPlayer(player);
if (fplayer.getFaction() == this) {
ret.add(player);
}
}
return ret;
}
// slightly faster check than getOnlinePlayers() if you just want to see if
// there are any players online
public boolean hasPlayersOnline() {
// only real factions can have players online, not safe zone / war zone
if (this.isPlayerFreeType()) {
return false;
}
for (Player player : P.p.getServer().getOnlinePlayers()) {
FPlayer fplayer = FPlayers.getInstance().getByPlayer(player);
if (fplayer != null && fplayer.getFaction() == this) {
return true;
}
}
// even if all players are technically logged off, maybe someone was on
// recently enough to not consider them officially offline yet
return Conf.considerFactionsReallyOfflineAfterXMinutes > 0 && System.currentTimeMillis() < lastPlayerLoggedOffTime + (Conf.considerFactionsReallyOfflineAfterXMinutes * 60000);
}
public void memberLoggedOff() {
if (this.isNormal()) {
lastPlayerLoggedOffTime = System.currentTimeMillis();
}
}
// used when current leader is about to be removed from the faction;
// promotes new leader, or disbands faction if no other members left
public void promoteNewLeader() {
if (!this.isNormal()) {
return;
}
if (this.isPermanent() && Conf.permanentFactionsDisableLeaderPromotion) {
return;
}
FPlayer oldLeader = this.getFPlayerAdmin();
// get list of moderators, or list of normal members if there are no moderators
ArrayList<FPlayer> replacements = this.getFPlayersWhereRole(Role.MODERATOR);
if (replacements == null || replacements.isEmpty()) {
replacements = this.getFPlayersWhereRole(Role.NORMAL);
}
if (replacements == null || replacements.isEmpty()) { // faction admin is the only member; one-man faction
if (this.isPermanent()) {
if (oldLeader != null) {
oldLeader.setRole(Role.NORMAL);
}
return;
}
// no members left and faction isn't permanent, so disband it
if (Conf.logFactionDisband) {
P.p.log("The faction " + this.getTag() + " (" + this.getId() + ") has been disbanded since it has no members left.");
}
for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) {
fplayer.msg("The faction %s<i> was disbanded.", this.getTag(fplayer));
}
Factions.getInstance().removeFaction(getId());
} else { // promote new faction admin
if (oldLeader != null) {
oldLeader.setRole(Role.NORMAL);
}
replacements.get(0).setRole(Role.ADMIN);
this.msg("<i>Faction admin <h>%s<i> has been removed. %s<i> has been promoted as the new faction admin.", oldLeader == null ? "" : oldLeader.getName(), replacements.get(0).getName());
P.p.log("Faction " + this.getTag() + " (" + this.getId() + ") admin was removed. Replacement admin: " + replacements.get(0).getName());
}
}
// ----------------------------------------------//
// Messages
// ----------------------------------------------//
public void msg(String message, Object... args) {
message = P.p.txt.parse(message, args);
for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) {
fplayer.sendMessage(message);
}
}
public void sendMessage(String message) {
for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) {
fplayer.sendMessage(message);
}
}
public void sendMessage(List<String> messages) {
for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) {
fplayer.sendMessage(messages);
}
}
// ----------------------------------------------//
// Ownership of specific claims
// ----------------------------------------------//
public Map<FLocation, Set<String>> getClaimOwnership() {
return claimOwnership;
}
public void clearAllClaimOwnership() {
claimOwnership.clear();
}
public void clearClaimOwnership(FLocation loc) {
claimOwnership.remove(loc);
}
public void clearClaimOwnership(FPlayer player) {
if (id == null || id.isEmpty()) {
return;
}
Set<String> ownerData;
for (Entry<FLocation, Set<String>> entry : claimOwnership.entrySet()) {
ownerData = entry.getValue();
if (ownerData == null) {
continue;
}
Iterator<String> iter = ownerData.iterator();
while (iter.hasNext()) {
if (iter.next().equals(player.getId())) {
iter.remove();
}
}
if (ownerData.isEmpty()) {
claimOwnership.remove(entry.getKey());
}
}
}
public int getCountOfClaimsWithOwners() {
return claimOwnership.isEmpty() ? 0 : claimOwnership.size();
}
public boolean doesLocationHaveOwnersSet(FLocation loc) {
if (claimOwnership.isEmpty() || !claimOwnership.containsKey(loc)) {
return false;
}
Set<String> ownerData = claimOwnership.get(loc);
return ownerData != null && !ownerData.isEmpty();
}
public boolean isPlayerInOwnerList(FPlayer player, FLocation loc) {
if (claimOwnership.isEmpty()) {
return false;
}
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
return false;
}
return ownerData.contains(player.getId());
}
public void setPlayerAsOwner(FPlayer player, FLocation loc) {
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
ownerData = new HashSet<String>();
}
ownerData.add(player.getId());
claimOwnership.put(loc, ownerData);
}
public void removePlayerAsOwner(FPlayer player, FLocation loc) {
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
return;
}
ownerData.remove(player.getId());
claimOwnership.put(loc, ownerData);
}
public Set<String> getOwnerList(FLocation loc) {
return claimOwnership.get(loc);
}
public String getOwnerListString(FLocation loc) {
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null || ownerData.isEmpty()) {
return "";
}
String ownerList = "";
Iterator<String> iter = ownerData.iterator();
while (iter.hasNext()) {
if (!ownerList.isEmpty()) {
ownerList += ", ";
}
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(UUID.fromString(iter.next()));
ownerList += offlinePlayer != null ? offlinePlayer.getName() : "null player";
}
return ownerList;
}
public boolean playerHasOwnershipRights(FPlayer fplayer, FLocation loc) {
// in own faction, with sufficient role or permission to bypass
// ownership?
if (fplayer.getFaction() == this && (fplayer.getRole().isAtLeast(Conf.ownedAreaModeratorsBypass ? Role.MODERATOR : Role.ADMIN) || Permission.OWNERSHIP_BYPASS.has(fplayer.getPlayer()))) {
return true;
}
// make sure claimOwnership is initialized
if (claimOwnership.isEmpty()) {
return true;
}
// need to check the ownership list, then
Set<String> ownerData = claimOwnership.get(loc);
// if no owner list, owner list is empty, or player is in owner list,
// they're allowed
return ownerData == null || ownerData.isEmpty() || ownerData.contains(fplayer.getId());
}
// ----------------------------------------------//
// Persistance and entity management
// ----------------------------------------------//
public void remove() {
if (Econ.shouldBeUsed()) {
Econ.setBalance(getAccountId(), 0);
}
// Clean the board
((MemoryBoard) Board.getInstance()).clean(id);
for (FPlayer fPlayer : fplayers) {
fPlayer.resetFactionData(false);
}
}
}

View File

@ -0,0 +1,171 @@
package com.massivecraft.factions.zcore.persist;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.ChatColor;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.util.MiscUtil;
import com.massivecraft.factions.zcore.util.TL;
public abstract class MemoryFactions extends Factions {
public Map<String, Faction> factions = new ConcurrentHashMap<String, Faction>();
public int nextId = 1;
public abstract void load(); {
// Make sure the default neutral faction exists
if (!factions.containsKey("0")) {
Faction faction = generateFactionObject("0");
factions.put("0", faction);
faction.setTag(TL.WILDERNESS.toString());
faction.setDescription(TL.WILDERNESS_DESCRIPTION.toString());
} else {
Faction faction = factions.get("0");
if (!faction.getTag().equalsIgnoreCase(TL.WILDERNESS.toString())) {
faction.setTag(TL.WILDERNESS.toString());
}
if (!faction.getDescription().equalsIgnoreCase(TL.WILDERNESS_DESCRIPTION.toString())) {
faction.setDescription(TL.WILDERNESS_DESCRIPTION.toString());
}
}
// Make sure the safe zone faction exists
if (!factions.containsKey("-1")) {
Faction faction = generateFactionObject("-1");
factions.put("-1", faction);
faction.setTag(TL.SAFEZONE.toString());
faction.setDescription(TL.SAFEZONE_DESCRIPTION.toString());
} else {
Faction faction = factions.get("-1");
if (!faction.getTag().equalsIgnoreCase(TL.SAFEZONE.toString())) {
faction.setTag(TL.SAFEZONE.toString());
}
if (!faction.getDescription().equalsIgnoreCase(TL.SAFEZONE_DESCRIPTION.toString())) {
faction.setDescription(TL.SAFEZONE_DESCRIPTION.toString());
}
// if SafeZone has old pre-1.6.0 name, rename it to remove troublesome " "
if (faction.getTag().contains(" ")) {
faction.setTag(TL.SAFEZONE.toString());
}
}
// Make sure the war zone faction exists
if (!factions.containsKey("-2")) {
Faction faction = generateFactionObject("-2");
factions.put("-2", faction);
faction.setTag(TL.WARZONE.toString());
faction.setDescription(TL.WARZONE_DESCRIPTION.toString());
} else {
Faction faction = factions.get("-2");
if (!faction.getTag().equalsIgnoreCase(TL.WARZONE.toString())) {
faction.setTag(TL.WARZONE.toString());
}
if (!faction.getDescription().equalsIgnoreCase(TL.WARZONE_DESCRIPTION.toString())) {
faction.setDescription(TL.WARZONE_DESCRIPTION.toString());
}
// if WarZone has old pre-1.6.0 name, rename it to remove troublesome " "
if (faction.getTag().contains(" ")) {
faction.setTag(TL.WARZONE.toString());
}
}
}
public Faction getFactionById(String id) {
return factions.get(id);
}
public abstract Faction generateFactionObject(String string);
public Faction getByTag(String str) {
String compStr = MiscUtil.getComparisonString(str);
for (Faction faction : factions.values()) {
if (faction.getComparisonTag().equals(compStr)) {
return faction;
}
}
return null;
}
public Faction getBestTagMatch(String start) {
int best = 0;
start = start.toLowerCase();
int minlength = start.length();
Faction bestMatch = null;
for (Faction faction : factions.values()) {
String candidate = faction.getTag();
candidate = ChatColor.stripColor(candidate);
if (candidate.length() < minlength) {
continue;
}
if (!candidate.toLowerCase().startsWith(start)) {
continue;
}
// The closer to zero the better
int lendiff = candidate.length() - minlength;
if (lendiff == 0) {
return faction;
}
if (lendiff < best || best == 0) {
best = lendiff;
bestMatch = faction;
}
}
return bestMatch;
}
public boolean isTagTaken(String str) {
return this.getByTag(str) != null;
}
public boolean isValidFactionId(String id) {
return factions.containsKey(id);
}
public Faction createFaction() {
Faction faction = generateFactionObject();
factions.put(faction.getId(), faction);
return faction;
}
public Set<String> getFactionTags() {
Set<String> tags = new HashSet<String>();
for (Faction faction : factions.values()) {
tags.add(faction.getTag());
}
return tags;
}
public abstract Faction generateFactionObject();
public void removeFaction(String id) {
factions.remove(id).remove();
}
@Override
public ArrayList<Faction> getAllFactions() {
return new ArrayList<Faction>(factions.values());
}
@Override
public Faction getNone() {
return factions.get("0");
}
@Override
public Faction getSafeZone() {
return factions.get("-1");
}
@Override
public Faction getWarZone() {
return factions.get("-2");
}
public abstract void convertFrom(MemoryFactions old);
}

View File

@ -1,50 +0,0 @@
package com.massivecraft.factions.zcore.persist;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.List;
public class PlayerEntity extends Entity {
public Player getPlayer() {
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
if (player.getUniqueId().toString().equals(this.getId())) {
return player;
}
}
return null;
}
public boolean isOnline() {
return this.getPlayer() != null;
}
// make sure target player should be able to detect that this player is online
public boolean isOnlineAndVisibleTo(Player player) {
Player target = this.getPlayer();
return target != null && player.canSee(target);
}
public boolean isOffline() {
return !isOnline();
}
// -------------------------------------------- //
// Message Sending Helpers
// -------------------------------------------- //
public void sendMessage(String msg) {
Player player = this.getPlayer();
if (player == null) {
return;
}
player.sendMessage(msg);
}
public void sendMessage(List<String> msgs) {
for (String msg : msgs) {
this.sendMessage(msg);
}
}
}

View File

@ -1,44 +0,0 @@
package com.massivecraft.factions.zcore.persist;
import com.google.gson.Gson;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.io.File;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* The PlayerEntityCollection is an EntityCollection with the extra features a player skin usually requires.
* <p/>
* This entity collection is not only creative. It even creates the instance for the player when the player logs in to
* the server.
* <p/>
* This way we can be sure that PlayerEntityCollection.get() will contain all entities in
* PlayerEntityCollection.getOnline()
*/
public abstract class PlayerEntityCollection<E extends Entity> extends EntityCollection<E> {
public PlayerEntityCollection(Class<E> entityClass, Collection<E> entities, Map<String, E> id2entity, File file, Gson gson) {
super(entityClass, entities, id2entity, file, gson, true);
}
public E get(OfflinePlayer player) {
return this.get(player.getUniqueId().toString());
}
public E get(Player player) {
return this.get(player.getUniqueId().toString());
}
public Set<E> getOnline() {
Set<E> entities = new HashSet<E>();
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
entities.add(this.get(player));
}
return entities;
}
}

View File

@ -1,5 +1,8 @@
package com.massivecraft.factions.zcore.persist;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.zcore.MPlugin;
public class SaveTask implements Runnable {
@ -18,7 +21,9 @@ public class SaveTask implements Runnable {
}
running = true;
p.preAutoSave();
EM.saveAllToDisc();
Factions.getInstance().forceSave();
FPlayers.getInstance().forceSave();
Board.getInstance().forceSave();
p.postAutoSave();
running = false;
}

View File

@ -0,0 +1,51 @@
package com.massivecraft.factions.zcore.persist.json;
import java.util.logging.Logger;
import org.bukkit.scheduler.BukkitRunnable;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.P;
import com.massivecraft.factions.zcore.persist.MemoryBoard;
import com.massivecraft.factions.zcore.persist.MemoryFPlayers;
import com.massivecraft.factions.zcore.persist.MemoryFactions;
public class FactionsJSON {
public static void convertTo() {
if (!(Factions.getInstance() instanceof MemoryFactions)) {
return;
}
if (!(FPlayers.getInstance() instanceof MemoryFPlayers)) {
return;
}
if (!(Board.getInstance() instanceof MemoryBoard)) {
return;
}
new BukkitRunnable() {
@Override
public void run() {
Logger logger = P.p.getLogger();
logger.info("Beginning Board conversion to JSON");
new JSONBoard().convertFrom((MemoryBoard) Board.getInstance());
logger.info("Board Converted");
logger.info("Beginning FPlayers conversion to JSON");
new JSONFPlayers().convertFrom((MemoryFPlayers) FPlayers.getInstance());
logger.info("FPlayers Converted");
logger.info("Beginning Factions conversion to JSON");
new JSONFactions().convertFrom((MemoryFactions) Factions.getInstance());
logger.info("Factions Converted");
logger.info("Refreshing object caches");
for (FPlayer fPlayer : FPlayers.getInstance().getAllFPlayers()) {
Faction faction = Factions.getInstance().getFactionById(fPlayer.getFactionId());
faction.addFPlayer(fPlayer);
}
logger.info("Conversion Complete");
}
}.runTaskAsynchronously(P.p);
}
}

View File

@ -0,0 +1,108 @@
package com.massivecraft.factions.zcore.persist.json;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.P;
import com.massivecraft.factions.zcore.persist.MemoryBoard;
import com.massivecraft.factions.zcore.util.DiscUtil;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.lang.reflect.Type;
import java.util.*;
import java.util.Map.Entry;
public class JSONBoard extends MemoryBoard {
private static transient File file = new File(P.p.getDataFolder(), "board.json");
// -------------------------------------------- //
// Persistance
// -------------------------------------------- //
public Map<String, Map<String, String>> dumpAsSaveFormat() {
Map<String, Map<String, String>> worldCoordIds = new HashMap<String, Map<String, String>>();
String worldName, coords;
String id;
for (Entry<FLocation, String> entry : flocationIds.entrySet()) {
worldName = entry.getKey().getWorldName();
coords = entry.getKey().getCoordString();
id = entry.getValue();
if (!worldCoordIds.containsKey(worldName)) {
worldCoordIds.put(worldName, new TreeMap<String, String>());
}
worldCoordIds.get(worldName).put(coords, id);
}
return worldCoordIds;
}
public void loadFromSaveFormat(Map<String, Map<String, String>> worldCoordIds) {
flocationIds.clear();
String worldName;
String[] coords;
int x, z;
String factionId;
for (Entry<String, Map<String, String>> entry : worldCoordIds.entrySet()) {
worldName = entry.getKey();
for (Entry<String, String> entry2 : entry.getValue().entrySet()) {
coords = entry2.getKey().trim().split("[,\\s]+");
x = Integer.parseInt(coords[0]);
z = Integer.parseInt(coords[1]);
factionId = entry2.getValue();
flocationIds.put(new FLocation(worldName, x, z), factionId);
}
}
}
public boolean forceSave() {
//Factions.log("Saving board to disk");
try {
DiscUtil.write(file, P.p.gson.toJson(dumpAsSaveFormat()));
} catch (Exception e) {
e.printStackTrace();
P.p.log("Failed to save the board to disk.");
return false;
}
return true;
}
public boolean load() {
P.p.log("Loading board from disk");
if (!file.exists()) {
P.p.log("No board to load from disk. Creating new file.");
forceSave();
return true;
}
try {
Type type = new TypeToken<Map<String, Map<String, String>>>() {
}.getType();
Map<String, Map<String, String>> worldCoordIds = P.p.gson.fromJson(DiscUtil.read(file), type);
loadFromSaveFormat(worldCoordIds);
P.p.log("Loaded " + flocationIds.size() + " board locations");
} catch (Exception e) {
e.printStackTrace();
P.p.log("Failed to load the board from disk.");
return false;
}
return true;
}
@Override
public void convertFrom(MemoryBoard old) {
this.flocationIds = old.flocationIds;
forceSave();
Board.instance = this;
}
}

View File

@ -0,0 +1,32 @@
package com.massivecraft.factions.zcore.persist.json;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.zcore.persist.MemoryFPlayer;
public class JSONFPlayer extends MemoryFPlayer {
private transient boolean remove = false;
public JSONFPlayer(MemoryFPlayer arg0) {
super(arg0);
}
public JSONFPlayer() {
remove = false;
}
public JSONFPlayer(String id) {
super(id);
}
@Override
public void remove() {
remove = true;
}
public boolean shouldBeSaved() {
if (!this.hasFaction() && (this.getPowerRounded() == this.getPowerMaxRounded() || this.getPowerRounded() == (int) Math.round(Conf.powerPlayerStarting))) {
return false;
}
return !remove;
}
}

View File

@ -0,0 +1,188 @@
package com.massivecraft.factions.zcore.persist.json;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.P;
import com.massivecraft.factions.zcore.persist.MemoryFPlayer;
import com.massivecraft.factions.zcore.persist.MemoryFPlayers;
import com.massivecraft.factions.zcore.util.DiscUtil;
import com.massivecraft.factions.zcore.util.UUIDFetcher;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Level;
public class JSONFPlayers extends MemoryFPlayers {
// Info on how to persist
private Gson gson;
public Gson getGson() {
return gson;
}
public void setGson(Gson gson) {
this.gson = gson;
}
private File file;
public JSONFPlayers() {
file = new File(P.p.getDataFolder(), "players.json");
gson = P.p.gson;
}
public void convertFrom(MemoryFPlayers old) {
this.fPlayers.putAll(Maps.transformValues(old.fPlayers, new Function<FPlayer, JSONFPlayer>() {
@Override
public JSONFPlayer apply(FPlayer arg0) {
return new JSONFPlayer((MemoryFPlayer) arg0);
}
}));
forceSave();
FPlayers.instance = this;
}
public void forceSave() {
Map<String, JSONFPlayer> entitiesThatShouldBeSaved = new HashMap<String, JSONFPlayer>();
for (FPlayer entity : this.fPlayers.values()) {
if (((MemoryFPlayer) entity).shouldBeSaved()) {
entitiesThatShouldBeSaved.put(entity.getId(), (JSONFPlayer) entity);
}
}
this.saveCore(this.file, entitiesThatShouldBeSaved);
}
private boolean saveCore(File target, Map<String, JSONFPlayer> data) {
return DiscUtil.writeCatch(target, this.gson.toJson(data));
}
public void load() {
Map<String, JSONFPlayer> fplayers = this.loadCore();
if (fplayers == null) {
return;
}
this.fPlayers.clear();
this.fPlayers.putAll(fplayers);
P.p.log("Loaded " + fPlayers.size() + " players");
}
private Map<String, JSONFPlayer> loadCore() {
if (!this.file.exists()) {
return new HashMap<String, JSONFPlayer>();
}
String content = DiscUtil.readCatch(this.file);
if (content == null) {
return null;
}
Map<String, JSONFPlayer> data = this.gson.fromJson(content, new TypeToken<Map<String, JSONFPlayer>>(){}.getType());
Set<String> list = new HashSet<String>();
Set<String> invalidList = new HashSet<String>();
for (Entry<String, JSONFPlayer> entry : data.entrySet()) {
String key = entry.getKey();
entry.getValue().setId(key);
if (doesKeyNeedMigration(key)) {
if (!isKeyInvalid(key)) {
list.add(key);
} else {
invalidList.add(key);
}
}
}
if (list.size() > 0) {
// We've got some converting to do!
Bukkit.getLogger().log(Level.INFO, "Factions is now updating players.json");
// First we'll make a backup, because god forbid anybody heed a
// warning
File file = new File(this.file.getParentFile(), "players.json.old");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
saveCore(file, (Map<String, JSONFPlayer>) data);
Bukkit.getLogger().log(Level.INFO, "Backed up your old data at " + file.getAbsolutePath());
// Start fetching those UUIDs
Bukkit.getLogger().log(Level.INFO, "Please wait while Factions converts " + list.size() + " old player names to UUID. This may take a while.");
UUIDFetcher fetcher = new UUIDFetcher(new ArrayList(list));
try {
Map<String, UUID> response = fetcher.call();
for (String s : list) {
// Are we missing any responses?
if (!response.containsKey(s)) {
// They don't have a UUID so they should just be removed
invalidList.add(s);
}
}
for (String value : response.keySet()) {
// For all the valid responses, let's replace their old
// named entry with a UUID key
String id = response.get(value).toString();
JSONFPlayer player = data.get(value);
if (player == null) {
// The player never existed here, and shouldn't persist
invalidList.add(value);
continue;
}
player.setId(id); // Update the object so it knows
data.remove(value); // Out with the old...
data.put(id, player); // And in with the new
}
} catch (Exception e) {
e.printStackTrace();
}
if (invalidList.size() > 0) {
for (String name : invalidList) {
// Remove all the invalid names we collected
data.remove(name);
}
Bukkit.getLogger().log(Level.INFO, "While converting we found names that either don't have a UUID or aren't players and removed them from storage.");
Bukkit.getLogger().log(Level.INFO, "The following names were detected as being invalid: " + StringUtils.join(invalidList, ", "));
}
saveCore(this.file, (Map<String, JSONFPlayer>) data); // Update the
// flatfile
Bukkit.getLogger().log(Level.INFO, "Done converting players.json to UUID.");
}
return (Map<String, JSONFPlayer>) data;
}
private boolean doesKeyNeedMigration(String key) {
if (!key.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")) {
// Not a valid UUID..
if (key.matches("[a-zA-Z0-9_]{2,16}")) {
// Valid playername, we'll mark this as one for conversion
// to UUID
return true;
}
}
return false;
}
private boolean isKeyInvalid(String key) {
return !key.matches("[a-zA-Z0-9_]{2,16}");
}
@Override
public FPlayer generateFPlayer(String id) {
FPlayer player = new JSONFPlayer(id);
this.fPlayers.put(player.getId(), player);
return player;
}
}

View File

@ -0,0 +1,16 @@
package com.massivecraft.factions.zcore.persist.json;
import com.massivecraft.factions.zcore.persist.MemoryFaction;
public class JSONFaction extends MemoryFaction {
public JSONFaction(MemoryFaction arg0) {
super(arg0);
}
public JSONFaction() {}
public JSONFaction(String id) {
super(id);
}
}

View File

@ -0,0 +1,258 @@
package com.massivecraft.factions.zcore.persist.json;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.P;
import com.massivecraft.factions.zcore.persist.MemoryFaction;
import com.massivecraft.factions.zcore.persist.MemoryFactions;
import com.massivecraft.factions.zcore.util.DiscUtil;
import com.massivecraft.factions.zcore.util.UUIDFetcher;
import org.bukkit.Bukkit;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Level;
public class JSONFactions extends MemoryFactions {
// Info on how to persist
private Gson gson;
public Gson getGson() {
return gson;
}
public void setGson(Gson gson) {
this.gson = gson;
}
private File file;
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
// -------------------------------------------- //
// CONSTRUCTORS
// -------------------------------------------- //
public JSONFactions() {
this.file = new File(P.p.getDataFolder(), "factions.json");
this.gson = P.p.gson;
this.nextId = 1;
}
public void forceSave() {
Map<String, JSONFaction> entitiesThatShouldBeSaved = new HashMap<String, JSONFaction>();
for (Faction entity : this.factions.values()) {
entitiesThatShouldBeSaved.put(entity.getId(), (JSONFaction) entity);
}
this.saveCore(this.file, entitiesThatShouldBeSaved);
}
private boolean saveCore(File target, Map<String, JSONFaction> entities) {
return DiscUtil.writeCatch(target, this.gson.toJson(entities));
}
public void load() {
Map<String, JSONFaction> factions = this.loadCore();
if (factions == null) {
return ;
}
this.factions.clear();
this.factions.putAll(factions);
P.p.log("Loaded " + factions.size() + " Factions");
}
private Map<String, JSONFaction> loadCore() {
if (!this.file.exists()) {
return new HashMap<String, JSONFaction>();
}
String content = DiscUtil.readCatch(this.file);
if (content == null) {
return null;
}
Map<String, JSONFaction> data = this.gson.fromJson(content, new TypeToken<Map<String, JSONFaction>>(){}.getType());
this.nextId = 1;
// Do we have any names that need updating in claims or invites?
int needsUpdate = 0;
for (Entry<String, JSONFaction> entry : data.entrySet()) {
String id = entry.getKey();
Faction f = entry.getValue();
f.setId(id);
this.updateNextIdForId(id);
needsUpdate += whichKeysNeedMigration(f.getInvites()).size();
for (Set<String> keys : f.getClaimOwnership().values()) {
needsUpdate += whichKeysNeedMigration(keys).size();
}
}
if (needsUpdate > 0) {
// We've got some converting to do!
Bukkit.getLogger().log(Level.INFO, "Factions is now updating factions.json");
// First we'll make a backup, because god forbid anybody heed a
// warning
File file = new File(this.file.getParentFile(), "factions.json.old");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
saveCore(file, (Map<String, JSONFaction>) data);
Bukkit.getLogger().log(Level.INFO, "Backed up your old data at " + file.getAbsolutePath());
Bukkit.getLogger().log(Level.INFO, "Please wait while Factions converts " + needsUpdate + " old player names to UUID. This may take a while.");
// Update claim ownership
for (String string : data.keySet()) {
Faction f = data.get(string);
Map<FLocation, Set<String>> claims = f.getClaimOwnership();
for (FLocation key : claims.keySet()) {
Set<String> set = claims.get(key);
Set<String> list = whichKeysNeedMigration(set);
if (list.size() > 0) {
UUIDFetcher fetcher = new UUIDFetcher(new ArrayList(list));
try {
Map<String, UUID> response = fetcher.call();
for (String value : response.keySet()) {
// Let's replace their old named entry with a
// UUID key
String id = response.get(value).toString();
set.remove(value.toLowerCase()); // Out with the
// old...
set.add(id); // And in with the new
}
} catch (Exception e) {
e.printStackTrace();
}
claims.put(key, set); // Update
}
}
}
// Update invites
for (String string : data.keySet()) {
Faction f = data.get(string);
Set<String> invites = f.getInvites();
Set<String> list = whichKeysNeedMigration(invites);
if (list.size() > 0) {
UUIDFetcher fetcher = new UUIDFetcher(new ArrayList(list));
try {
Map<String, UUID> response = fetcher.call();
for (String value : response.keySet()) {
// Let's replace their old named entry with a UUID
// key
String id = response.get(value).toString();
invites.remove(value.toLowerCase()); // Out with the
// old...
invites.add(id); // And in with the new
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
saveCore(this.file, (Map<String, JSONFaction>) data); // Update the flatfile
Bukkit.getLogger().log(Level.INFO, "Done converting factions.json to UUID.");
}
return data;
}
private Set<String> whichKeysNeedMigration(Set<String> keys) {
HashSet<String> list = new HashSet<String>();
for (String value : keys) {
if (!value.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")) {
// Not a valid UUID..
if (value.matches("[a-zA-Z0-9_]{2,16}")) {
// Valid playername, we'll mark this as one for conversion
// to UUID
list.add(value);
}
}
}
return list;
}
// -------------------------------------------- //
// ID MANAGEMENT
// -------------------------------------------- //
public String getNextId() {
while (!isIdFree(this.nextId)) {
this.nextId += 1;
}
return Integer.toString(this.nextId);
}
public boolean isIdFree(String id) {
return !this.factions.containsKey(id);
}
public boolean isIdFree(int id) {
return this.isIdFree(Integer.toString(id));
}
protected synchronized void updateNextIdForId(int id) {
if (this.nextId < id) {
this.nextId = id + 1;
}
}
protected void updateNextIdForId(String id) {
try {
int idAsInt = Integer.parseInt(id);
this.updateNextIdForId(idAsInt);
} catch (Exception ignored) {
}
}
@Override
public Faction generateFactionObject() {
String id = getNextId();
Faction faction = new JSONFaction(id);
updateNextIdForId(id);
return faction;
}
@Override
public Faction generateFactionObject(String id) {
Faction faction = new JSONFaction(id);
return faction;
}
@Override
public void convertFrom(MemoryFactions old) {
this.factions.putAll(Maps.transformValues(old.factions, new Function<Faction, JSONFaction>() {
@Override
public JSONFaction apply(Faction arg0) {
return new JSONFaction((MemoryFaction) arg0);
}
}));
this.nextId = old.nextId;
forceSave();
Factions.instance = this;
}
}