Factions/src/com/massivecraft/factions/Faction.java

720 lines
18 KiB
Java
Raw Normal View History

2011-07-18 22:06:02 +02:00
package com.massivecraft.factions;
2011-02-06 13:36:11 +01:00
import java.io.*;
2011-03-18 17:33:23 +01:00
import java.lang.reflect.Type;
2011-02-06 13:36:11 +01:00
import java.util.*;
2011-03-18 17:33:23 +01:00
import java.util.Map.Entry;
import java.util.logging.Level;
2011-02-06 13:36:11 +01:00
import org.bukkit.ChatColor;
2011-03-23 17:39:56 +01:00
import org.bukkit.Location;
2011-02-06 13:36:11 +01:00
import org.bukkit.entity.Player;
2011-07-18 22:06:02 +02:00
2011-07-27 22:56:45 +02:00
import com.google.gson.reflect.TypeToken;
2011-07-18 22:06:02 +02:00
import com.massivecraft.factions.struct.Relation;
import com.massivecraft.factions.struct.Role;
import com.massivecraft.factions.util.*;
2011-02-06 13:36:11 +01:00
public class Faction {
2011-03-22 17:20:21 +01:00
// -------------------------------------------- //
// Fields
// -------------------------------------------- //
private static transient Map<Integer, Faction> instances = new HashMap<Integer, Faction>();
private static transient File file = new File(Factions.instance.getDataFolder(), "factions.json");
private static transient int nextId;
private transient int id;
private Map<Integer, Relation> relationWish;
private Map<FLocation, Set<String>> claimOwnership = new HashMap<FLocation, Set<String>>();
2011-03-23 12:00:38 +01:00
private Set<String> invites; // Where string is a lowercase player name
2011-03-22 17:20:21 +01:00
private boolean open;
private String tag;
private String description;
2011-03-23 17:39:56 +01:00
private Location home;
private transient long lastPlayerLoggedOffTime;
2011-03-22 17:20:21 +01:00
// -------------------------------------------- //
// Construct
// -------------------------------------------- //
2011-02-06 13:36:11 +01:00
public Faction() {
this.relationWish = new HashMap<Integer, Relation>();
this.invites = new HashSet<String>();
this.open = Conf.newFactionsDefaultOpen;
this.tag = "???";
2011-02-06 13:36:11 +01:00
this.description = "Default faction description :(";
this.lastPlayerLoggedOffTime = 0;
2011-02-06 13:36:11 +01:00
}
2011-03-22 17:20:21 +01:00
// -------------------------------------------- //
// Getters And Setters
// -------------------------------------------- //
public int getId() {
return this.id;
}
public boolean getOpen() {
return open;
}
public void setOpen(boolean isOpen) {
open = isOpen;
}
public String getTag() {
return this.getTag("");
}
public String getTag(String prefix) {
return prefix+this.tag;
}
public String getTag(Faction otherFaction) {
if (otherFaction == null)
return getTag();
else
return this.getTag(otherFaction.getRelationColor(this).toString());
}
2011-03-23 12:00:38 +01:00
public String getTag(FPlayer otherFplayer) {
if (otherFplayer == null)
return getTag();
else
return this.getTag(otherFplayer.getRelationColor(this).toString());
}
public void setTag(String str) {
if (Conf.factionTagForceUpperCase) {
str = str.toUpperCase();
}
this.tag = str;
}
public String getDescription() {
return this.description;
}
public void setDescription(String value) {
this.description = value;
}
2011-03-23 17:39:56 +01:00
public void setHome(Location home) {
this.home = home;
}
public Location getHome() {
confirmValidHome();
2011-03-23 17:39:56 +01:00
return home;
}
public boolean hasHome() {
confirmValidHome();
2011-03-23 17:39:56 +01:00
return this.home != null;
}
public void confirmValidHome() {
if (!Conf.homesMustBeInClaimedTerritory || this.home == null || Board.getFactionAt(new FLocation(this.home)) == this) {
return;
}
sendMessage("Your faction home has been un-set since it is no longer in your territory.");
this.home = null;
}
2011-03-23 17:39:56 +01:00
// -------------------------------
// Understand the types
// -------------------------------
public boolean isNormal() {
return this.getId() > 0;
}
public boolean isNone() {
return this.getId() == 0;
}
public boolean isSafeZone() {
return this.getId() == -1;
}
public boolean isWarZone() {
return this.getId() == -2;
}
2011-03-22 17:20:21 +01:00
// -------------------------------
2011-03-23 12:00:38 +01:00
// Invites - uses lowercase name
2011-03-22 17:20:21 +01:00
// -------------------------------
public void invite(FPlayer fplayer) {
2011-03-23 12:00:38 +01:00
this.invites.add(fplayer.getName().toLowerCase());
2011-03-22 17:20:21 +01:00
}
public void deinvite(FPlayer fplayer) {
2011-03-23 12:00:38 +01:00
this.invites.remove(fplayer.getName().toLowerCase());
2011-03-22 17:20:21 +01:00
}
public boolean isInvited(FPlayer fplayer) {
2011-03-23 12:00:38 +01:00
return this.invites.contains(fplayer.getName().toLowerCase());
2011-03-22 17:20:21 +01:00
}
// -------------------------------
// Relation and relation colors TODO
// -------------------------------
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);
}
}
public Relation getRelation(Faction otherFaction) {
if (!otherFaction.isNormal() || !this.isNormal()) {
2011-03-22 17:20:21 +01:00
return Relation.NEUTRAL;
}
if (otherFaction.equals(this)) {
return Relation.MEMBER;
}
if(this.getRelationWish(otherFaction).value >= otherFaction.getRelationWish(this).value) {
return otherFaction.getRelationWish(this);
}
return this.getRelationWish(otherFaction);
}
2011-03-23 12:00:38 +01:00
public Relation getRelation(FPlayer fplayer) {
if (fplayer == null)
return Relation.NEUTRAL;
else
return getRelation(fplayer.getFaction());
2011-03-22 17:20:21 +01:00
}
2011-02-06 13:36:11 +01:00
//----------------------------------------------//
// Power
//----------------------------------------------//
public double getPower() {
double ret = 0;
2011-03-23 12:00:38 +01:00
for (FPlayer fplayer : this.getFPlayers()) {
ret += fplayer.getPower();
2011-02-06 13:36:11 +01:00
}
if (Conf.powerFactionMax > 0 && ret > Conf.powerFactionMax) {
ret = Conf.powerFactionMax;
}
2011-02-06 13:36:11 +01:00
return ret;
}
public double getPowerMax() {
double ret = 0;
2011-03-23 12:00:38 +01:00
for (FPlayer fplayer : this.getFPlayers()) {
ret += fplayer.getPowerMax();
2011-02-06 13:36:11 +01:00
}
if (Conf.powerFactionMax > 0 && ret > Conf.powerFactionMax) {
ret = Conf.powerFactionMax;
}
2011-02-06 13:36:11 +01:00
return ret;
}
public int getPowerRounded() {
return (int) Math.round(this.getPower());
}
public int getPowerMaxRounded() {
return (int) Math.round(this.getPowerMax());
}
public int getLandRounded() {
2011-03-22 17:20:21 +01:00
return Board.getFactionCoordCount(this);
2011-02-06 13:36:11 +01:00
}
public int getLandRoundedInWorld(String worldName) {
return Board.getFactionCoordCountInWorld(this, worldName);
}
2011-02-06 13:36:11 +01:00
public boolean hasLandInflation() {
return this.getLandRounded() > this.getPowerRounded();
2011-02-06 13:36:11 +01:00
}
// -------------------------------
2011-03-23 12:00:38 +01:00
// Fplayers
2011-02-06 13:36:11 +01:00
// -------------------------------
2011-03-19 13:00:03 +01:00
public ArrayList<FPlayer> getFPlayers() {
2011-03-18 17:33:23 +01:00
ArrayList<FPlayer> ret = new ArrayList<FPlayer>();
if (id < 0)
return ret;
2011-03-23 12:00:38 +01:00
for (FPlayer fplayer : FPlayer.getAll()) {
if (fplayer.getFaction() == this) {
ret.add(fplayer);
2011-02-06 13:36:11 +01:00
}
}
2011-02-06 13:36:11 +01:00
return ret;
}
2011-03-19 13:00:03 +01:00
public ArrayList<FPlayer> getFPlayersWhereOnline(boolean online) {
2011-03-18 17:33:23 +01:00
ArrayList<FPlayer> ret = new ArrayList<FPlayer>();
if (id < 0)
return ret;
2011-03-22 17:20:21 +01:00
for (FPlayer fplayer : FPlayer.getAll()) {
if (fplayer.getFaction() == this && fplayer.isOnline() == online) {
ret.add(fplayer);
2011-02-06 13:36:11 +01:00
}
}
2011-02-06 13:36:11 +01:00
return ret;
}
public FPlayer getFPlayerAdmin() {
if (id <= 0)
return null;
for (FPlayer fplayer : FPlayer.getAll()) {
if (fplayer.getFaction() == this && fplayer.getRole() == Role.ADMIN) {
return fplayer;
}
}
return null;
}
2011-03-19 13:00:03 +01:00
public ArrayList<FPlayer> getFPlayersWhereRole(Role role) {
2011-03-18 17:33:23 +01:00
ArrayList<FPlayer> ret = new ArrayList<FPlayer>();
if (id <= 0)
return ret;
2011-02-06 13:36:11 +01:00
2011-03-22 17:20:21 +01:00
for (FPlayer fplayer : FPlayer.getAll()) {
if (fplayer.getFaction() == this && fplayer.getRole() == role) {
ret.add(fplayer);
2011-02-06 13:36:11 +01:00
}
}
return ret;
}
public ArrayList<Player> getOnlinePlayers() {
ArrayList<Player> ret = new ArrayList<Player>();
if (id < 0)
return ret;
2011-03-18 17:33:23 +01:00
for (Player player: Factions.instance.getServer().getOnlinePlayers()) {
2011-03-23 12:00:38 +01:00
FPlayer fplayer = FPlayer.get(player);
if (fplayer.getFaction() == this) {
2011-02-06 13:36:11 +01:00
ret.add(player);
}
}
2011-02-06 13:36:11 +01:00
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 (id < 0)
return false;
for (Player player: Factions.instance.getServer().getOnlinePlayers()) {
FPlayer fplayer = FPlayer.get(player);
if (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
if (Conf.considerFactionsReallyOfflineAfterXMinutes > 0 &&
System.currentTimeMillis() < lastPlayerLoggedOffTime + (Conf.considerFactionsReallyOfflineAfterXMinutes * 60000)) {
return true;
}
return false;
}
public void memberLoggedOff() {
if (this.isNormal()) {
lastPlayerLoggedOffTime = System.currentTimeMillis();
}
}
2011-02-06 13:36:11 +01:00
//----------------------------------------------//
// Faction tag
2011-02-06 13:36:11 +01:00
//----------------------------------------------//
public String getComparisonTag() {
return TextUtil.getComparisonString(this.tag);
2011-02-06 13:36:11 +01:00
}
public static ArrayList<String> validateTag(String str) {
2011-02-06 13:36:11 +01:00
ArrayList<String> errors = new ArrayList<String>();
if(TextUtil.getComparisonString(str).length() < Conf.factionTagLengthMin) {
errors.add(Conf.colorSystem+"The faction tag can't be shorter than "+Conf.factionTagLengthMin+ " chars.");
}
if(str.length() > Conf.factionTagLengthMax) {
errors.add(Conf.colorSystem+"The faction tag can't be longer than "+Conf.factionTagLengthMax+ " chars.");
2011-02-06 13:36:11 +01:00
}
for (char c : str.toCharArray()) {
if ( ! TextUtil.substanceChars.contains(String.valueOf(c))) {
errors.add(Conf.colorSystem+"Faction tag must be alphanumeric. \""+c+"\" is not allowed.");
}
2011-02-06 13:36:11 +01:00
}
return errors;
}
public static Faction findByTag(String str) {
String compStr = TextUtil.getComparisonString(str);
2011-02-06 13:36:11 +01:00
for (Faction faction : Faction.getAll()) {
if (faction.getComparisonTag().equals(compStr)) {
2011-02-06 13:36:11 +01:00
return faction;
}
}
return null;
}
public static boolean isTagTaken(String str) {
return Faction.findByTag(str) != null;
2011-02-06 13:36:11 +01:00
}
//----------------------------------------------//
2011-03-22 17:20:21 +01:00
// Messages
2011-02-06 13:36:11 +01:00
//----------------------------------------------//
public void sendMessage(String message) {
2011-03-22 17:20:21 +01:00
for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) {
fplayer.sendMessage(message);
2011-02-06 13:36:11 +01:00
}
}
2011-03-22 17:20:21 +01:00
public void sendMessage(List<String> messages) {
for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) {
fplayer.sendMessage(messages);
2011-02-06 13:36:11 +01:00
}
}
2011-03-22 17:20:21 +01:00
//----------------------------------------------//
// Mudd TODO
//----------------------------------------------//
2011-02-06 13:36:11 +01:00
public ChatColor getRelationColor(Faction otherFaction) {
return this.getRelation(otherFaction).getColor();
}
2011-03-23 12:00:38 +01:00
public ChatColor getRelationColor(FPlayer fplayer) {
return this.getRelation(fplayer).getColor();
2011-02-06 13:36:11 +01:00
}
2011-07-31 03:17:00 +02:00
//----------------------------------------------//
// Ownership of specific claims
//----------------------------------------------//
public void clearAllClaimOwnership() {
claimOwnership.clear();
}
public void clearClaimOwnership(FLocation loc) {
claimOwnership.remove(loc);
}
public void clearClaimOwnership(String playerName) {
if (playerName == null || playerName.isEmpty()) {
return;
}
Set<String> ownerData;
String player = playerName.toLowerCase();
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)) {
iter.remove();
}
}
if (ownerData.isEmpty()) {
claimOwnership.remove(entry.getKey());
}
}
}
public int getCountOfClaimsWithOwners() {
return claimOwnership.isEmpty() ? 0 : claimOwnership.size();
2011-07-31 03:17:00 +02:00
}
public boolean doesLocationHaveOwnersSet(FLocation loc) {
if (claimOwnership.isEmpty() || !claimOwnership.containsKey(loc)) {
2011-07-31 03:17:00 +02:00
return false;
}
Set<String> ownerData = claimOwnership.get(loc);
return ownerData != null && !ownerData.isEmpty();
}
public boolean isPlayerInOwnerList(String playerName, FLocation loc) {
if (claimOwnership.isEmpty()) {
2011-07-31 03:17:00 +02:00
return false;
}
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
return false;
}
if (ownerData.contains(playerName.toLowerCase())) {
return true;
}
return false;
}
public void setPlayerAsOwner(String playerName, FLocation loc) {
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
ownerData = new HashSet<String>();
}
ownerData.add(playerName.toLowerCase());
claimOwnership.put(loc, ownerData);
}
public void removePlayerAsOwner(String playerName, FLocation loc) {
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
return;
}
ownerData.remove(playerName.toLowerCase());
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 += ", ";
}
ownerList += iter.next();
}
return ownerList;
}
public boolean playerHasOwnershipRights(FPlayer fplayer, FLocation loc) {
// different faction?
if (fplayer.getFactionId() != id) {
return false;
}
// sufficient role to bypass ownership?
if (fplayer.getRole() == (Conf.ownedAreaModeratorsBypass ? Role.MODERATOR : Role.ADMIN)) {
return true;
}
// make sure claimOwnership is initialized
if (claimOwnership.isEmpty()) {
2011-07-31 03:17:00 +02:00
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
if (ownerData == null || ownerData.isEmpty() || ownerData.contains(fplayer.getName().toLowerCase())) {
return true;
}
return false;
}
2011-03-22 17:20:21 +01:00
2011-02-06 13:36:11 +01:00
//----------------------------------------------//
// Persistance and entity management
//----------------------------------------------//
2011-03-18 17:33:23 +01:00
public static boolean save() {
2011-03-22 22:31:04 +01:00
//Factions.log("Saving factions to disk");
2011-03-18 17:33:23 +01:00
try {
2011-07-27 22:56:45 +02:00
DiscUtil.write(file, Factions.instance.gson.toJson(instances));
2011-03-18 17:33:23 +01:00
} catch (IOException e) {
e.printStackTrace();
Factions.log("Failed to save the factions to disk due to I/O exception.");
return false;
} catch (Exception e) {
2011-03-18 17:33:23 +01:00
e.printStackTrace();
Factions.log("Failed to save the factions to disk.");
2011-03-18 17:33:23 +01:00
return false;
}
return true;
}
public static boolean load() {
2011-03-23 12:00:38 +01:00
Factions.log("Loading factions from disk");
2011-03-18 17:33:23 +01:00
if ( ! file.exists()) {
if ( ! loadOld())
Factions.log("No factions to load from disk. Creating new file.");
2011-03-18 17:33:23 +01:00
save();
}
try {
Type type = new TypeToken<Map<Integer, Faction>>(){}.getType();
2011-07-27 22:56:45 +02:00
Map<Integer, Faction> instancesFromFile = Factions.instance.gson.fromJson(DiscUtil.read(file), type);
2011-03-23 12:00:38 +01:00
instances.clear();
instances.putAll(instancesFromFile);
} catch (Exception e) {
2011-03-18 17:33:23 +01:00
e.printStackTrace();
Factions.log("Failed to load the factions from disk.");
2011-03-18 17:33:23 +01:00
return false;
}
fillIds();
// Make sure the default neutral faction exists
if ( ! instances.containsKey(0)) {
Faction faction = new Faction();
faction.tag = ChatColor.DARK_GREEN+"Wilderness";
faction.description = "";
2011-03-18 17:33:23 +01:00
faction.id = 0;
instances.put(faction.id, faction);
}
// Make sure the safe zone faction exists
2011-03-23 17:39:56 +01:00
if ( ! instances.containsKey(-1)) {
Faction faction = new Faction();
faction.tag = ChatColor.GOLD+"Safe Zone";
faction.description = "Free from PVP and monsters";
faction.id = -1;
instances.put(faction.id, faction);
}
// Make sure the war zone faction exists
if ( ! instances.containsKey(-2)) {
Faction faction = new Faction();
faction.tag = ChatColor.DARK_RED+"War Zone";
faction.description = "Not the safest place to be";
faction.id = -2;
instances.put(faction.id, faction);
}
2011-03-18 17:33:23 +01:00
return true;
}
public static void fillIds() {
nextId = 1;
for(Entry<Integer, Faction> entry : instances.entrySet()) {
entry.getValue().id = entry.getKey();
if (nextId < entry.getKey()) {
nextId = entry.getKey();
}
}
nextId += 1; // make it the next id and not the current highest.
}
2011-03-18 17:33:23 +01:00
public static Faction get(Integer factionId) {
if ( ! instances.containsKey(factionId)) {
2011-03-22 19:25:11 +01:00
Factions.log(Level.WARNING, "Non existing factionId "+factionId+" requested! Issuing cleaning!");
2011-03-22 17:20:21 +01:00
Board.clean();
2011-03-22 19:25:11 +01:00
FPlayer.clean();
2011-03-18 17:33:23 +01:00
}
return instances.get(factionId);
}
2011-03-23 17:39:56 +01:00
public static Faction getNone() {
return instances.get(0);
}
public static Faction getSafeZone() {
return instances.get(-1);
}
public static Faction getWarZone() {
return instances.get(-2);
}
2011-03-18 17:33:23 +01:00
public static boolean exists(Integer factionId) {
return instances.containsKey(factionId);
}
public static Collection<Faction> getAll() {
return instances.values();
}
//TODO ta parametrar här. All info som behövs ska matas in här och så sparar vi i denna method.
public static Faction create() {
Faction faction = new Faction();
faction.id = nextId;
nextId += 1;
instances.put(faction.id, faction);
Factions.log("created new faction "+faction.id);
//faction.save();
return faction;
}
2011-03-22 19:25:11 +01:00
public static void delete(Integer id) {
2011-03-18 17:33:23 +01:00
// Remove the faction
instances.remove(id);
2011-03-22 19:25:11 +01:00
// Clean the board
Board.clean();
// Clean the fplayers
FPlayer.clean();
2011-03-18 17:33:23 +01:00
}
private static boolean loadOld() {
File folderFaction = new File(Factions.instance.getDataFolder(), "faction");
if ( ! folderFaction.isDirectory())
return false;
Factions.log("Factions file doesn't exist, attempting to load old pre-1.1 data.");
String ext = ".json";
class jsonFileFilter implements FileFilter {
@Override
public boolean accept(File file) {
return (file.getName().toLowerCase().endsWith(".json") && file.isFile());
}
}
File[] jsonFiles = folderFaction.listFiles(new jsonFileFilter());
for (File jsonFile : jsonFiles) {
// Extract the name from the filename. The name is filename minus ".json"
String name = jsonFile.getName();
name = name.substring(0, name.length() - ext.length());
int id = Integer.parseInt(name);
try {
2011-07-27 22:56:45 +02:00
Faction faction = Factions.instance.gson.fromJson(DiscUtil.read(jsonFile), Faction.class);
faction.id = id;
instances.put(faction.id, faction);
Factions.log("loaded pre-1.1 faction "+id);
} catch (Exception e) {
e.printStackTrace();
Factions.log(Level.WARNING, "Failed to load faction "+id);
}
}
return true;
}
2011-02-06 13:36:11 +01:00
}