Remove Maven
This commit is contained in:
421
src/com/massivecraft/factions/entity/Board.java
Normal file
421
src/com/massivecraft/factions/entity/Board.java
Normal file
@ -0,0 +1,421 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import com.massivecraft.factions.Const;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.RelationParticipator;
|
||||
import com.massivecraft.factions.TerritoryAccess;
|
||||
import com.massivecraft.factions.util.AsciiCompass;
|
||||
import com.massivecraft.massivecore.collections.MassiveMap;
|
||||
import com.massivecraft.massivecore.collections.MassiveSet;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.store.Entity;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
import com.massivecraft.massivecore.xlib.gson.reflect.TypeToken;
|
||||
|
||||
public class Board extends Entity<Board> implements BoardInterface
|
||||
{
|
||||
public static final transient Type MAP_TYPE = new TypeToken<Map<PS, TerritoryAccess>>(){}.getType();
|
||||
|
||||
// -------------------------------------------- //
|
||||
// META
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static Board get(Object oid)
|
||||
{
|
||||
return BoardColl.get().get(oid);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE: ENTITY
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public Board load(Board that)
|
||||
{
|
||||
this.map = that.map;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefault()
|
||||
{
|
||||
if (this.map == null) return true;
|
||||
if (this.map.isEmpty()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELDS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// TODO: Make TerritoryAccess immutable.
|
||||
|
||||
private ConcurrentSkipListMap<PS, TerritoryAccess> map;
|
||||
public Map<PS, TerritoryAccess> getMap() { return Collections.unmodifiableMap(this.map); }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
public Board()
|
||||
{
|
||||
this.map = new ConcurrentSkipListMap<PS, TerritoryAccess>();
|
||||
}
|
||||
|
||||
public Board(Map<PS, TerritoryAccess> map)
|
||||
{
|
||||
this.map = new ConcurrentSkipListMap<PS, TerritoryAccess>(map);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE: BOARD
|
||||
// -------------------------------------------- //
|
||||
|
||||
// GET
|
||||
|
||||
@Override
|
||||
public TerritoryAccess getTerritoryAccessAt(PS ps)
|
||||
{
|
||||
if (ps == null) return null;
|
||||
ps = ps.getChunkCoords(true);
|
||||
TerritoryAccess ret = this.map.get(ps);
|
||||
if (ret == null) ret = TerritoryAccess.valueOf(Factions.ID_NONE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Faction getFactionAt(PS ps)
|
||||
{
|
||||
if (ps == null) return null;
|
||||
TerritoryAccess ta = this.getTerritoryAccessAt(ps);
|
||||
return ta.getHostFaction();
|
||||
}
|
||||
|
||||
// SET
|
||||
|
||||
@Override
|
||||
public void setTerritoryAccessAt(PS ps, TerritoryAccess territoryAccess)
|
||||
{
|
||||
ps = ps.getChunkCoords(true);
|
||||
|
||||
if (territoryAccess == null || (territoryAccess.getHostFactionId().equals(Factions.ID_NONE) && territoryAccess.isDefault()))
|
||||
{
|
||||
this.map.remove(ps);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.map.put(ps, territoryAccess);
|
||||
}
|
||||
|
||||
this.changed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFactionAt(PS ps, Faction faction)
|
||||
{
|
||||
TerritoryAccess territoryAccess = null;
|
||||
if (faction != null)
|
||||
{
|
||||
territoryAccess = TerritoryAccess.valueOf(faction.getId());
|
||||
}
|
||||
this.setTerritoryAccessAt(ps, territoryAccess);
|
||||
}
|
||||
|
||||
// REMOVE
|
||||
|
||||
@Override
|
||||
public void removeAt(PS ps)
|
||||
{
|
||||
this.setTerritoryAccessAt(ps, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAll(Faction faction)
|
||||
{
|
||||
String factionId = faction.getId();
|
||||
|
||||
for (Entry<PS, TerritoryAccess> entry : this.map.entrySet())
|
||||
{
|
||||
TerritoryAccess territoryAccess = entry.getValue();
|
||||
if ( ! territoryAccess.getHostFactionId().equals(factionId)) continue;
|
||||
|
||||
PS ps = entry.getKey();
|
||||
this.removeAt(ps);
|
||||
}
|
||||
}
|
||||
|
||||
// Removes orphaned foreign keys
|
||||
@Override
|
||||
public void clean()
|
||||
{
|
||||
for (Entry<PS, TerritoryAccess> entry : this.map.entrySet())
|
||||
{
|
||||
TerritoryAccess territoryAccess = entry.getValue();
|
||||
String factionId = territoryAccess.getHostFactionId();
|
||||
|
||||
if (FactionColl.get().containsId(factionId)) continue;
|
||||
|
||||
PS ps = entry.getKey();
|
||||
this.removeAt(ps);
|
||||
|
||||
Factions.get().log("Board cleaner removed "+factionId+" from "+ps);
|
||||
}
|
||||
}
|
||||
|
||||
// CHUNKS
|
||||
|
||||
@Override
|
||||
public Set<PS> getChunks(Faction faction)
|
||||
{
|
||||
return this.getChunks(faction.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PS> getChunks(String factionId)
|
||||
{
|
||||
Set<PS> ret = new HashSet<PS>();
|
||||
for (Entry<PS, TerritoryAccess> entry : this.map.entrySet())
|
||||
{
|
||||
TerritoryAccess ta = entry.getValue();
|
||||
if (!ta.getHostFactionId().equals(factionId)) continue;
|
||||
|
||||
PS ps = entry.getKey();
|
||||
ps = ps.withWorld(this.getId());
|
||||
ret.add(ps);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Faction, Set<PS>> getFactionToChunks()
|
||||
{
|
||||
Map<Faction, Set<PS>> ret = new MassiveMap<Faction, Set<PS>>();
|
||||
|
||||
for (Entry<PS, TerritoryAccess> entry : this.map.entrySet())
|
||||
{
|
||||
// Get Faction
|
||||
TerritoryAccess ta = entry.getValue();
|
||||
Faction faction = ta.getHostFaction();
|
||||
if (faction == null) continue;
|
||||
|
||||
// Get Chunks
|
||||
Set<PS> chunks = ret.get(faction);
|
||||
if (chunks == null)
|
||||
{
|
||||
chunks = new MassiveSet<PS>();
|
||||
ret.put(faction, chunks);
|
||||
}
|
||||
|
||||
// Add Chunk
|
||||
PS chunk = entry.getKey();
|
||||
chunk = chunk.withWorld(this.getId());
|
||||
chunks.add(chunk);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// COUNT
|
||||
|
||||
@Override
|
||||
public int getCount(Faction faction)
|
||||
{
|
||||
return this.getCount(faction.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount(String factionId)
|
||||
{
|
||||
int ret = 0;
|
||||
for (TerritoryAccess ta : this.map.values())
|
||||
{
|
||||
if (!ta.getHostFactionId().equals(factionId)) continue;
|
||||
ret += 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Faction, Integer> getFactionToCount()
|
||||
{
|
||||
Map<Faction, Integer> ret = new MassiveMap<Faction, Integer>();
|
||||
|
||||
for (Entry<PS, TerritoryAccess> entry : this.map.entrySet())
|
||||
{
|
||||
// Get Faction
|
||||
TerritoryAccess ta = entry.getValue();
|
||||
Faction faction = ta.getHostFaction();
|
||||
if (faction == null) continue;
|
||||
|
||||
// Get Count
|
||||
Integer count = ret.get(faction);
|
||||
if (count == null)
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
|
||||
// Add Chunk
|
||||
ret.put(faction, count + 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// NEARBY DETECTION
|
||||
|
||||
// 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?
|
||||
@Override
|
||||
public boolean isBorderPs(PS ps)
|
||||
{
|
||||
ps = ps.getChunk(true);
|
||||
|
||||
PS nearby = null;
|
||||
Faction faction = this.getFactionAt(ps);
|
||||
|
||||
nearby = ps.withChunkX(ps.getChunkX() +1);
|
||||
if (faction != this.getFactionAt(nearby)) return true;
|
||||
|
||||
nearby = ps.withChunkX(ps.getChunkX() -1);
|
||||
if (faction != this.getFactionAt(nearby)) return true;
|
||||
|
||||
nearby = ps.withChunkZ(ps.getChunkZ() +1);
|
||||
if (faction != this.getFactionAt(nearby)) return true;
|
||||
|
||||
nearby = ps.withChunkZ(ps.getChunkZ() -1);
|
||||
if (faction != this.getFactionAt(nearby)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnyBorderPs(Set<PS> pss)
|
||||
{
|
||||
for (PS ps : pss)
|
||||
{
|
||||
if (this.isBorderPs(ps)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is this coord connected to any coord claimed by the specified faction?
|
||||
@Override
|
||||
public boolean isConnectedPs(PS ps, Faction faction)
|
||||
{
|
||||
ps = ps.getChunk(true);
|
||||
|
||||
PS nearby = null;
|
||||
|
||||
nearby = ps.withChunkX(ps.getChunkX() +1);
|
||||
if (faction == this.getFactionAt(nearby)) return true;
|
||||
|
||||
nearby = ps.withChunkX(ps.getChunkX() -1);
|
||||
if (faction == this.getFactionAt(nearby)) return true;
|
||||
|
||||
nearby = ps.withChunkZ(ps.getChunkZ() +1);
|
||||
if (faction == this.getFactionAt(nearby)) return true;
|
||||
|
||||
nearby = ps.withChunkZ(ps.getChunkZ() -1);
|
||||
if (faction == this.getFactionAt(nearby)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnyConnectedPs(Set<PS> pss, Faction faction)
|
||||
{
|
||||
for (PS ps : pss)
|
||||
{
|
||||
if (this.isConnectedPs(ps, faction)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// MAP GENERATION
|
||||
|
||||
@Override
|
||||
public ArrayList<String> getMap(RelationParticipator observer, PS centerPs, double inDegrees, int width, int height)
|
||||
{
|
||||
centerPs = centerPs.getChunkCoords(true);
|
||||
|
||||
ArrayList<String> ret = new ArrayList<String>();
|
||||
Faction centerFaction = this.getFactionAt(centerPs);
|
||||
|
||||
ret.add(Txt.titleize("("+centerPs.getChunkX() + "," + centerPs.getChunkZ()+") "+centerFaction.getName(observer)));
|
||||
|
||||
int halfWidth = width / 2;
|
||||
int halfHeight = height / 2;
|
||||
width = halfWidth * 2 + 1;
|
||||
height = halfHeight * 2 + 1;
|
||||
|
||||
PS topLeftPs = centerPs.plusChunkCoords(-halfWidth, -halfHeight);
|
||||
|
||||
// Make room for the list of names
|
||||
height--;
|
||||
|
||||
Map<Faction, Character> fList = new HashMap<Faction, 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+"+";
|
||||
continue;
|
||||
}
|
||||
|
||||
PS herePs = topLeftPs.plusChunkCoords(dx, dz);
|
||||
Faction hereFaction = this.getFactionAt(herePs);
|
||||
if (hereFaction.isNone())
|
||||
{
|
||||
row += ChatColor.GRAY+"-";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!fList.containsKey(hereFaction))
|
||||
fList.put(hereFaction, Const.MAP_KEY_CHARS[chrIdx++]);
|
||||
char fchar = fList.get(hereFaction);
|
||||
row += hereFaction.getColorTo(observer) + "" + fchar;
|
||||
}
|
||||
}
|
||||
ret.add(row);
|
||||
}
|
||||
|
||||
// Get the compass
|
||||
ArrayList<String> asciiCompass = AsciiCompass.getAsciiCompass(inDegrees, ChatColor.RED, 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));
|
||||
|
||||
String fRow = "";
|
||||
for (Faction keyfaction : fList.keySet())
|
||||
{
|
||||
fRow += ""+keyfaction.getColorTo(observer) + fList.get(keyfaction) + ": " + keyfaction.getName() + " ";
|
||||
}
|
||||
fRow = fRow.trim();
|
||||
ret.add(fRow);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
374
src/com/massivecraft/factions/entity/BoardColl.java
Normal file
374
src/com/massivecraft/factions/entity/BoardColl.java
Normal file
@ -0,0 +1,374 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.massivecraft.factions.Const;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.RelationParticipator;
|
||||
import com.massivecraft.factions.TerritoryAccess;
|
||||
import com.massivecraft.massivecore.collections.MassiveMap;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.store.Coll;
|
||||
import com.massivecraft.massivecore.store.MStore;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
|
||||
public class BoardColl extends Coll<Board> implements BoardInterface
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static BoardColl i = new BoardColl();
|
||||
public static BoardColl get() { return i; }
|
||||
private BoardColl()
|
||||
{
|
||||
super(Const.COLLECTION_BOARD, Board.class, MStore.getDb(), Factions.get(), false, true, true);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE: COLL
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public String fixId(Object oid)
|
||||
{
|
||||
if (oid == null) return null;
|
||||
if (oid instanceof String) return (String)oid;
|
||||
if (oid instanceof Board) return this.getId(oid);
|
||||
|
||||
return MUtil.extract(String.class, "worldName", oid);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE: BOARD
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public TerritoryAccess getTerritoryAccessAt(PS ps)
|
||||
{
|
||||
if (ps == null) return null;
|
||||
Board board = this.get(ps.getWorld());
|
||||
if (board == null) return null;
|
||||
return board.getTerritoryAccessAt(ps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Faction getFactionAt(PS ps)
|
||||
{
|
||||
if (ps == null) return null;
|
||||
Board board = this.get(ps.getWorld());
|
||||
if (board == null) return null;
|
||||
return board.getFactionAt(ps);
|
||||
}
|
||||
|
||||
// SET
|
||||
|
||||
@Override
|
||||
public void setTerritoryAccessAt(PS ps, TerritoryAccess territoryAccess)
|
||||
{
|
||||
if (ps == null) return;
|
||||
Board board = this.get(ps.getWorld());
|
||||
if (board == null) return;
|
||||
board.setTerritoryAccessAt(ps, territoryAccess);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFactionAt(PS ps, Faction faction)
|
||||
{
|
||||
if (ps == null) return;
|
||||
Board board = this.get(ps.getWorld());
|
||||
if (board == null) return;
|
||||
board.setFactionAt(ps, faction);
|
||||
}
|
||||
|
||||
// REMOVE
|
||||
|
||||
@Override
|
||||
public void removeAt(PS ps)
|
||||
{
|
||||
if (ps == null) return;
|
||||
Board board = this.get(ps.getWorld());
|
||||
if (board == null) return;
|
||||
board.removeAt(ps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAll(Faction faction)
|
||||
{
|
||||
for (Board board : this.getAll())
|
||||
{
|
||||
board.removeAll(faction);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clean()
|
||||
{
|
||||
for (Board board : this.getAll())
|
||||
{
|
||||
board.clean();
|
||||
}
|
||||
}
|
||||
|
||||
// CHUNKS
|
||||
|
||||
@Override
|
||||
public Set<PS> getChunks(Faction faction)
|
||||
{
|
||||
Set<PS> ret = new HashSet<PS>();
|
||||
for (Board board : this.getAll())
|
||||
{
|
||||
ret.addAll(board.getChunks(faction));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PS> getChunks(String factionId)
|
||||
{
|
||||
Set<PS> ret = new HashSet<PS>();
|
||||
for (Board board : this.getAll())
|
||||
{
|
||||
ret.addAll(board.getChunks(factionId));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Faction, Set<PS>> getFactionToChunks()
|
||||
{
|
||||
Map<Faction, Set<PS>> ret = null;
|
||||
for (Board board : this.getAll())
|
||||
{
|
||||
// Use the first board directly
|
||||
Map<Faction, Set<PS>> factionToChunks = board.getFactionToChunks();
|
||||
if (ret == null)
|
||||
{
|
||||
ret = factionToChunks;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Merge the following boards
|
||||
for (Entry<Faction, Set<PS>> entry : factionToChunks.entrySet())
|
||||
{
|
||||
Faction faction = entry.getKey();
|
||||
Set<PS> chunks = ret.get(faction);
|
||||
if (chunks == null)
|
||||
{
|
||||
ret.put(faction, entry.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
chunks.addAll(entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == null) ret = new MassiveMap<Faction, Set<PS>>();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// COUNT
|
||||
|
||||
@Override
|
||||
public int getCount(Faction faction)
|
||||
{
|
||||
return this.getCount(faction.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount(String factionId)
|
||||
{
|
||||
int ret = 0;
|
||||
for (Board board : this.getAll())
|
||||
{
|
||||
ret += board.getCount(factionId);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Faction, Integer> getFactionToCount()
|
||||
{
|
||||
Map<Faction, Integer> ret = null;
|
||||
for (Board board : this.getAll())
|
||||
{
|
||||
// Use the first board directly
|
||||
Map<Faction, Integer> factionToCount = board.getFactionToCount();
|
||||
if (ret == null)
|
||||
{
|
||||
ret = factionToCount;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Merge the following boards
|
||||
for (Entry<Faction, Integer> entry : factionToCount.entrySet())
|
||||
{
|
||||
Faction faction = entry.getKey();
|
||||
Integer count = ret.get(faction);
|
||||
if (count == null)
|
||||
{
|
||||
ret.put(faction, entry.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.put(faction, count + entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == null) ret = new MassiveMap<Faction, Integer>();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// NEARBY DETECTION
|
||||
|
||||
@Override
|
||||
public boolean isBorderPs(PS ps)
|
||||
{
|
||||
if (ps == null) return false;
|
||||
Board board = this.get(ps.getWorld());
|
||||
if (board == null) return false;
|
||||
return board.isBorderPs(ps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnyBorderPs(Set<PS> pss)
|
||||
{
|
||||
for (PS ps : pss)
|
||||
{
|
||||
if (this.isBorderPs(ps)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnectedPs(PS ps, Faction faction)
|
||||
{
|
||||
if (ps == null) return false;
|
||||
Board board = this.get(ps.getWorld());
|
||||
if (board == null) return false;
|
||||
return board.isConnectedPs(ps, faction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnyConnectedPs(Set<PS> pss, Faction faction)
|
||||
{
|
||||
for (PS ps : pss)
|
||||
{
|
||||
if (this.isConnectedPs(ps, faction)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// MAP GENERATION
|
||||
|
||||
@Override
|
||||
public ArrayList<String> getMap(RelationParticipator observer, PS centerPs, double inDegrees, int width, int height)
|
||||
{
|
||||
if (centerPs == null) return null;
|
||||
Board board = this.get(centerPs.getWorld());
|
||||
if (board == null) return null;
|
||||
return board.getMap(observer, centerPs, inDegrees, width, height);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UTIL
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Distance -1 returns 0 chunks always.
|
||||
// Distance 0 returns 1 chunk only (the one supplied).
|
||||
// Distance 1 returns 3x3 = 9 chunks.
|
||||
public static Set<PS> getNearbyChunks(PS chunk, int distance)
|
||||
{
|
||||
// Fix Args
|
||||
if (chunk == null) throw new NullPointerException("chunk");
|
||||
chunk = chunk.getChunk(true);
|
||||
|
||||
// Create Ret
|
||||
Set<PS> ret = new LinkedHashSet<PS>();
|
||||
|
||||
if (distance < 0) return ret;
|
||||
|
||||
// Main
|
||||
int xmin = chunk.getChunkX() - distance;
|
||||
int xmax = chunk.getChunkX() + distance;
|
||||
|
||||
int zmin = chunk.getChunkZ() - distance;
|
||||
int zmax = chunk.getChunkZ() + distance;
|
||||
|
||||
for (int x = xmin; x <= xmax; x++)
|
||||
{
|
||||
for (int z = zmin; z <= zmax; z++)
|
||||
{
|
||||
ret.add(chunk.withChunkX(x).withChunkZ(z));
|
||||
}
|
||||
}
|
||||
|
||||
// Return Ret
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Set<PS> getNearbyChunks(Collection<PS> chunks, int distance)
|
||||
{
|
||||
// Fix Args
|
||||
if (chunks == null) throw new NullPointerException("chunks");
|
||||
|
||||
// Create Ret
|
||||
Set<PS> ret = new LinkedHashSet<PS>();
|
||||
|
||||
if (distance < 0) return ret;
|
||||
|
||||
// Main
|
||||
for (PS chunk : chunks)
|
||||
{
|
||||
ret.addAll(getNearbyChunks(chunk, distance));
|
||||
}
|
||||
|
||||
// Return Ret
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Set<Faction> getDistinctFactions(Collection<PS> chunks)
|
||||
{
|
||||
// Fix Args
|
||||
if (chunks == null) throw new NullPointerException("chunks");
|
||||
|
||||
// Create Ret
|
||||
Set<Faction> ret = new LinkedHashSet<Faction>();
|
||||
|
||||
// Main
|
||||
for (PS chunk : chunks)
|
||||
{
|
||||
Faction faction = BoardColl.get().getFactionAt(chunk);
|
||||
if (faction == null) continue;
|
||||
ret.add(faction);
|
||||
}
|
||||
|
||||
// Return Ret
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Map<PS, Faction> getChunkFaction(Collection<PS> chunks)
|
||||
{
|
||||
Map<PS, Faction> ret = new LinkedHashMap<PS, Faction>();
|
||||
|
||||
for (PS chunk : chunks)
|
||||
{
|
||||
chunk = chunk.getChunk(true);
|
||||
Faction faction = get().getFactionAt(chunk);
|
||||
if (faction == null) faction = FactionColl.get().getNone();
|
||||
ret.put(chunk, faction);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
46
src/com/massivecraft/factions/entity/BoardInterface.java
Normal file
46
src/com/massivecraft/factions/entity/BoardInterface.java
Normal file
@ -0,0 +1,46 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.massivecraft.factions.RelationParticipator;
|
||||
import com.massivecraft.factions.TerritoryAccess;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
|
||||
public interface BoardInterface
|
||||
{
|
||||
// GET
|
||||
public TerritoryAccess getTerritoryAccessAt(PS ps);
|
||||
public Faction getFactionAt(PS ps);
|
||||
|
||||
// SET
|
||||
public void setTerritoryAccessAt(PS ps, TerritoryAccess territoryAccess);
|
||||
public void setFactionAt(PS ps, Faction faction);
|
||||
|
||||
// REMOVE
|
||||
public void removeAt(PS ps);
|
||||
public void removeAll(Faction faction);
|
||||
public void clean();
|
||||
|
||||
// CHUNKS
|
||||
public Set<PS> getChunks(Faction faction);
|
||||
public Set<PS> getChunks(String factionId);
|
||||
public Map<Faction, Set<PS>> getFactionToChunks();
|
||||
|
||||
// COUNT
|
||||
public int getCount(Faction faction);
|
||||
public int getCount(String factionId);
|
||||
public Map<Faction, Integer> getFactionToCount();
|
||||
|
||||
// NEARBY DETECTION
|
||||
public boolean isBorderPs(PS ps);
|
||||
public boolean isAnyBorderPs(Set<PS> pss);
|
||||
public boolean isConnectedPs(PS ps, Faction faction);
|
||||
public boolean isAnyConnectedPs(Set<PS> pss, Faction faction);
|
||||
|
||||
// MAP
|
||||
// TODO: Could the degrees be embedded in centerPs yaw instead?
|
||||
public ArrayList<String> getMap(RelationParticipator observer, PS centerPs, double inDegrees, int width, int height);
|
||||
|
||||
}
|
1214
src/com/massivecraft/factions/entity/Faction.java
Normal file
1214
src/com/massivecraft/factions/entity/Faction.java
Normal file
File diff suppressed because it is too large
Load Diff
307
src/com/massivecraft/factions/entity/FactionColl.java
Normal file
307
src/com/massivecraft/factions/entity/FactionColl.java
Normal file
@ -0,0 +1,307 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.massivecraft.massivecore.store.Coll;
|
||||
import com.massivecraft.massivecore.store.MStore;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
import com.massivecraft.factions.Const;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.integration.Econ;
|
||||
import com.massivecraft.factions.util.MiscUtil;
|
||||
|
||||
public class FactionColl extends Coll<Faction>
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static FactionColl i = new FactionColl();
|
||||
public static FactionColl get() { return i; }
|
||||
private FactionColl()
|
||||
{
|
||||
super(Const.COLLECTION_FACTION, Faction.class, MStore.getDb(), Factions.get());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE: COLL
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
this.createSpecialFactions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Faction get(Object oid)
|
||||
{
|
||||
Faction ret = super.get(oid);
|
||||
|
||||
// We should only trigger automatic clean if the whole database system is initialized.
|
||||
// A cleaning can only be successful if all data is available.
|
||||
// Example Reason: When creating the special factions for the first time "createSpecialFactions" a clean would be triggered otherwise.
|
||||
if (ret == null && Factions.get().isDatabaseInitialized())
|
||||
{
|
||||
String message = Txt.parse("<b>Non existing factionId <h>%s <b>requested. <i>Cleaning all boards and mplayers.", this.fixId(oid));
|
||||
Factions.get().log(message);
|
||||
|
||||
BoardColl.get().clean();
|
||||
MPlayerColl.get().clean();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// INDEX
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void reindexMPlayers()
|
||||
{
|
||||
for (Faction faction : this.getAll())
|
||||
{
|
||||
faction.reindexMPlayers();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// SPECIAL FACTIONS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void createSpecialFactions()
|
||||
{
|
||||
this.getNone();
|
||||
this.getSafezone();
|
||||
this.getWarzone();
|
||||
}
|
||||
|
||||
public Faction getNone()
|
||||
{
|
||||
String id = Factions.ID_NONE;
|
||||
Faction faction = this.get(id);
|
||||
if (faction != null) return faction;
|
||||
|
||||
faction = this.create(id);
|
||||
|
||||
faction.setName(Factions.NAME_NONE_DEFAULT);
|
||||
faction.setDescription(null);
|
||||
|
||||
faction.setFlag(MFlag.getFlagOpen(), false);
|
||||
faction.setFlag(MFlag.getFlagPermanent(), true);
|
||||
faction.setFlag(MFlag.getFlagPeaceful(), false);
|
||||
faction.setFlag(MFlag.getFlagInfpower(), true);
|
||||
faction.setFlag(MFlag.getFlagPowerloss(), true);
|
||||
faction.setFlag(MFlag.getFlagPvp(), true);
|
||||
faction.setFlag(MFlag.getFlagFriendlyire(), false);
|
||||
faction.setFlag(MFlag.getFlagMonsters(), true);
|
||||
faction.setFlag(MFlag.getFlagExplosions(), true);
|
||||
faction.setFlag(MFlag.getFlagOfflineexplosions(), true);
|
||||
faction.setFlag(MFlag.getFlagFirespread(), true);
|
||||
faction.setFlag(MFlag.getFlagEndergrief(), true);
|
||||
|
||||
faction.setPermittedRelations(MPerm.getPermBuild(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermDoor(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermContainer(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermButton(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermLever(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermDeposit(), Rel.LEADER, Rel.OFFICER); // Wilderness deposit should be limited as an anti spam meassure.
|
||||
|
||||
return faction;
|
||||
}
|
||||
|
||||
public Faction getSafezone()
|
||||
{
|
||||
String id = Factions.ID_SAFEZONE;
|
||||
Faction faction = this.get(id);
|
||||
if (faction != null) return faction;
|
||||
|
||||
faction = this.create(id);
|
||||
|
||||
faction.setName(Factions.NAME_SAFEZONE_DEFAULT);
|
||||
faction.setDescription("Free from PVP and monsters");
|
||||
|
||||
faction.setFlag(MFlag.getFlagOpen(), false);
|
||||
faction.setFlag(MFlag.getFlagPermanent(), true);
|
||||
faction.setFlag(MFlag.getFlagPeaceful(), true);
|
||||
faction.setFlag(MFlag.getFlagInfpower(), true);
|
||||
faction.setFlag(MFlag.getFlagPowerloss(), false);
|
||||
faction.setFlag(MFlag.getFlagPvp(), false);
|
||||
faction.setFlag(MFlag.getFlagFriendlyire(), false);
|
||||
faction.setFlag(MFlag.getFlagMonsters(), false);
|
||||
faction.setFlag(MFlag.getFlagExplosions(), false);
|
||||
faction.setFlag(MFlag.getFlagOfflineexplosions(), false);
|
||||
faction.setFlag(MFlag.getFlagFirespread(), false);
|
||||
faction.setFlag(MFlag.getFlagEndergrief(), false);
|
||||
|
||||
faction.setPermittedRelations(MPerm.getPermDoor(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermContainer(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermButton(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermLever(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermTerritory(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER);
|
||||
|
||||
return faction;
|
||||
}
|
||||
|
||||
public Faction getWarzone()
|
||||
{
|
||||
String id = Factions.ID_WARZONE;
|
||||
Faction faction = this.get(id);
|
||||
if (faction != null) return faction;
|
||||
|
||||
faction = this.create(id);
|
||||
|
||||
faction.setName(Factions.NAME_WARZONE_DEFAULT);
|
||||
faction.setDescription("Not the safest place to be");
|
||||
|
||||
faction.setFlag(MFlag.getFlagOpen(), false);
|
||||
faction.setFlag(MFlag.getFlagPermanent(), true);
|
||||
faction.setFlag(MFlag.getFlagPeaceful(), true);
|
||||
faction.setFlag(MFlag.getFlagInfpower(), true);
|
||||
faction.setFlag(MFlag.getFlagPowerloss(), true);
|
||||
faction.setFlag(MFlag.getFlagPvp(), true);
|
||||
faction.setFlag(MFlag.getFlagFriendlyire(), true);
|
||||
faction.setFlag(MFlag.getFlagMonsters(), true);
|
||||
faction.setFlag(MFlag.getFlagExplosions(), true);
|
||||
faction.setFlag(MFlag.getFlagOfflineexplosions(), true);
|
||||
faction.setFlag(MFlag.getFlagFirespread(), true);
|
||||
faction.setFlag(MFlag.getFlagEndergrief(), true);
|
||||
|
||||
faction.setPermittedRelations(MPerm.getPermDoor(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermContainer(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermButton(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermLever(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
|
||||
faction.setPermittedRelations(MPerm.getPermTerritory(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER);
|
||||
|
||||
return faction;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// LAND REWARD
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void econLandRewardRoutine()
|
||||
{
|
||||
if (!Econ.isEnabled()) return;
|
||||
|
||||
double econLandReward = MConf.get().econLandReward;
|
||||
if (econLandReward == 0.0) return;
|
||||
|
||||
Factions.get().log("Running econLandRewardRoutine...");
|
||||
for (Faction faction : this.getAll())
|
||||
{
|
||||
int landCount = faction.getLandCount();
|
||||
if (!faction.getFlag(MFlag.getFlagPeaceful()) && landCount > 0)
|
||||
{
|
||||
List<MPlayer> players = faction.getMPlayers();
|
||||
int playerCount = players.size();
|
||||
double reward = econLandReward * landCount / playerCount;
|
||||
for (MPlayer player : players)
|
||||
{
|
||||
Econ.modifyMoney(player, reward, "own " + landCount + " faction land divided among " + playerCount + " members");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FACTION NAME
|
||||
// -------------------------------------------- //
|
||||
|
||||
public ArrayList<String> validateName(String str)
|
||||
{
|
||||
ArrayList<String> errors = new ArrayList<String>();
|
||||
|
||||
if (MiscUtil.getComparisonString(str).length() < MConf.get().factionNameLengthMin)
|
||||
{
|
||||
errors.add(Txt.parse("<i>The faction name can't be shorter than <h>%s<i> chars.", MConf.get().factionNameLengthMin));
|
||||
}
|
||||
|
||||
if (str.length() > MConf.get().factionNameLengthMax)
|
||||
{
|
||||
errors.add(Txt.parse("<i>The faction name can't be longer than <h>%s<i> chars.", MConf.get().factionNameLengthMax));
|
||||
}
|
||||
|
||||
for (char c : str.toCharArray())
|
||||
{
|
||||
if ( ! MiscUtil.substanceChars.contains(String.valueOf(c)))
|
||||
{
|
||||
errors.add(Txt.parse("<i>Faction name must be alphanumeric. \"<h>%s<i>\" is not allowed.", c));
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
public Faction getByName(String name)
|
||||
{
|
||||
String compStr = MiscUtil.getComparisonString(name);
|
||||
for (Faction faction : this.getAll())
|
||||
{
|
||||
if (faction.getComparisonName().equals(compStr))
|
||||
{
|
||||
return faction;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isNameTaken(String str)
|
||||
{
|
||||
return this.getByName(str) != null;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OLD MIGRATION COMMENT
|
||||
// -------------------------------------------- //
|
||||
|
||||
/*
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
this.migrate();
|
||||
}
|
||||
|
||||
// This method is for the 1.8.X --> 2.0.0 migration
|
||||
public void migrate()
|
||||
{
|
||||
// Create file objects
|
||||
File oldFile = new File(Factions.get().getDataFolder(), "factions.json");
|
||||
File newFile = new File(Factions.get().getDataFolder(), "factions.json.migrated");
|
||||
|
||||
// Already migrated?
|
||||
if ( ! oldFile.exists()) return;
|
||||
|
||||
// Faction ids /delete
|
||||
// For simplicity we just drop the old special factions.
|
||||
// They will be replaced with new autogenerated ones per universe.
|
||||
Set<String> factionIdsToDelete = MUtil.set("0", "-1", "-2");
|
||||
|
||||
// Read the file content through GSON.
|
||||
Type type = new TypeToken<Map<String, Faction>>(){}.getType();
|
||||
Map<String, Faction> id2faction = Factions.get().gson.fromJson(DiscUtil.readCatch(oldFile), type);
|
||||
|
||||
// The Coll
|
||||
FactionColl coll = this.getForUniverse(MassiveCore.DEFAULT);
|
||||
|
||||
// Set the data
|
||||
for (Entry<String, Faction> entry : id2faction.entrySet())
|
||||
{
|
||||
String factionId = entry.getKey();
|
||||
if (factionIdsToDelete.contains(factionId)) continue;
|
||||
Faction faction = entry.getValue();
|
||||
coll.attach(faction, factionId);
|
||||
}
|
||||
|
||||
// Mark as migrated
|
||||
oldFile.renameTo(newFile);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
684
src/com/massivecraft/factions/entity/MConf.java
Normal file
684
src/com/massivecraft/factions/entity/MConf.java
Normal file
@ -0,0 +1,684 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.engine.EngineChat;
|
||||
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
|
||||
import com.massivecraft.massivecore.collections.BackstringEnumSet;
|
||||
import com.massivecraft.massivecore.collections.WorldExceptionSet;
|
||||
import com.massivecraft.massivecore.store.Entity;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import com.massivecraft.massivecore.util.TimeUnit;
|
||||
|
||||
public class MConf extends Entity<MConf>
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// META
|
||||
// -------------------------------------------- //
|
||||
|
||||
protected static transient MConf i;
|
||||
public static MConf get() { return i; }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE: ENTITY
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public MConf load(MConf that)
|
||||
{
|
||||
super.load(that);
|
||||
|
||||
if (!Factions.get().isDatabaseInitialized()) return this;
|
||||
|
||||
EngineChat.get().deactivate();
|
||||
EngineChat.get().activate();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// COMMAND ALIASES
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Don't you want "f" as the base command alias? Simply change it here.
|
||||
public List<String> aliasesF = MUtil.list("f");
|
||||
|
||||
// -------------------------------------------- //
|
||||
// WORLDS FEATURE ENABLED
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Use this blacklist/whitelist system to toggle features on a per world basis.
|
||||
// Do you only want claiming enabled on the one map called "Hurr"?
|
||||
// In such case set standard to false and add "Hurr" as an exeption to worldsClaimingEnabled.
|
||||
public WorldExceptionSet worldsClaimingEnabled = new WorldExceptionSet();
|
||||
public WorldExceptionSet worldsPowerLossEnabled = new WorldExceptionSet();
|
||||
public WorldExceptionSet worldsPvpRulesEnabled = new WorldExceptionSet();
|
||||
|
||||
// -------------------------------------------- //
|
||||
// DERPY OVERRIDES
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Add player names here who should bypass all protections.
|
||||
// Should /not/ be used for admins. There is "/f adminmode" for that.
|
||||
// This is for other plugins/mods that use a fake player to take actions, which shouldn't be subject to our protections.
|
||||
public Set<String> playersWhoBypassAllProtection = new LinkedHashSet<String>();
|
||||
|
||||
// -------------------------------------------- //
|
||||
// TASKS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Define the time in minutes between certain Factions system tasks is ran.
|
||||
public double taskPlayerPowerUpdateMinutes = 1;
|
||||
public double taskPlayerDataRemoveMinutes = 5;
|
||||
public double taskEconLandRewardMinutes = 20;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// REMOVE DATA
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Should players be kicked from their faction and their data erased when banned?
|
||||
public boolean removePlayerWhenBanned = true;
|
||||
|
||||
// After how many milliseconds should players be automatically kicked from their faction?
|
||||
|
||||
// The Default
|
||||
public long removePlayerMillisDefault = 10 * TimeUnit.MILLIS_PER_DAY; // 10 days
|
||||
|
||||
// Player Age Bonus
|
||||
public Map<Long, Long> removePlayerMillisPlayerAgeToBonus = MUtil.map(
|
||||
2 * TimeUnit.MILLIS_PER_WEEK, 10 * TimeUnit.MILLIS_PER_DAY // +10 days after 2 weeks
|
||||
);
|
||||
|
||||
// Faction Age Bonus
|
||||
public Map<Long, Long> removePlayerMillisFactionAgeToBonus = MUtil.map(
|
||||
4 * TimeUnit.MILLIS_PER_WEEK, 10 * TimeUnit.MILLIS_PER_DAY, // +10 days after 4 weeks
|
||||
2 * TimeUnit.MILLIS_PER_WEEK, 5 * TimeUnit.MILLIS_PER_DAY // +5 days after 2 weeks
|
||||
);
|
||||
|
||||
// -------------------------------------------- //
|
||||
// SPECIAL FACTION IDS
|
||||
// -------------------------------------------- //
|
||||
// These are a deprecated remnant from the universe system.
|
||||
// We needed these to understand the difference between wilderness in different universes.
|
||||
// Now that we are back to one universe only, we can have static names like simply "none", "safezone" and "warzone".
|
||||
// Previously we set them to UUID.randomUUID().toString() but now we set them to null.
|
||||
// If the value is set we use it to update map entries and then set it to null really quick.
|
||||
|
||||
public String factionIdNone = null;
|
||||
public String factionIdSafezone = null;
|
||||
public String factionIdWarzone = null;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// DEFAULTS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Which faction should new players be followers of?
|
||||
// "none" means Wilderness. Remember to specify the id, like "3defeec7-b3b1-48d9-82bb-2a8903df24e3" and not the name.
|
||||
public String defaultPlayerFactionId = Factions.ID_NONE;
|
||||
|
||||
// What rank should new players joining a faction get?
|
||||
// If not RECRUIT then MEMBER might make sense.
|
||||
public Rel defaultPlayerRole = Rel.RECRUIT;
|
||||
|
||||
// What power should the player start with?
|
||||
public double defaultPlayerPower = 0.0;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// MOTD
|
||||
// -------------------------------------------- //
|
||||
|
||||
// During which event priority should the faction message of the day be displayed?
|
||||
// Choose between: LOWEST, LOW, NORMAL, HIGH, HIGHEST and MONITOR.
|
||||
// This setting only matters if "motdDelayTicks" is set to -1
|
||||
public EventPriority motdPriority = EventPriority.NORMAL;
|
||||
|
||||
// How many ticks should we delay the faction message of the day with?
|
||||
// -1 means we don't delay at all. We display it at once.
|
||||
// 0 means it's deferred to the upcomming server tick.
|
||||
// 5 means we delay it yet another 5 ticks.
|
||||
public int motdDelayTicks = -1;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// POWER
|
||||
// -------------------------------------------- //
|
||||
|
||||
// What is the maximum player power?
|
||||
public double powerMax = 10.0;
|
||||
|
||||
// What is the minimum player power?
|
||||
// NOTE: Negative minimum values is possible.
|
||||
public double powerMin = 0.0;
|
||||
|
||||
// How much power should be regained per hour online on the server?
|
||||
public double powerPerHour = 2.0;
|
||||
|
||||
// How much power should be lost on death?
|
||||
public double powerPerDeath = -2.0;
|
||||
|
||||
// Can players with negative power leave their faction?
|
||||
// NOTE: This only makes sense to set to false if your "powerMin" setting is negative.
|
||||
public boolean canLeaveWithNegativePower = true;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CORE
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Is there a maximum amount of members per faction?
|
||||
// 0 means there is not. If you set it to 100 then there can at most be 100 members per faction.
|
||||
public int factionMemberLimit = 0;
|
||||
|
||||
// Is there a maximum faction power cap?
|
||||
// 0 means there is not. Set it to a positive value in case you wan't to use this feature.
|
||||
public double factionPowerMax = 0.0;
|
||||
|
||||
// Limit the length of faction names here.
|
||||
public int factionNameLengthMin = 3;
|
||||
public int factionNameLengthMax = 16;
|
||||
|
||||
// Should faction names automatically be converted to upper case?
|
||||
// You probably don't want this feature.
|
||||
// It's a remnant from old faction versions.
|
||||
public boolean factionNameForceUpperCase = false;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// SET LIMITS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// When using radius setting of faction territory, what is the maximum radius allowed?
|
||||
public int setRadiusMax = 30;
|
||||
|
||||
// When using fill setting of faction territory, what is the maximum chunk count allowed?
|
||||
public int setFillMax = 1000;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CLAIMS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Must claims be connected to each other?
|
||||
// If you set this to false you will allow factions to claim more than one base per world map.
|
||||
// That would makes outposts possible but also potentially ugly weird claims messing up your Dynmap and ingame experiance.
|
||||
public boolean claimsMustBeConnected = true;
|
||||
|
||||
// Would you like to allow unconnected claims when conquering land from another faction?
|
||||
// Setting this to true would allow taking over someone elses base even if claims normally have to be connected.
|
||||
// Note that even without this you can pillage/unclaim another factions territory in war.
|
||||
// You just won't be able to take the land as your own.
|
||||
public boolean claimsCanBeUnconnectedIfOwnedByOtherFaction = false;
|
||||
|
||||
// Is claiming from other factions even allowed?
|
||||
// Set this to false to disable territorial warfare altogether.
|
||||
public boolean claimingFromOthersAllowed = true;
|
||||
|
||||
// Is a minimum distance (measured in chunks) to other factions required?
|
||||
// 0 means the feature is disabled.
|
||||
// Set the feature to 10 and there must be 10 chunks of wilderness between factions.
|
||||
// Factions may optionally allow their allies to bypass this limit by configuring their faction permissions ingame themselves.
|
||||
public int claimMinimumChunksDistanceToOthers = 0;
|
||||
|
||||
// Do you need a minimum amount of faction members to claim land?
|
||||
// 1 means just the faction leader alone is enough.
|
||||
public int claimsRequireMinFactionMembers = 1;
|
||||
|
||||
// Is there a maximum limit to chunks claimed?
|
||||
// 0 means there isn't.
|
||||
public int claimedLandsMax = 0;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// HOMES
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Is the home feature enabled?
|
||||
// If you set this to false players can't set homes or teleport home.
|
||||
public boolean homesEnabled = true;
|
||||
|
||||
// Must homes be located inside the faction's territory?
|
||||
// It's usually a wise idea keeping this true.
|
||||
// Otherwise players can set their homes inside enemy territory.
|
||||
public boolean homesMustBeInClaimedTerritory = true;
|
||||
|
||||
// Is the home teleport command available?
|
||||
// One reason you might set this to false is if you only want players going home on respawn after death.
|
||||
public boolean homesTeleportCommandEnabled = true;
|
||||
|
||||
// These options can be used to limit rights to tp home under different circumstances.
|
||||
public boolean homesTeleportAllowedFromEnemyTerritory = true;
|
||||
public boolean homesTeleportAllowedFromDifferentWorld = true;
|
||||
public double homesTeleportAllowedEnemyDistance = 32.0;
|
||||
public boolean homesTeleportIgnoreEnemiesIfInOwnTerritory = true;
|
||||
|
||||
// Should players teleport to faction home on death?
|
||||
// Set this to true to override the default respawn location.
|
||||
public boolean homesTeleportToOnDeathActive = false;
|
||||
|
||||
// This value can be used to tweak compatibility with other plugins altering the respawn location.
|
||||
// Choose between: LOWEST, LOW, NORMAL, HIGH, HIGHEST and MONITOR.
|
||||
public EventPriority homesTeleportToOnDeathPriority = EventPriority.NORMAL;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// ASSORTED
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Set this to true if want to block the promotion of new leaders for permanent factions.
|
||||
// I don't really understand the user case for this option.
|
||||
public boolean permanentFactionsDisableLeaderPromotion = false;
|
||||
|
||||
// How much health damage should a player take upon placing or breaking a block in a "pain build" territory?
|
||||
// 2.0 means one heart.
|
||||
public double actionDeniedPainAmount = 2.0D;
|
||||
|
||||
// If you set this option to true then factionless players cant partake in PVP.
|
||||
// It works in both directions. Meaning you must join a faction to hurt players and get hurt by players.
|
||||
public boolean disablePVPForFactionlessPlayers = false;
|
||||
|
||||
// Set this option to true to create an exception to the rule above.
|
||||
// Players inside their own faction territory can then hurt facitonless players.
|
||||
// This way you may "evict" factionless trolls messing around in your home base.
|
||||
public boolean enablePVPAgainstFactionlessInAttackersLand = false;
|
||||
|
||||
// Inside your own faction territory you take less damage.
|
||||
// 0.1 means that you take 10% less damage at home.
|
||||
public double territoryShieldFactor = 0.1D;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// DENY COMMANDS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// A list of commands to block for members of permanent factions.
|
||||
// I don't really understand the user case for this option.
|
||||
public List<String> denyCommandsPermanentFactionMember = new ArrayList<String>();
|
||||
|
||||
// Lists of commands to deny depending on your relation to the current faction territory.
|
||||
// You may for example not type /home (might be the plugin Essentials) in the territory of your enemies.
|
||||
public Map<Rel, List<String>> denyCommandsTerritoryRelation = MUtil.map(
|
||||
Rel.ENEMY, MUtil.list(
|
||||
// Essentials commands
|
||||
"home",
|
||||
"homes",
|
||||
"sethome",
|
||||
"createhome",
|
||||
"tpahere",
|
||||
"tpaccept",
|
||||
"tpyes",
|
||||
"tpa",
|
||||
"call",
|
||||
"tpask",
|
||||
"warp",
|
||||
"warps",
|
||||
"spawn",
|
||||
// Essentials e-alliases
|
||||
"ehome",
|
||||
"ehomes",
|
||||
"esethome",
|
||||
"ecreatehome",
|
||||
"etpahere",
|
||||
"etpaccept",
|
||||
"etpyes",
|
||||
"etpa",
|
||||
"ecall",
|
||||
"etpask",
|
||||
"ewarp",
|
||||
"ewarps",
|
||||
"espawn",
|
||||
// Essentials fallback alliases
|
||||
"essentials:home",
|
||||
"essentials:homes",
|
||||
"essentials:sethome",
|
||||
"essentials:createhome",
|
||||
"essentials:tpahere",
|
||||
"essentials:tpaccept",
|
||||
"essentials:tpyes",
|
||||
"essentials:tpa",
|
||||
"essentials:call",
|
||||
"essentials:tpask",
|
||||
"essentials:warp",
|
||||
"essentials:warps",
|
||||
"essentials:spawn",
|
||||
// Other plugins
|
||||
"wtp",
|
||||
"uspawn",
|
||||
"utp",
|
||||
"mspawn",
|
||||
"mtp",
|
||||
"fspawn",
|
||||
"ftp",
|
||||
"jspawn",
|
||||
"jtp"
|
||||
),
|
||||
Rel.NEUTRAL, new ArrayList<String>(),
|
||||
Rel.TRUCE, new ArrayList<String>(),
|
||||
Rel.ALLY, new ArrayList<String>(),
|
||||
Rel.MEMBER, new ArrayList<String>()
|
||||
);
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CHAT
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Should Factions set the chat format?
|
||||
// This should be kept at false if you use an external chat format plugin.
|
||||
// If you are planning on running a more lightweight server you can set this to true.
|
||||
public boolean chatSetFormat = true;
|
||||
|
||||
// At which event priority should the chat format be set in such case?
|
||||
// Choose between: LOWEST, LOW, NORMAL, HIGH and HIGHEST.
|
||||
public EventPriority chatSetFormatAt = EventPriority.LOWEST;
|
||||
|
||||
// What format should be set?
|
||||
public String chatSetFormatTo = "<{factions_relcolor}§l{factions_roleprefix}§r{factions_relcolor}{factions_name|rp}§f%1$s> %2$s";
|
||||
|
||||
// Should the chat tags such as {factions_name} be parsed?
|
||||
// NOTE: You can set this to true even with chatSetFormat = false.
|
||||
// But in such case you must set the chat format using an external chat format plugin.
|
||||
public boolean chatParseTags = true;
|
||||
|
||||
// At which event priority should the faction chat tags be parsed in such case?
|
||||
// Choose between: LOWEST, LOW, NORMAL, HIGH, HIGHEST.
|
||||
public EventPriority chatParseTagsAt = EventPriority.LOW;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// COLORS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Here you can alter the colors tied to certain faction relations and settings.
|
||||
// You probably don't want to edit these to much.
|
||||
// Doing so might confuse players that are used to Factions.
|
||||
public ChatColor colorMember = ChatColor.GREEN;
|
||||
public ChatColor colorAlly = ChatColor.DARK_PURPLE;
|
||||
public ChatColor colorTruce = ChatColor.LIGHT_PURPLE;
|
||||
public ChatColor colorNeutral = ChatColor.WHITE;
|
||||
public ChatColor colorEnemy = ChatColor.RED;
|
||||
|
||||
// This one is for example applied to SafeZone since that faction has the pvp flag set to false.
|
||||
public ChatColor colorNoPVP = ChatColor.GOLD;
|
||||
|
||||
// This one is for example applied to WarZone since that faction has the friendly fire flag set to true.
|
||||
public ChatColor colorFriendlyFire = ChatColor.DARK_RED;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// PREFIXES
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Here you may edit the name prefixes associated with different faction ranks.
|
||||
public String prefixLeader = "**";
|
||||
public String prefixOfficer = "*";
|
||||
public String prefixMember = "+";
|
||||
public String prefixRecruit = "-";
|
||||
|
||||
// -------------------------------------------- //
|
||||
// EXPLOITS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public boolean handleExploitObsidianGenerators = true;
|
||||
public boolean handleExploitEnderPearlClipping = true;
|
||||
public boolean handleExploitTNTWaterlog = false;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// SEE CHUNK
|
||||
// -------------------------------------------- //
|
||||
|
||||
// These options can be used to tweak the "/f seechunk" particle effect.
|
||||
// They are fine as is but feel free to experiment with them if you want to.
|
||||
|
||||
// Use 1 or multiple of 3, 4 or 5.
|
||||
public int seeChunkSteps = 1;
|
||||
|
||||
// White/Black List for creating sparse patterns.
|
||||
public int seeChunkKeepEvery = 5;
|
||||
public int seeChunkSkipEvery = 0;
|
||||
|
||||
public long seeChunkPeriodMillis = 500;
|
||||
public int seeChunkParticleAmount = 30;
|
||||
public float seeChunkParticleOffsetY = 2;
|
||||
public float seeChunkParticleDeltaY = 2;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// LOGGING
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Here you can disable logging of certain events to the server console.
|
||||
|
||||
public boolean logFactionCreate = true;
|
||||
public boolean logFactionDisband = true;
|
||||
public boolean logFactionJoin = true;
|
||||
public boolean logFactionKick = true;
|
||||
public boolean logFactionLeave = true;
|
||||
public boolean logLandClaims = true;
|
||||
public boolean logLandUnclaims = true;
|
||||
public boolean logMoneyTransactions = true;
|
||||
public boolean logPlayerCommands = true;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// ENUMERATIONS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// These values are fine for most standard bukkit/spigot servers.
|
||||
// If you however are using Forge with mods that add new container types you might want to add them here.
|
||||
// This way they can be protected in Faction territory.
|
||||
|
||||
// Interacting with these materials when they are already placed in the terrain results in an edit.
|
||||
public BackstringEnumSet<Material> materialsEditOnInteract = new BackstringEnumSet<Material>(Material.class,
|
||||
"DIODE_BLOCK_OFF", // Minecraft 1.?
|
||||
"DIODE_BLOCK_ON", // Minecraft 1.?
|
||||
"NOTE_BLOCK", // Minecraft 1.?
|
||||
"CAULDRON", // Minecraft 1.?
|
||||
"SOIL" // Minecraft 1.?
|
||||
);
|
||||
|
||||
// Interacting with the the terrain holding this item in hand results in an edit.
|
||||
// There's no need to add all block materials here. Only special items other than blocks.
|
||||
public BackstringEnumSet<Material> materialsEditTools = new BackstringEnumSet<Material>(Material.class,
|
||||
"FIREBALL", // Minecraft 1.?
|
||||
"FLINT_AND_STEEL", // Minecraft 1.?
|
||||
"BUCKET", // Minecraft 1.?
|
||||
"WATER_BUCKET", // Minecraft 1.?
|
||||
"LAVA_BUCKET", // Minecraft 1.?
|
||||
"ARMOR_STAND" // Minecraft 1.8
|
||||
);
|
||||
|
||||
// The duplication bug found in Spigot 1.8 protocol patch
|
||||
// https://github.com/MassiveCraft/Factions/issues/693
|
||||
public BackstringEnumSet<Material> materialsEditToolsDupeBug = new BackstringEnumSet<Material>(Material.class,
|
||||
"CHEST", // Minecraft 1.?
|
||||
"SIGN_POST", // Minecraft 1.?
|
||||
"TRAPPED_CHEST", // Minecraft 1.?
|
||||
"SIGN", // Minecraft 1.?
|
||||
"WOOD_DOOR", // Minecraft 1.?
|
||||
"IRON_DOOR" // Minecraft 1.?
|
||||
);
|
||||
|
||||
// Interacting with these materials placed in the terrain results in door toggling.
|
||||
public BackstringEnumSet<Material> materialsDoor = new BackstringEnumSet<Material>(Material.class,
|
||||
"WOODEN_DOOR", // Minecraft 1.?
|
||||
"ACACIA_DOOR", // Minecraft 1.8
|
||||
"BIRCH_DOOR", // Minecraft 1.8
|
||||
"DARK_OAK_DOOR", // Minecraft 1.8
|
||||
"JUNGLE_DOOR", // Minecraft 1.8
|
||||
"SPRUCE_DOOR", // Minecraft 1.8
|
||||
"TRAP_DOOR", // Minecraft 1.?
|
||||
"FENCE_GATE", // Minecraft 1.?
|
||||
"ACACIA_FENCE_GATE", // Minecraft 1.8
|
||||
"BIRCH_FENCE_GATE", // Minecraft 1.8
|
||||
"DARK_OAK_FENCE_GATE", // Minecraft 1.8
|
||||
"JUNGLE_FENCE_GATE", // Minecraft 1.8
|
||||
"SPRUCE_FENCE_GATE" // Minecraft 1.8
|
||||
);
|
||||
|
||||
// Interacting with these materials placed in the terrain results in opening a container.
|
||||
public BackstringEnumSet<Material> materialsContainer = new BackstringEnumSet<Material>(Material.class,
|
||||
"DISPENSER", // Minecraft 1.?
|
||||
"CHEST", // Minecraft 1.?
|
||||
"FURNACE", // Minecraft 1.?
|
||||
"BURNING_FURNACE", // Minecraft 1.?
|
||||
"JUKEBOX", // Minecraft 1.?
|
||||
"BREWING_STAND", // Minecraft 1.?
|
||||
"ENCHANTMENT_TABLE", // Minecraft 1.?
|
||||
"ANVIL", // Minecraft 1.?
|
||||
"BEACON", // Minecraft 1.?
|
||||
"TRAPPED_CHEST", // Minecraft 1.?
|
||||
"HOPPER", // Minecraft 1.?
|
||||
"DROPPER" // Minecraft 1.?
|
||||
);
|
||||
|
||||
// Interacting with these entities results in an edit.
|
||||
public BackstringEnumSet<EntityType> entityTypesEditOnInteract = new BackstringEnumSet<EntityType>(EntityType.class,
|
||||
"ITEM_FRAME", // Minecraft 1.?
|
||||
"ARMOR_STAND" // Minecraft 1.8
|
||||
);
|
||||
|
||||
// Damaging these entities results in an edit.
|
||||
public BackstringEnumSet<EntityType> entityTypesEditOnDamage = new BackstringEnumSet<EntityType>(EntityType.class,
|
||||
"ITEM_FRAME", // Minecraft 1.?
|
||||
"ARMOR_STAND" // Minecraft 1.8
|
||||
);
|
||||
|
||||
// Interacting with these entities results in opening a container.
|
||||
public BackstringEnumSet<EntityType> entityTypesContainer = new BackstringEnumSet<EntityType>(EntityType.class,
|
||||
"MINECART_CHEST", // Minecraft 1.?
|
||||
"MINECART_HOPPER" // Minecraft 1.?
|
||||
);
|
||||
|
||||
// The complete list of entities considered to be monsters.
|
||||
public BackstringEnumSet<EntityType> entityTypesMonsters = new BackstringEnumSet<EntityType>(EntityType.class,
|
||||
"BLAZE", // Minecraft 1.?
|
||||
"CAVE_SPIDER", // Minecraft 1.?
|
||||
"CREEPER", // Minecraft 1.?
|
||||
"ENDERMAN", // Minecraft 1.?
|
||||
"ENDER_DRAGON", // Minecraft 1.?
|
||||
"GUARDIAN", // Minecraft 1.8
|
||||
"GHAST", // Minecraft 1.?
|
||||
"GIANT", // Minecraft 1.?
|
||||
"MAGMA_CUBE", // Minecraft 1.?
|
||||
"PIG_ZOMBIE", // Minecraft 1.?
|
||||
"SILVERFISH", // Minecraft 1.?
|
||||
"SKELETON", // Minecraft 1.?
|
||||
"SLIME", // Minecraft 1.?
|
||||
"SPIDER", // Minecraft 1.?
|
||||
"WITCH", // Minecraft 1.?
|
||||
"WITHER", // Minecraft 1.?
|
||||
"ZOMBIE" // Minecraft 1.?
|
||||
);
|
||||
|
||||
// -------------------------------------------- //
|
||||
// INTEGRATION: HeroChat
|
||||
// -------------------------------------------- //
|
||||
|
||||
// I you are using the chat plugin HeroChat Factions ship with built in integration.
|
||||
// The two channels Faction and Allies will be created.
|
||||
// Their data is actually stored right here in the factions config.
|
||||
// NOTE: HeroChat will create it's own database files for these two channels.
|
||||
// You should ignore those and edit the channel settings from here.
|
||||
// Those HeroChat channel database files aren't read for the Faction and Allies channels.
|
||||
|
||||
// The Faction Channel
|
||||
public String herochatFactionName = "Faction";
|
||||
public String herochatFactionNick = "F";
|
||||
public String herochatFactionFormat = "{color}[&l{nick}&r{color} &l{factions_roleprefix}&r{color}{factions_title|rp}{sender}{color}] &f{msg}";
|
||||
public ChatColor herochatFactionColor = ChatColor.GREEN;
|
||||
public int herochatFactionDistance = 0;
|
||||
public boolean herochatFactionIsShortcutAllowed = false;
|
||||
public boolean herochatFactionCrossWorld = true;
|
||||
public boolean herochatFactionMuted = false;
|
||||
public Set<String> herochatFactionWorlds = new HashSet<String>();
|
||||
|
||||
// The Allies Channel
|
||||
public String herochatAlliesName = "Allies";
|
||||
public String herochatAlliesNick = "A";
|
||||
public String herochatAlliesFormat = "{color}[&l{nick}&r&f {factions_relcolor}&l{factions_roleprefix}&r{factions_relcolor}{factions_name|rp}{sender}{color}] &f{msg}";
|
||||
public ChatColor herochatAlliesColor = ChatColor.DARK_PURPLE;
|
||||
public int herochatAlliesDistance = 0;
|
||||
public boolean herochatAlliesIsShortcutAllowed = false;
|
||||
public boolean herochatAlliesCrossWorld = true;
|
||||
public boolean herochatAlliesMuted = false;
|
||||
public Set<String> herochatAlliesWorlds = new HashSet<String>();
|
||||
|
||||
// -------------------------------------------- //
|
||||
// INTEGRATION: LWC
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Do you need faction build rights in the territory to create an LWC protection there?
|
||||
public boolean lwcMustHaveBuildRightsToCreate = true;
|
||||
|
||||
// The config option above does not handle situations where a player creates an LWC protection in Faction territory and then leaves the faction.
|
||||
// The player would then have an LWC protection in a territory where they can not build.
|
||||
// Set this config option to true to enable an automatic removal feature.
|
||||
// LWC protections that couldn't be created will be removed on an attempt to open them by any player.
|
||||
public boolean lwcRemoveIfNoBuildRights = false;
|
||||
|
||||
// WARN: Experimental and semi buggy.
|
||||
// If you change this to true: alien LWC protections will be removed upon using /f set.
|
||||
public Map<EventFactionsChunkChangeType, Boolean> lwcRemoveOnChange = MUtil.map(
|
||||
EventFactionsChunkChangeType.BUY, false, // when claiming from wilderness
|
||||
EventFactionsChunkChangeType.SELL, false, // when selling back to wilderness
|
||||
EventFactionsChunkChangeType.CONQUER, false, // when claiming from another player faction
|
||||
EventFactionsChunkChangeType.PILLAGE, false // when unclaiming (to wilderness) from another player faction
|
||||
);
|
||||
|
||||
// -------------------------------------------- //
|
||||
// INTEGRATION: ECONOMY
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Should economy features be enabled?
|
||||
// This requires that you have the external plugin called "Vault" installed.
|
||||
public boolean econEnabled = true;
|
||||
|
||||
// A money reward per chunk. This reward is divided among the players in the faction.
|
||||
// You set the time inbetween each reward almost at the top of this config file. (taskEconLandRewardMinutes)
|
||||
public double econLandReward = 0.00;
|
||||
|
||||
// When paying a cost you may specify an account that should receive the money here.
|
||||
// Per default "" the money is just destroyed.
|
||||
public String econUniverseAccount = "";
|
||||
|
||||
// What is the price per chunk when using /f set?
|
||||
public Map<EventFactionsChunkChangeType, Double> econChunkCost = MUtil.map(
|
||||
EventFactionsChunkChangeType.BUY, 1.0, // when claiming from wilderness
|
||||
EventFactionsChunkChangeType.SELL, 0.0, // when selling back to wilderness
|
||||
EventFactionsChunkChangeType.CONQUER, 0.0, // when claiming from another player faction
|
||||
EventFactionsChunkChangeType.PILLAGE, 0.0 // when unclaiming (to wilderness) from another player faction
|
||||
);
|
||||
|
||||
// What is the price to create a faction?
|
||||
public double econCostCreate = 100.0;
|
||||
|
||||
// And so on and so forth ... you get the idea.
|
||||
public double econCostSethome = 0.0;
|
||||
public double econCostJoin = 0.0;
|
||||
public double econCostLeave = 0.0;
|
||||
public double econCostKick = 0.0;
|
||||
public double econCostInvite = 0.0;
|
||||
public double econCostDeinvite = 0.0;
|
||||
public double econCostHome = 0.0;
|
||||
public double econCostName = 0.0;
|
||||
public double econCostDescription = 0.0;
|
||||
public double econCostTitle = 0.0;
|
||||
public double econCostFlag = 0.0;
|
||||
|
||||
public Map<Rel, Double> econRelCost = MUtil.map(
|
||||
Rel.ENEMY, 0.0,
|
||||
Rel.ALLY, 0.0,
|
||||
Rel.TRUCE, 0.0,
|
||||
Rel.NEUTRAL, 0.0
|
||||
);
|
||||
|
||||
// Should the faction bank system be enabled?
|
||||
// This enables the command /f money.
|
||||
public boolean bankEnabled = true;
|
||||
|
||||
// That costs should the faciton bank take care of?
|
||||
// If you set this to false the player executing the command will pay instead.
|
||||
public boolean bankFactionPaysCosts = true;
|
||||
public boolean bankFactionPaysLandCosts = true;
|
||||
|
||||
}
|
33
src/com/massivecraft/factions/entity/MConfColl.java
Normal file
33
src/com/massivecraft/factions/entity/MConfColl.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import com.massivecraft.factions.Const;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.massivecore.MassiveCore;
|
||||
import com.massivecraft.massivecore.store.Coll;
|
||||
import com.massivecraft.massivecore.store.MStore;
|
||||
|
||||
public class MConfColl extends Coll<MConf>
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static MConfColl i = new MConfColl();
|
||||
public static MConfColl get() { return i; }
|
||||
private MConfColl()
|
||||
{
|
||||
super(Const.COLLECTION_MCONF, MConf.class, MStore.getDb(), Factions.get());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
MConf.i = this.get(MassiveCore.INSTANCE, true);
|
||||
}
|
||||
|
||||
}
|
296
src/com/massivecraft/factions/entity/MFlag.java
Normal file
296
src/com/massivecraft/factions/entity/MFlag.java
Normal file
@ -0,0 +1,296 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.massivecraft.factions.event.EventFactionsCreateFlags;
|
||||
import com.massivecraft.massivecore.PredictateIsRegistered;
|
||||
import com.massivecraft.massivecore.Prioritized;
|
||||
import com.massivecraft.massivecore.Registerable;
|
||||
import com.massivecraft.massivecore.collections.MassiveList;
|
||||
import com.massivecraft.massivecore.store.Entity;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
|
||||
public class MFlag extends Entity<MFlag> implements Prioritized, Registerable
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// CONSTANTS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public final static transient String ID_OPEN = "open";
|
||||
public final static transient String ID_MONSTERS = "monsters";
|
||||
public final static transient String ID_POWERLOSS = "powerloss";
|
||||
public final static transient String ID_PVP = "pvp";
|
||||
public final static transient String ID_FRIENDLYFIRE = "friendlyfire";
|
||||
public final static transient String ID_EXPLOSIONS = "explosions";
|
||||
public final static transient String ID_OFFLINEEXPLOSIONS = "offlineexplosions";
|
||||
public final static transient String ID_FIRESPREAD = "firespread";
|
||||
public final static transient String ID_ENDERGRIEF = "endergrief";
|
||||
public final static transient String ID_PERMANENT = "permanent";
|
||||
public final static transient String ID_PEACEFUL = "peaceful";
|
||||
public final static transient String ID_INFPOWER = "infpower";
|
||||
|
||||
public final static transient int PRIORITY_OPEN = 1000;
|
||||
public final static transient int PRIORITY_MONSTERS = 2000;
|
||||
public final static transient int PRIORITY_POWERLOSS = 3000;
|
||||
public final static transient int PRIORITY_PVP = 4000;
|
||||
public final static transient int PRIORITY_FRIENDLYFIRE = 5000;
|
||||
public final static transient int PRIORITY_EXPLOSIONS = 6000;
|
||||
public final static transient int PRIORITY_OFFLINEEXPLOSIONS = 7000;
|
||||
public final static transient int PRIORITY_FIRESPREAD = 8000;
|
||||
public final static transient int PRIORITY_ENDERGRIEF = 9000;
|
||||
public final static transient int PRIORITY_PERMANENT = 10000;
|
||||
public final static transient int PRIORITY_PEACEFUL = 11000;
|
||||
public final static transient int PRIORITY_INFPOWER = 12000;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// META: CORE
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static MFlag get(Object oid)
|
||||
{
|
||||
return MFlagColl.get().get(oid);
|
||||
}
|
||||
|
||||
public static List<MFlag> getAll()
|
||||
{
|
||||
return getAll(false);
|
||||
}
|
||||
|
||||
public static List<MFlag> getAll(boolean isAsync)
|
||||
{
|
||||
setupStandardFlags();
|
||||
new EventFactionsCreateFlags(isAsync).run();
|
||||
return MFlagColl.get().getAll(PredictateIsRegistered.get());
|
||||
}
|
||||
|
||||
public static void setupStandardFlags()
|
||||
{
|
||||
getFlagOpen();
|
||||
getFlagMonsters();
|
||||
getFlagPowerloss();
|
||||
getFlagPvp();
|
||||
getFlagFriendlyire();
|
||||
getFlagExplosions();
|
||||
getFlagOfflineexplosions();
|
||||
getFlagFirespread();
|
||||
getFlagEndergrief();
|
||||
getFlagPermanent();
|
||||
getFlagPeaceful();
|
||||
getFlagInfpower();
|
||||
}
|
||||
|
||||
public static MFlag getFlagOpen() { return getCreative(PRIORITY_OPEN, ID_OPEN, ID_OPEN, "Can the faction be joined without an invite?", "Anyone can join. No invite required.", "An invite is required to join.", false, true, true); }
|
||||
public static MFlag getFlagMonsters() { return getCreative(PRIORITY_MONSTERS, ID_MONSTERS, ID_MONSTERS, "Can monsters spawn in this territory?", "Monsters can spawn in this territory.", "Monsters can NOT spawn in this territory.", false, true, true); }
|
||||
public static MFlag getFlagPowerloss() { return getCreative(PRIORITY_POWERLOSS, ID_POWERLOSS, ID_POWERLOSS, "Is power lost on death in this territory?", "Power is lost on death in this territory.", "Power is NOT lost on death in this territory.", true, false, true); }
|
||||
public static MFlag getFlagPvp() { return getCreative(PRIORITY_PVP, ID_PVP, ID_PVP, "Can you PVP in territory?", "You can PVP in this territory.", "You can NOT PVP in this territory.", true, false, true); }
|
||||
public static MFlag getFlagFriendlyire() { return getCreative(PRIORITY_FRIENDLYFIRE, ID_FRIENDLYFIRE, ID_FRIENDLYFIRE, "Can friends hurt eachother in this territory?", "Friends can hurt eachother in this territory.", "Friends can NOT hurt eachother in this territory.", false, false, true); }
|
||||
public static MFlag getFlagExplosions() { return getCreative(PRIORITY_EXPLOSIONS, ID_EXPLOSIONS, ID_EXPLOSIONS, "Can explosions occur in this territory?", "Explosions can occur in this territory.", "Explosions can NOT occur in this territory.", true, false, true); }
|
||||
public static MFlag getFlagOfflineexplosions() { return getCreative(PRIORITY_OFFLINEEXPLOSIONS, ID_OFFLINEEXPLOSIONS, ID_OFFLINEEXPLOSIONS, "Can explosions occur if faction is offline?", "Explosions can occur if faction is offline.", "Explosions can NOT occur if faction is offline.", false, false, true); }
|
||||
public static MFlag getFlagFirespread() { return getCreative(PRIORITY_FIRESPREAD, ID_FIRESPREAD, ID_FIRESPREAD, "Can fire spread in territory?", "Fire can spread in this territory.", "Fire can NOT spread in this territory.", true, false, true); }
|
||||
public static MFlag getFlagEndergrief() { return getCreative(PRIORITY_ENDERGRIEF, ID_ENDERGRIEF, ID_ENDERGRIEF, "Can endermen grief in this territory?", "Endermen can grief in this territory", "Endermen can NOT grief in this territory.", false, false, true); }
|
||||
public static MFlag getFlagPermanent() { return getCreative(PRIORITY_PERMANENT, ID_PERMANENT, ID_PERMANENT, "Is the faction immune to deletion?", "The faction can NOT be deleted.", "The faction can be deleted.", false, false, true); }
|
||||
public static MFlag getFlagPeaceful() { return getCreative(PRIORITY_PEACEFUL, ID_PEACEFUL, ID_PEACEFUL, "Is the faction in truce with everyone?", "The faction is in truce with everyone.", "The faction relations work as usual.", false, false, true); }
|
||||
public static MFlag getFlagInfpower() { return getCreative(PRIORITY_INFPOWER, ID_INFPOWER, ID_INFPOWER, "Does the faction have infinite power?", "The faction has infinite power.", "The faction power works as usual.", false, false, true); }
|
||||
|
||||
public static MFlag getCreative(int priority, String id, String name, String desc, String descYes, String descNo, boolean standard, boolean editable, boolean visible)
|
||||
{
|
||||
MFlag ret = MFlagColl.get().get(id, false);
|
||||
if (ret != null)
|
||||
{
|
||||
ret.setRegistered(true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = new MFlag(priority, name, desc, descYes, descNo, standard, editable, visible);
|
||||
MFlagColl.get().attach(ret, id);
|
||||
ret.setRegistered(true);
|
||||
ret.sync();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public MFlag load(MFlag that)
|
||||
{
|
||||
this.priority = that.priority;
|
||||
this.name = that.name;
|
||||
this.desc = that.desc;
|
||||
this.descYes = that.descYes;
|
||||
this.descNo = that.descNo;
|
||||
this.standard = that.standard;
|
||||
this.editable = that.editable;
|
||||
this.visible = that.visible;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// TRANSIENT FIELDS (Registered)
|
||||
// -------------------------------------------- //
|
||||
|
||||
private transient boolean registered = false;
|
||||
public boolean isRegistered() { return this.registered; }
|
||||
public void setRegistered(boolean registered) { this.registered = registered; }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELDS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// The sort priority. Low values appear first in sorted lists.
|
||||
// 1 is high up, 99999 is far down.
|
||||
// Standard Faction flags use "thousand values" like 1000, 2000, 3000 etc to allow adding new flags inbetween.
|
||||
// So 1000 might sound like a lot but it's actually the priority for the first flag.
|
||||
private int priority = 0;
|
||||
@Override public int getPriority() { return this.priority; }
|
||||
public MFlag setPriority(int priority) { this.priority = priority; this.changed(); return this; }
|
||||
|
||||
// The name of the flag. According to standard it should be fully lowercase just like the flag id.
|
||||
// In fact the name and the id of all standard flags are the same.
|
||||
// I just added the name in case anyone feel like renaming their flags for some reason.
|
||||
// Example: "monsters"
|
||||
private String name = "defaultName";
|
||||
public String getName() { return this.name; }
|
||||
public MFlag setName(String name) { this.name = name; this.changed(); return this; }
|
||||
|
||||
// The flag function described as a question.
|
||||
// Example: "Can monsters spawn in this territory?"
|
||||
private String desc = "defaultDesc";
|
||||
public String getDesc() { return this.desc; }
|
||||
public MFlag setDesc(String desc) { this.desc = desc; this.changed(); return this; }
|
||||
|
||||
// The flag function described when true.
|
||||
// Example: "Monsters can spawn in this territory."
|
||||
private String descYes = "defaultDescYes";
|
||||
public String getDescYes() { return this.descYes; }
|
||||
public MFlag setDescYes(String descYes) { this.descYes = descYes; this.changed(); return this; }
|
||||
|
||||
// The flag function described when false.
|
||||
// Example: "Monsters can NOT spawn in this territory."
|
||||
private String descNo = "defaultDescNo";
|
||||
public String getDescNo() { return this.descNo; }
|
||||
public MFlag setDescNo(String descNo) { this.descNo = descNo; this.changed(); return this; }
|
||||
|
||||
// What is the standard (aka default) flag value?
|
||||
// This value will be set for factions from the beginning.
|
||||
// Example: false (per default monsters do not spawn in faction territory)
|
||||
private boolean standard = true;
|
||||
public boolean isStandard() { return this.standard; }
|
||||
public MFlag setStandard(boolean standard) { this.standard = standard; this.changed(); return this; }
|
||||
|
||||
// Is this flag editable by players?
|
||||
// With this we mean standard non administrator players.
|
||||
// All flags can be changed using /f admin.
|
||||
// Example: true (if players want to turn mob spawning on I guess they should be able to)
|
||||
private boolean editable = false;
|
||||
public boolean isEditable() { return this.editable; }
|
||||
public MFlag setEditable(boolean editable) { this.editable = editable; this.changed(); return this; }
|
||||
|
||||
// Is this flag visible to players?
|
||||
// With this we mean standard non administrator players.
|
||||
// All flags can be seen using /f admin.
|
||||
// Some flags can be rendered meaningless by settings in Factions or external plugins.
|
||||
// Say we set "editable" to false and "standard" to true for the "open" flag to force all factions being open.
|
||||
// In such case we might want to hide the open flag by setting "visible" false.
|
||||
// If it can't be changed, why bother showing it?
|
||||
// Example: true (yeah we need to see this flag)
|
||||
private boolean visible = true;
|
||||
public boolean isVisible() { return this.visible; }
|
||||
public MFlag setVisible(boolean visible) { this.visible = visible; this.changed(); return this; }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
public MFlag()
|
||||
{
|
||||
// No argument constructor for GSON
|
||||
}
|
||||
|
||||
public MFlag(int priority, String name, String desc, String descYes, String descNo, boolean standard, boolean editable, boolean visible)
|
||||
{
|
||||
this.priority = priority;
|
||||
this.name = name;
|
||||
this.desc = desc;
|
||||
this.descYes = descYes;
|
||||
this.descNo = descNo;
|
||||
this.standard = standard;
|
||||
this.editable = editable;
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// EXTRAS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public boolean isInteresting(boolean value)
|
||||
{
|
||||
if ( ! this.isVisible()) return false;
|
||||
if (this.isEditable()) return true;
|
||||
return this.isStandard() != value;
|
||||
}
|
||||
|
||||
public String getStateDesc(boolean value, boolean withValue, boolean monospaceValue, boolean withName, boolean withDesc, boolean specificDesc)
|
||||
{
|
||||
List<String> parts = new MassiveList<String>();
|
||||
|
||||
if (withValue)
|
||||
{
|
||||
if (monospaceValue)
|
||||
{
|
||||
parts.add(Txt.parse(value ? "<g>YES" : "<b>NOO"));
|
||||
}
|
||||
else
|
||||
{
|
||||
parts.add(Txt.parse(value ? "<g>YES" : "<b>NO"));
|
||||
}
|
||||
}
|
||||
|
||||
if (withName)
|
||||
{
|
||||
String nameFormat;
|
||||
if ( ! this.isVisible())
|
||||
{
|
||||
nameFormat = "<silver>%s";
|
||||
}
|
||||
else if (this.isEditable())
|
||||
{
|
||||
nameFormat = "<pink>%s";
|
||||
}
|
||||
else
|
||||
{
|
||||
nameFormat = "<aqua>%s";
|
||||
}
|
||||
String name = this.getName();
|
||||
String nameDesc = Txt.parse(nameFormat, name);
|
||||
parts.add(nameDesc);
|
||||
}
|
||||
|
||||
if (withDesc)
|
||||
{
|
||||
String desc;
|
||||
if (specificDesc)
|
||||
{
|
||||
desc = value ? this.getDescYes() : this.getDescNo();
|
||||
}
|
||||
else
|
||||
{
|
||||
desc = this.getDesc();
|
||||
}
|
||||
String descDesc = Txt.parse("<i>%s", desc);
|
||||
parts.add(descDesc);
|
||||
}
|
||||
|
||||
return Txt.implode(parts, " ");
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getStateInfo(boolean value, boolean withDesc)
|
||||
{
|
||||
return this.getStateDesc(value, true, true, true, true, false);
|
||||
}
|
||||
|
||||
}
|
51
src/com/massivecraft/factions/entity/MFlagColl.java
Normal file
51
src/com/massivecraft/factions/entity/MFlagColl.java
Normal file
@ -0,0 +1,51 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.massivecraft.factions.Const;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.massivecore.PriorityComparator;
|
||||
import com.massivecraft.massivecore.store.Coll;
|
||||
import com.massivecraft.massivecore.store.MStore;
|
||||
|
||||
public class MFlagColl extends Coll<MFlag>
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static MFlagColl i = new MFlagColl();
|
||||
public static MFlagColl get() { return i; }
|
||||
private MFlagColl()
|
||||
{
|
||||
super(Const.COLLECTION_MFLAG, MFlag.class, MStore.getDb(), Factions.get(), false, false, true, null, PriorityComparator.get());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
MFlag.setupStandardFlags();
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// EXTRAS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public List<MFlag> getAll(boolean registered)
|
||||
{
|
||||
List<MFlag> ret = new ArrayList<MFlag>();
|
||||
for (MFlag mflag : this.getAll())
|
||||
{
|
||||
if (mflag.isRegistered() != registered) continue;
|
||||
ret.add(mflag);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
407
src/com/massivecraft/factions/entity/MPerm.java
Normal file
407
src/com/massivecraft/factions/entity/MPerm.java
Normal file
@ -0,0 +1,407 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.Perm;
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.TerritoryAccess;
|
||||
import com.massivecraft.factions.event.EventFactionsCreatePerms;
|
||||
import com.massivecraft.massivecore.PredictateIsRegistered;
|
||||
import com.massivecraft.massivecore.Prioritized;
|
||||
import com.massivecraft.massivecore.Registerable;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.store.Entity;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
|
||||
public class MPerm extends Entity<MPerm> implements Prioritized, Registerable
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// CONSTANTS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public final static transient String ID_BUILD = "build";
|
||||
public final static transient String ID_PAINBUILD = "painbuild";
|
||||
public final static transient String ID_DOOR = "door";
|
||||
public final static transient String ID_BUTTON = "button";
|
||||
public final static transient String ID_LEVER = "lever";
|
||||
public final static transient String ID_CONTAINER = "container";
|
||||
|
||||
public final static transient String ID_NAME = "name";
|
||||
public final static transient String ID_DESC = "desc";
|
||||
public final static transient String ID_MOTD = "motd";
|
||||
public final static transient String ID_INVITE = "invite";
|
||||
public final static transient String ID_KICK = "kick";
|
||||
public final static transient String ID_TITLE = "title";
|
||||
public final static transient String ID_HOME = "home";
|
||||
public final static transient String ID_SETHOME = "sethome";
|
||||
public final static transient String ID_DEPOSIT = "deposit";
|
||||
public final static transient String ID_WITHDRAW = "withdraw";
|
||||
public final static transient String ID_TERRITORY = "territory";
|
||||
public final static transient String ID_ACCESS = "access";
|
||||
public final static transient String ID_CLAIMNEAR = "claimnear";
|
||||
public final static transient String ID_REL = "rel";
|
||||
public final static transient String ID_DISBAND = "disband";
|
||||
public final static transient String ID_FLAGS = "flags";
|
||||
public final static transient String ID_PERMS = "perms";
|
||||
|
||||
public final static transient int PRIORITY_BUILD = 1000;
|
||||
public final static transient int PRIORITY_PAINBUILD = 2000;
|
||||
public final static transient int PRIORITY_DOOR = 3000;
|
||||
public final static transient int PRIORITY_BUTTON = 4000;
|
||||
public final static transient int PRIORITY_LEVER = 5000;
|
||||
public final static transient int PRIORITY_CONTAINER = 6000;
|
||||
|
||||
public final static transient int PRIORITY_NAME = 7000;
|
||||
public final static transient int PRIORITY_DESC = 8000;
|
||||
public final static transient int PRIORITY_MOTD = 9000;
|
||||
public final static transient int PRIORITY_INVITE = 10000;
|
||||
public final static transient int PRIORITY_KICK = 11000;
|
||||
public final static transient int PRIORITY_TITLE = 12000;
|
||||
public final static transient int PRIORITY_HOME = 13000;
|
||||
public final static transient int PRIORITY_SETHOME = 14000;
|
||||
public final static transient int PRIORITY_DEPOSIT = 15000;
|
||||
public final static transient int PRIORITY_WITHDRAW = 16000;
|
||||
public final static transient int PRIORITY_TERRITORY = 17000;
|
||||
public final static transient int PRIORITY_ACCESS = 18000;
|
||||
public final static transient int PRIORITY_CLAIMNEAR = 19000;
|
||||
public final static transient int PRIORITY_REL = 20000;
|
||||
public final static transient int PRIORITY_DISBAND = 21000;
|
||||
public final static transient int PRIORITY_FLAGS = 22000;
|
||||
public final static transient int PRIORITY_PERMS = 23000;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// META: CORE
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static MPerm get(Object oid)
|
||||
{
|
||||
return MPermColl.get().get(oid);
|
||||
}
|
||||
|
||||
public static List<MPerm> getAll()
|
||||
{
|
||||
return getAll(false);
|
||||
}
|
||||
|
||||
public static List<MPerm> getAll(boolean isAsync)
|
||||
{
|
||||
setupStandardPerms();
|
||||
new EventFactionsCreatePerms().run();
|
||||
|
||||
return MPermColl.get().getAll(PredictateIsRegistered.get());
|
||||
}
|
||||
|
||||
public static void setupStandardPerms()
|
||||
{
|
||||
getPermBuild();
|
||||
getPermPainbuild();
|
||||
getPermDoor();
|
||||
getPermButton();
|
||||
getPermLever();
|
||||
getPermContainer();
|
||||
|
||||
getPermName();
|
||||
getPermDesc();
|
||||
getPermMotd();
|
||||
getPermInvite();
|
||||
getPermKick();
|
||||
getPermTitle();
|
||||
getPermHome();
|
||||
getPermSethome();
|
||||
getPermDeposit();
|
||||
getPermWithdraw();
|
||||
getPermTerritory();
|
||||
getPermAccess();
|
||||
getPermClaimnear();
|
||||
getPermRel();
|
||||
getPermDisband();
|
||||
getPermFlags();
|
||||
getPermPerms();
|
||||
}
|
||||
|
||||
public static MPerm getPermBuild() { return getCreative(PRIORITY_BUILD, ID_BUILD, ID_BUILD, "edit the terrain", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER), true, true, true); }
|
||||
public static MPerm getPermPainbuild() { return getCreative(PRIORITY_PAINBUILD, ID_PAINBUILD, ID_PAINBUILD, "edit, take damage", new LinkedHashSet<Rel>(), true, true, true); }
|
||||
public static MPerm getPermDoor() { return getCreative(PRIORITY_DOOR, ID_DOOR, ID_DOOR, "use doors", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), true, true, true); }
|
||||
public static MPerm getPermButton() { return getCreative(PRIORITY_BUTTON, ID_BUTTON, ID_BUTTON, "use stone buttons", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), true, true, true); }
|
||||
public static MPerm getPermLever() { return getCreative(PRIORITY_LEVER, ID_LEVER, ID_LEVER, "use levers", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), true, true, true); }
|
||||
public static MPerm getPermContainer() { return getCreative(PRIORITY_CONTAINER, ID_CONTAINER, ID_CONTAINER, "use containers", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER), true, true, true); }
|
||||
|
||||
public static MPerm getPermName() { return getCreative(PRIORITY_NAME, ID_NAME, ID_NAME, "set name", MUtil.set(Rel.LEADER), false, true, true); }
|
||||
public static MPerm getPermDesc() { return getCreative(PRIORITY_DESC, ID_DESC, ID_DESC, "set description", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
|
||||
public static MPerm getPermMotd() { return getCreative(PRIORITY_MOTD, ID_MOTD, ID_MOTD, "set motd", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
|
||||
public static MPerm getPermInvite() { return getCreative(PRIORITY_INVITE, ID_INVITE, ID_INVITE, "invite players", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
|
||||
public static MPerm getPermKick() { return getCreative(PRIORITY_KICK, ID_KICK, ID_KICK, "kick members", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
|
||||
public static MPerm getPermTitle() { return getCreative(PRIORITY_TITLE, ID_TITLE, ID_TITLE, "set titles", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
|
||||
public static MPerm getPermHome() { return getCreative(PRIORITY_HOME, ID_HOME, ID_HOME, "teleport home", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), false, true, true); }
|
||||
public static MPerm getPermSethome() { return getCreative(PRIORITY_SETHOME, ID_SETHOME, ID_SETHOME, "set the home", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
|
||||
public static MPerm getPermDeposit() { return getCreative(PRIORITY_DEPOSIT, ID_DEPOSIT, ID_DEPOSIT, "deposit money", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY), false, false, false); } // non editable, non visible.
|
||||
public static MPerm getPermWithdraw() { return getCreative(PRIORITY_WITHDRAW, ID_WITHDRAW, ID_WITHDRAW, "withdraw money", MUtil.set(Rel.LEADER), false, true, true); }
|
||||
public static MPerm getPermTerritory() { return getCreative(PRIORITY_TERRITORY, ID_TERRITORY, ID_TERRITORY, "claim or unclaim", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
|
||||
public static MPerm getPermAccess() { return getCreative(PRIORITY_ACCESS, ID_ACCESS, ID_ACCESS, "grant territory", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
|
||||
public static MPerm getPermClaimnear() { return getCreative(PRIORITY_CLAIMNEAR, ID_CLAIMNEAR, ID_CLAIMNEAR, "claim nearby", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), false, false, false); } // non editable, non visible.
|
||||
public static MPerm getPermRel() { return getCreative(PRIORITY_REL, ID_REL, ID_REL, "change relations", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
|
||||
public static MPerm getPermDisband() { return getCreative(PRIORITY_DISBAND, ID_DISBAND, ID_DISBAND, "disband the faction", MUtil.set(Rel.LEADER), false, true, true); }
|
||||
public static MPerm getPermFlags() { return getCreative(PRIORITY_FLAGS, ID_FLAGS, ID_FLAGS, "manage flags", MUtil.set(Rel.LEADER), false, true, true); }
|
||||
public static MPerm getPermPerms() { return getCreative(PRIORITY_PERMS, ID_PERMS, ID_PERMS, "manage permissions", MUtil.set(Rel.LEADER), false, true, true); }
|
||||
|
||||
public static MPerm getCreative(int priority, String id, String name, String desc, Set<Rel> standard, boolean territory, boolean editable, boolean visible)
|
||||
{
|
||||
MPerm ret = MPermColl.get().get(id, false);
|
||||
if (ret != null)
|
||||
{
|
||||
ret.setRegistered(true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = new MPerm(priority, name, desc, standard, territory, editable, visible);
|
||||
MPermColl.get().attach(ret, id);
|
||||
ret.setRegistered(true);
|
||||
ret.sync();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public MPerm load(MPerm that)
|
||||
{
|
||||
this.priority = that.priority;
|
||||
this.name = that.name;
|
||||
this.desc = that.desc;
|
||||
this.standard = that.standard;
|
||||
this.territory = that.territory;
|
||||
this.editable = that.editable;
|
||||
this.visible = that.visible;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// TRANSIENT FIELDS (Registered)
|
||||
// -------------------------------------------- //
|
||||
|
||||
private transient boolean registered = false;
|
||||
public boolean isRegistered() { return this.registered; }
|
||||
public void setRegistered(boolean registered) { this.registered = registered; }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELDS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// The sort priority. Low values appear first in sorted lists.
|
||||
// 1 is high up, 99999 is far down.
|
||||
// Standard Faction perms use "thousand values" like 1000, 2000, 3000 etc to allow adding new perms inbetween.
|
||||
// So 1000 might sound like a lot but it's actually the priority for the first perm.
|
||||
private int priority = 0;
|
||||
@Override public int getPriority() { return this.priority; }
|
||||
public MPerm setPriority(int priority) { this.priority = priority; this.changed(); return this; }
|
||||
|
||||
// The name of the perm. According to standard it should be fully lowercase just like the perm id.
|
||||
// In fact the name and the id of all standard perms are the same.
|
||||
// I just added the name in case anyone feel like renaming their perms for some reason.
|
||||
// Example: "build"
|
||||
private String name = "defaultName";
|
||||
public String getName() { return this.name; }
|
||||
public MPerm setName(String name) { this.name = name; this.changed(); return this; }
|
||||
|
||||
// The perm function described as an "order".
|
||||
// The desc should match the format:
|
||||
// "You are not allowed to X."
|
||||
// "You are not allowed to edit the terrain."
|
||||
// Example: "edit the terrain"
|
||||
private String desc = "defaultDesc";
|
||||
public String getDesc() { return this.desc; }
|
||||
public MPerm setDesc(String desc) { this.desc = desc; this.changed(); return this; }
|
||||
|
||||
// What is the standard (aka default) perm value?
|
||||
// This value will be set for factions from the beginning.
|
||||
// Example: ... set of relations ...
|
||||
private Set<Rel> standard = new LinkedHashSet<Rel>();
|
||||
public Set<Rel> getStandard() { return this.standard; }
|
||||
public MPerm setStandard(Set<Rel> standard) { this.standard = standard; this.changed(); return this; }
|
||||
|
||||
// Is this a territory perm meaning it has to do with territory construction, modification or interaction?
|
||||
// True Examples: build, container, door, lever etc.
|
||||
// False Examples: name, invite, home, sethome, deposit, withdraw etc.
|
||||
private boolean territory = false;
|
||||
public boolean isTerritory() { return this.territory; }
|
||||
public MPerm setTerritory(boolean territory) { this.territory = territory; this.changed(); return this; }
|
||||
|
||||
// Is this perm editable by players?
|
||||
// With this we mean standard non administrator players.
|
||||
// All perms can be changed using /f admin.
|
||||
// Example: true (all perms are editable by default)
|
||||
private boolean editable = false;
|
||||
public boolean isEditable() { return this.editable; }
|
||||
public MPerm setEditable(boolean editable) { this.editable = editable; this.changed(); return this; }
|
||||
|
||||
// Is this perm visible to players?
|
||||
// With this we mean standard non administrator players.
|
||||
// All perms can be seen using /f admin.
|
||||
// Some perms can be rendered meaningless by settings in Factions or external plugins.
|
||||
// Say we set "editable" to false.
|
||||
// In such case we might want to hide the perm by setting "visible" false.
|
||||
// If it can't be changed, why bother showing it?
|
||||
// Example: true (yeah we need to see this permission)
|
||||
private boolean visible = true;
|
||||
public boolean isVisible() { return this.visible; }
|
||||
public MPerm setVisible(boolean visible) { this.visible = visible; this.changed(); return this; }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
public MPerm()
|
||||
{
|
||||
// No argument constructor for GSON
|
||||
}
|
||||
|
||||
public MPerm(int priority, String name, String desc, Set<Rel> standard, boolean territory, boolean editable, boolean visible)
|
||||
{
|
||||
this.priority = priority;
|
||||
this.name = name;
|
||||
this.desc = desc;
|
||||
this.standard = standard;
|
||||
this.territory = territory;
|
||||
this.editable = editable;
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// EXTRAS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public String createDeniedMessage(MPlayer mplayer, Faction hostFaction)
|
||||
{
|
||||
// Null Check
|
||||
if (mplayer == null) throw new NullPointerException("mplayer");
|
||||
if (hostFaction == null) throw new NullPointerException("hostFaction");
|
||||
|
||||
String ret = Txt.parse("%s<b> does not allow you to %s<b>.", hostFaction.describeTo(mplayer, true), this.getDesc());
|
||||
|
||||
Player player = mplayer.getPlayer();
|
||||
if (player != null && Perm.ADMIN.has(player))
|
||||
{
|
||||
ret += Txt.parse("\n<i>You can bypass by using " + Factions.get().getOuterCmdFactions().cmdFactionsAdmin.getUseageTemplate(false));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean has(Faction faction, Faction hostFaction)
|
||||
{
|
||||
// Null Check
|
||||
if (faction == null) throw new NullPointerException("faction");
|
||||
if (hostFaction == null) throw new NullPointerException("hostFaction");
|
||||
|
||||
Rel rel = faction.getRelationTo(hostFaction);
|
||||
return hostFaction.isPermitted(this, rel);
|
||||
}
|
||||
|
||||
public boolean has(MPlayer mplayer, Faction hostFaction, boolean verboose)
|
||||
{
|
||||
// Null Check
|
||||
if (mplayer == null) throw new NullPointerException("mplayer");
|
||||
if (hostFaction == null) throw new NullPointerException("hostFaction");
|
||||
|
||||
if (mplayer.isUsingAdminMode()) return true;
|
||||
|
||||
Rel rel = mplayer.getRelationTo(hostFaction);
|
||||
if (hostFaction.isPermitted(this, rel)) return true;
|
||||
|
||||
if (verboose) mplayer.sendMessage(this.createDeniedMessage(mplayer, hostFaction));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean has(MPlayer mplayer, PS ps, boolean verboose)
|
||||
{
|
||||
// Null Check
|
||||
if (mplayer == null) throw new NullPointerException("mplayer");
|
||||
if (ps == null) throw new NullPointerException("ps");
|
||||
|
||||
if (mplayer.isUsingAdminMode()) return true;
|
||||
|
||||
TerritoryAccess ta = BoardColl.get().getTerritoryAccessAt(ps);
|
||||
Faction hostFaction = ta.getHostFaction();
|
||||
|
||||
if (this.isTerritory())
|
||||
{
|
||||
Boolean hasTerritoryAccess = ta.hasTerritoryAccess(mplayer);
|
||||
if (hasTerritoryAccess != null)
|
||||
{
|
||||
if (verboose && !hasTerritoryAccess)
|
||||
{
|
||||
mplayer.sendMessage(this.createDeniedMessage(mplayer, hostFaction));
|
||||
}
|
||||
return hasTerritoryAccess;
|
||||
}
|
||||
}
|
||||
|
||||
return this.has(mplayer, hostFaction, verboose);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UTIL: ASCII
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static String getStateHeaders()
|
||||
{
|
||||
String ret = "";
|
||||
for (Rel rel : Rel.values())
|
||||
{
|
||||
ret += rel.getColor().toString();
|
||||
ret += rel.toString().substring(0, 3);
|
||||
ret += " ";
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String getStateInfo(Set<Rel> value, boolean withDesc)
|
||||
{
|
||||
String ret = "";
|
||||
|
||||
for (Rel rel : Rel.values())
|
||||
{
|
||||
if (value.contains(rel))
|
||||
{
|
||||
ret += "<g>YES";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += "<b>NOO";
|
||||
}
|
||||
ret += " ";
|
||||
}
|
||||
|
||||
String color = "<aqua>";
|
||||
if (!this.isVisible())
|
||||
{
|
||||
color = "<silver>";
|
||||
}
|
||||
else if (this.isEditable())
|
||||
{
|
||||
color = "<pink>";
|
||||
}
|
||||
|
||||
ret += color;
|
||||
ret += this.getName();
|
||||
|
||||
ret = Txt.parse(ret);
|
||||
|
||||
if (withDesc) ret += " <i>" + this.getDesc();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
51
src/com/massivecraft/factions/entity/MPermColl.java
Normal file
51
src/com/massivecraft/factions/entity/MPermColl.java
Normal file
@ -0,0 +1,51 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.massivecraft.factions.Const;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.massivecore.PriorityComparator;
|
||||
import com.massivecraft.massivecore.store.Coll;
|
||||
import com.massivecraft.massivecore.store.MStore;
|
||||
|
||||
public class MPermColl extends Coll<MPerm>
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static MPermColl i = new MPermColl();
|
||||
public static MPermColl get() { return i; }
|
||||
private MPermColl()
|
||||
{
|
||||
super(Const.COLLECTION_MPERM, MPerm.class, MStore.getDb(), Factions.get(), false, false, true, null, PriorityComparator.get());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
MPerm.setupStandardPerms();
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// EXTRAS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public List<MPerm> getAll(boolean registered)
|
||||
{
|
||||
List<MPerm> ret = new ArrayList<MPerm>();
|
||||
for (MPerm mperm : this.getAll())
|
||||
{
|
||||
if (mperm.isRegistered() != registered) continue;
|
||||
ret.add(mperm);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
901
src/com/massivecraft/factions/entity/MPlayer.java
Normal file
901
src/com/massivecraft/factions/entity/MPlayer.java
Normal file
@ -0,0 +1,901 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.massivecraft.factions.EconomyParticipator;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.Lang;
|
||||
import com.massivecraft.factions.Perm;
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.RelationParticipator;
|
||||
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
|
||||
import com.massivecraft.factions.event.EventFactionsChunksChange;
|
||||
import com.massivecraft.factions.event.EventFactionsDisband;
|
||||
import com.massivecraft.factions.event.EventFactionsMembershipChange;
|
||||
import com.massivecraft.factions.event.EventFactionsRemovePlayerMillis;
|
||||
import com.massivecraft.factions.event.EventFactionsMembershipChange.MembershipChangeReason;
|
||||
import com.massivecraft.factions.util.RelationUtil;
|
||||
import com.massivecraft.massivecore.mixin.Mixin;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.ps.PSFormatHumanSpace;
|
||||
import com.massivecraft.massivecore.store.SenderEntity;
|
||||
import com.massivecraft.massivecore.util.IdUtil;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
|
||||
|
||||
public class MPlayer extends SenderEntity<MPlayer> implements EconomyParticipator
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// META
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static MPlayer get(Object oid)
|
||||
{
|
||||
return MPlayerColl.get().get(oid);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE: ENTITY
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public MPlayer load(MPlayer that)
|
||||
{
|
||||
this.setLastActivityMillis(that.lastActivityMillis);
|
||||
this.setFactionId(that.factionId);
|
||||
this.setRole(that.role);
|
||||
this.setTitle(that.title);
|
||||
this.setPowerBoost(that.powerBoost);
|
||||
this.setPower(that.power);
|
||||
this.setMapAutoUpdating(that.mapAutoUpdating);
|
||||
this.setUsingAdminMode(that.usingAdminMode);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefault()
|
||||
{
|
||||
// Last activity millis is data we use for clearing out inactive players. So it does not in itself make the player data worth keeping.
|
||||
if (this.hasFaction()) return false;
|
||||
// Role means nothing without a faction.
|
||||
// Title means nothing without a faction.
|
||||
if (this.hasPowerBoost()) return false;
|
||||
if (this.getPowerRounded() != (int) Math.round(MConf.get().defaultPlayerPower)) return false;
|
||||
// if (this.isMapAutoUpdating()) return false; // Just having an auto updating map is not in itself reason enough for database storage.
|
||||
if (this.isUsingAdminMode()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postAttach(String id)
|
||||
{
|
||||
// If inited ...
|
||||
if (!Factions.get().isDatabaseInitialized()) return;
|
||||
|
||||
// ... update the index.
|
||||
Faction faction = this.getFaction();
|
||||
faction.mplayers.add(this);
|
||||
|
||||
//Factions.get().log(Txt.parse("<g>postAttach added <h>%s <i>aka <h>%s <i>to <h>%s <i>aka <h>%s<i>.", id, Mixin.getDisplayName(id), faction.getId(), faction.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preDetach(String id)
|
||||
{
|
||||
// If inited ...
|
||||
if (!Factions.get().isDatabaseInitialized()) return;
|
||||
|
||||
// ... update the index.
|
||||
Faction faction = this.getFaction();
|
||||
faction.mplayers.remove(this);
|
||||
|
||||
//Factions.get().log(Txt.parse("<b>preDetach removed <h>%s <i>aka <h>%s <i>to <h>%s <i>aka <h>%s<i>.", id, Mixin.getDisplayName(id), faction.getId(), faction.getName()));
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELDS: RAW
|
||||
// -------------------------------------------- //
|
||||
// In this section of the source code we place the field declarations only.
|
||||
// Each field has it's own section further down since just the getter and setter logic takes up quite some place.
|
||||
|
||||
// The last known time of explicit player activity, such as login or logout.
|
||||
// This value is most importantly used for removing inactive players.
|
||||
// For that reason it defaults to the current time.
|
||||
// Really inactive players will be considered newly active when upgrading Factions from 2.6 --> 2.7.
|
||||
// There is actually more than one reason we store this data ourselves and don't use the OfflinePlayer#getLastPlayed.
|
||||
// 1. I don't trust that method. It's been very buggy or even completely broken in previous Bukkit versions.
|
||||
// 2. The method depends on the player.dat files being present.
|
||||
// Server owners clear those files at times, or move their database data around between different servers.
|
||||
private long lastActivityMillis = System.currentTimeMillis();
|
||||
|
||||
// This is a foreign key.
|
||||
// Each player belong to a faction.
|
||||
// Null means default.
|
||||
private String factionId = null;
|
||||
|
||||
// What role does the player have in the faction?
|
||||
// Null means default.
|
||||
private Rel role = null;
|
||||
|
||||
// What title does the player have in the faction?
|
||||
// The title is just for fun. It's not connected to any game mechanic.
|
||||
// The player title is similar to the faction description.
|
||||
//
|
||||
// Question: Can the title contain chat colors?
|
||||
// Answer: Yes but in such case the policy is that they already must be parsed using Txt.parse.
|
||||
// If the title contains raw markup, such as "<white>" instead of "§f" it will not be parsed and "<white>" will be displayed.
|
||||
//
|
||||
// Null means the player has no title.
|
||||
private String title = null;
|
||||
|
||||
// Player usually do not have a powerboost. It defaults to 0.
|
||||
// The powerBoost is a custom increase/decrease to default and maximum power.
|
||||
// Note that player powerBoost and faction powerBoost are very similar.
|
||||
private Double powerBoost = null;
|
||||
|
||||
// Each player has an individual power level.
|
||||
// The power level for online players is occasionally updated by a recurring task and the power should stay the same for offline players.
|
||||
// For that reason the value is to be considered correct when you pick it. Do not call the power update method.
|
||||
// Null means default.
|
||||
private Double power = null;
|
||||
|
||||
// Has this player requested an auto-updating ascii art map?
|
||||
// Null means false
|
||||
private Boolean mapAutoUpdating = null;
|
||||
|
||||
// Is this player using admin mode?
|
||||
// Null means false
|
||||
private Boolean usingAdminMode = null;
|
||||
|
||||
// The id for the faction this player is currently autoclaiming for.
|
||||
// Null means the player isn't auto claiming.
|
||||
// NOTE: This field will not be saved to the database ever.
|
||||
private transient Faction autoClaimFaction = null;
|
||||
public Faction getAutoClaimFaction() { return this.autoClaimFaction; }
|
||||
public void setAutoClaimFaction(Faction autoClaimFaction) { this.autoClaimFaction = autoClaimFaction; }
|
||||
|
||||
// Does the player have /f seechunk activated?
|
||||
// NOTE: This field will not be saved to the database ever.
|
||||
private transient boolean seeingChunk = false;
|
||||
public boolean isSeeingChunk() { return this.seeingChunk; }
|
||||
public void setSeeingChunk(boolean seeingChunk) { this.seeingChunk = seeingChunk; }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CORE UTILITIES
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void resetFactionData()
|
||||
{
|
||||
// The default neutral faction
|
||||
this.setFactionId(null);
|
||||
this.setRole(null);
|
||||
this.setTitle(null);
|
||||
this.setAutoClaimFaction(null);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELD: lastActivityMillis
|
||||
// -------------------------------------------- //
|
||||
|
||||
public long getLastActivityMillis()
|
||||
{
|
||||
return this.lastActivityMillis;
|
||||
}
|
||||
|
||||
public void setLastActivityMillis(long lastActivityMillis)
|
||||
{
|
||||
// Clean input
|
||||
long target = lastActivityMillis;
|
||||
|
||||
// Detect Nochange
|
||||
if (MUtil.equals(this.lastActivityMillis, target)) return;
|
||||
|
||||
// Apply
|
||||
this.lastActivityMillis = target;
|
||||
|
||||
// Mark as changed
|
||||
this.changed();
|
||||
}
|
||||
|
||||
public void setLastActivityMillis()
|
||||
{
|
||||
this.setLastActivityMillis(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELD: factionId
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Deprecated
|
||||
public String getDefaultFactionId()
|
||||
{
|
||||
return MConf.get().defaultPlayerFactionId;
|
||||
}
|
||||
|
||||
// This method never returns null
|
||||
public String getFactionId()
|
||||
{
|
||||
if (this.factionId == null) return MConf.get().defaultPlayerFactionId;
|
||||
return this.factionId;
|
||||
}
|
||||
|
||||
// This method never returns null
|
||||
public Faction getFaction()
|
||||
{
|
||||
Faction ret = Faction.get(this.getFactionId());
|
||||
if (ret == null) ret = Faction.get(MConf.get().defaultPlayerFactionId);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean hasFaction()
|
||||
{
|
||||
return !this.getFactionId().equals(Factions.ID_NONE);
|
||||
}
|
||||
|
||||
// This setter is so long because it search for default/null case and takes care of updating the faction member index
|
||||
public void setFactionId(String factionId)
|
||||
{
|
||||
// Clean input
|
||||
String target = factionId;
|
||||
|
||||
// Detect Nochange
|
||||
if (MUtil.equals(this.factionId, target)) return;
|
||||
|
||||
// Get the raw old value
|
||||
String oldFactionId = this.factionId;
|
||||
|
||||
// Apply
|
||||
this.factionId = target;
|
||||
|
||||
// Must be attached and initialized
|
||||
if (!this.attached()) return;
|
||||
if (!Factions.get().isDatabaseInitialized()) return;
|
||||
|
||||
if (oldFactionId == null) oldFactionId = MConf.get().defaultPlayerFactionId;
|
||||
|
||||
// Update index
|
||||
Faction oldFaction = Faction.get(oldFactionId);
|
||||
Faction faction = this.getFaction();
|
||||
|
||||
if (oldFaction != null) oldFaction.mplayers.remove(this);
|
||||
if (faction != null) faction.mplayers.add(this);
|
||||
|
||||
String oldFactionIdDesc = "NULL";
|
||||
String oldFactionNameDesc = "NULL";
|
||||
if (oldFaction != null)
|
||||
{
|
||||
oldFactionIdDesc = oldFaction.getId();
|
||||
oldFactionNameDesc = oldFaction.getName();
|
||||
}
|
||||
String factionIdDesc = "NULL";
|
||||
String factionNameDesc = "NULL";
|
||||
if (faction != null)
|
||||
{
|
||||
factionIdDesc = faction.getId();
|
||||
factionNameDesc = faction.getName();
|
||||
}
|
||||
|
||||
Factions.get().log(Txt.parse("<i>setFactionId moved <h>%s <i>aka <h>%s <i>from <h>%s <i>aka <h>%s <i>to <h>%s <i>aka <h>%s<i>.", this.getId(), this.getDisplayName(IdUtil.getConsole()), oldFactionIdDesc, oldFactionNameDesc, factionIdDesc, factionNameDesc));
|
||||
|
||||
// Mark as changed
|
||||
this.changed();
|
||||
}
|
||||
|
||||
public void setFaction(Faction faction)
|
||||
{
|
||||
this.setFactionId(faction.getId());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELD: role
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Deprecated
|
||||
public Rel getDefaultRole()
|
||||
{
|
||||
return MConf.get().defaultPlayerRole;
|
||||
}
|
||||
|
||||
public Rel getRole()
|
||||
{
|
||||
if (this.role == null) return MConf.get().defaultPlayerRole;
|
||||
return this.role;
|
||||
}
|
||||
|
||||
public void setRole(Rel role)
|
||||
{
|
||||
// Clean input
|
||||
Rel target = role;
|
||||
|
||||
// Detect Nochange
|
||||
if (MUtil.equals(this.role, target)) return;
|
||||
|
||||
// Apply
|
||||
this.role = target;
|
||||
|
||||
// Mark as changed
|
||||
this.changed();
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELD: title
|
||||
// -------------------------------------------- //
|
||||
|
||||
public boolean hasTitle()
|
||||
{
|
||||
return this.title != null;
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
if (this.hasTitle()) return this.title;
|
||||
return Lang.PLAYER_NOTITLE;
|
||||
}
|
||||
|
||||
public void setTitle(String title)
|
||||
{
|
||||
// Clean input
|
||||
String target = title;
|
||||
if (target != null)
|
||||
{
|
||||
target = target.trim();
|
||||
if (target.length() == 0)
|
||||
{
|
||||
target = null;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: That we parse the title here is considered part of the 1.8 --> 2.0 migration.
|
||||
// This should be removed once the migration phase is considered to be over.
|
||||
if (target != null)
|
||||
{
|
||||
target = Txt.parse(target);
|
||||
}
|
||||
|
||||
// Detect Nochange
|
||||
if (MUtil.equals(this.title, target)) return;
|
||||
|
||||
// Apply
|
||||
this.title = target;
|
||||
|
||||
// Mark as changed
|
||||
this.changed();
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELD: powerBoost
|
||||
// -------------------------------------------- //
|
||||
|
||||
public double getPowerBoost()
|
||||
{
|
||||
Double ret = this.powerBoost;
|
||||
if (ret == null) ret = 0D;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void setPowerBoost(Double powerBoost)
|
||||
{
|
||||
// Clean input
|
||||
Double target = powerBoost;
|
||||
if (target == null || target == 0) target = null;
|
||||
|
||||
// Detect Nochange
|
||||
if (MUtil.equals(this.powerBoost, target)) return;
|
||||
|
||||
// Apply
|
||||
this.powerBoost = target;
|
||||
|
||||
// Mark as changed
|
||||
this.changed();
|
||||
}
|
||||
|
||||
public boolean hasPowerBoost()
|
||||
{
|
||||
return this.getPowerBoost() != 0D;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELD: power
|
||||
// -------------------------------------------- //
|
||||
|
||||
// MIXIN: RAW
|
||||
|
||||
public double getPowerMaxUniversal()
|
||||
{
|
||||
return Factions.get().getPowerMixin().getMaxUniversal(this);
|
||||
}
|
||||
|
||||
public double getPowerMax()
|
||||
{
|
||||
return Factions.get().getPowerMixin().getMax(this);
|
||||
}
|
||||
|
||||
public double getPowerMin()
|
||||
{
|
||||
return Factions.get().getPowerMixin().getMin(this);
|
||||
}
|
||||
|
||||
public double getPowerPerHour()
|
||||
{
|
||||
return Factions.get().getPowerMixin().getPerHour(this);
|
||||
}
|
||||
|
||||
public double getPowerPerDeath()
|
||||
{
|
||||
return Factions.get().getPowerMixin().getPerDeath(this);
|
||||
}
|
||||
|
||||
// MIXIN: FINER
|
||||
|
||||
public double getLimitedPower(double power)
|
||||
{
|
||||
power = Math.max(power, this.getPowerMin());
|
||||
power = Math.min(power, this.getPowerMax());
|
||||
|
||||
return power;
|
||||
}
|
||||
|
||||
public int getPowerMaxRounded()
|
||||
{
|
||||
return (int) Math.round(this.getPowerMax());
|
||||
}
|
||||
|
||||
public int getPowerMinRounded()
|
||||
{
|
||||
return (int) Math.round(this.getPowerMin());
|
||||
}
|
||||
|
||||
public int getPowerMaxUniversalRounded()
|
||||
{
|
||||
return (int) Math.round(this.getPowerMaxUniversal());
|
||||
}
|
||||
|
||||
// RAW
|
||||
|
||||
@Deprecated
|
||||
public double getDefaultPower()
|
||||
{
|
||||
return MConf.get().defaultPlayerPower;
|
||||
}
|
||||
|
||||
public double getPower()
|
||||
{
|
||||
Double ret = this.power;
|
||||
if (ret == null) ret = MConf.get().defaultPlayerPower;
|
||||
ret = this.getLimitedPower(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void setPower(Double power)
|
||||
{
|
||||
// Clean input
|
||||
Double target = power;
|
||||
|
||||
// Detect Nochange
|
||||
if (MUtil.equals(this.power, target)) return;
|
||||
|
||||
// Apply
|
||||
this.power = target;
|
||||
|
||||
// Mark as changed
|
||||
this.changed();
|
||||
}
|
||||
|
||||
// FINER
|
||||
|
||||
public int getPowerRounded()
|
||||
{
|
||||
return (int) Math.round(this.getPower());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELD: mapAutoUpdating
|
||||
// -------------------------------------------- //
|
||||
|
||||
public boolean isMapAutoUpdating()
|
||||
{
|
||||
if (this.mapAutoUpdating == null) return false;
|
||||
if (this.mapAutoUpdating == false) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setMapAutoUpdating(Boolean mapAutoUpdating)
|
||||
{
|
||||
// Clean input
|
||||
Boolean target = mapAutoUpdating;
|
||||
if (MUtil.equals(target, false)) target = null;
|
||||
|
||||
// Detect Nochange
|
||||
if (MUtil.equals(this.mapAutoUpdating, target)) return;
|
||||
|
||||
// Apply
|
||||
this.mapAutoUpdating = target;
|
||||
|
||||
// Mark as changed
|
||||
this.changed();
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELD: usingAdminMode
|
||||
// -------------------------------------------- //
|
||||
|
||||
public boolean isUsingAdminMode()
|
||||
{
|
||||
if (this.usingAdminMode == null) return false;
|
||||
if (this.usingAdminMode == false) return false;
|
||||
|
||||
// Deactivate admin mode if we don't have permissions for it.
|
||||
if (this.getSender() != null && !Perm.ADMIN.has(this.getSender(), false))
|
||||
{
|
||||
this.setUsingAdminMode(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setUsingAdminMode(Boolean usingAdminMode)
|
||||
{
|
||||
// Clean input
|
||||
Boolean target = usingAdminMode;
|
||||
if (MUtil.equals(target, false)) target = null;
|
||||
|
||||
// Detect Nochange
|
||||
if (MUtil.equals(this.usingAdminMode, target)) return;
|
||||
|
||||
// Apply
|
||||
this.usingAdminMode = target;
|
||||
|
||||
// Mark as changed
|
||||
this.changed();
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// TITLE, NAME, FACTION NAME AND CHAT
|
||||
// -------------------------------------------- //
|
||||
|
||||
public String getFactionName()
|
||||
{
|
||||
Faction faction = this.getFaction();
|
||||
if (faction.isNone()) return "";
|
||||
return faction.getName();
|
||||
}
|
||||
|
||||
// Base concatenations:
|
||||
|
||||
public String getNameAndSomething(String color, String something)
|
||||
{
|
||||
String ret = "";
|
||||
ret += color;
|
||||
ret += this.getRole().getPrefix();
|
||||
if (something != null && something.length() > 0)
|
||||
{
|
||||
ret += something;
|
||||
ret += " ";
|
||||
ret += color;
|
||||
}
|
||||
ret += this.getName();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String getNameAndFactionName()
|
||||
{
|
||||
return this.getNameAndSomething("", this.getFactionName());
|
||||
}
|
||||
|
||||
public String getNameAndTitle(String color)
|
||||
{
|
||||
if (this.hasTitle())
|
||||
{
|
||||
return this.getNameAndSomething(color, this.getTitle());
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.getNameAndSomething(color, null);
|
||||
}
|
||||
}
|
||||
|
||||
// Colored concatenations:
|
||||
// These are used in information messages
|
||||
|
||||
public String getNameAndTitle(Faction faction)
|
||||
{
|
||||
return this.getNameAndTitle(this.getColorTo(faction).toString());
|
||||
}
|
||||
public String getNameAndTitle(MPlayer mplayer)
|
||||
{
|
||||
return this.getNameAndTitle(this.getColorTo(mplayer).toString());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// RELATION AND RELATION COLORS
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public String describeTo(RelationParticipator observer, boolean ucfirst)
|
||||
{
|
||||
return RelationUtil.describeThatToMe(this, observer, ucfirst);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describeTo(RelationParticipator observer)
|
||||
{
|
||||
return RelationUtil.describeThatToMe(this, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rel getRelationTo(RelationParticipator observer)
|
||||
{
|
||||
return RelationUtil.getRelationOfThatToMe(this, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rel getRelationTo(RelationParticipator observer, boolean ignorePeaceful)
|
||||
{
|
||||
return RelationUtil.getRelationOfThatToMe(this, observer, ignorePeaceful);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatColor getColorTo(RelationParticipator observer)
|
||||
{
|
||||
return RelationUtil.getColorOfThatToMe(this, observer);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// HEALTH
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void heal(int amnt)
|
||||
{
|
||||
Player player = this.getPlayer();
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
player.setHealth(player.getHealth() + amnt);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// TERRITORY
|
||||
// -------------------------------------------- //
|
||||
|
||||
public boolean isInOwnTerritory()
|
||||
{
|
||||
PS ps = Mixin.getSenderPs(this.getId());
|
||||
if (ps == null) return false;
|
||||
return BoardColl.get().getFactionAt(ps) == this.getFaction();
|
||||
}
|
||||
|
||||
public boolean isInEnemyTerritory()
|
||||
{
|
||||
PS ps = Mixin.getSenderPs(this.getId());
|
||||
if (ps == null) return false;
|
||||
return BoardColl.get().getFactionAt(ps).getRelationTo(this) == Rel.ENEMY;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// INACTIVITY TIMEOUT
|
||||
// -------------------------------------------- //
|
||||
|
||||
public long getRemovePlayerMillis(boolean async)
|
||||
{
|
||||
EventFactionsRemovePlayerMillis event = new EventFactionsRemovePlayerMillis(async, this);
|
||||
event.run();
|
||||
return event.getMillis();
|
||||
}
|
||||
|
||||
public boolean considerRemovePlayerMillis(boolean async)
|
||||
{
|
||||
// This may or may not be required.
|
||||
// Some users have been reporting a loop issue with the same player detaching over and over again.
|
||||
// Maybe skipping ahead if the player is detached will solve the issue.
|
||||
if (this.detached()) return false;
|
||||
|
||||
// Get the last activity millis.
|
||||
long lastActivityMillis = this.getLastActivityMillis();
|
||||
|
||||
// Consider
|
||||
long toleranceMillis = this.getRemovePlayerMillis(async);
|
||||
if (System.currentTimeMillis() - lastActivityMillis <= toleranceMillis) return false;
|
||||
|
||||
// Inform
|
||||
if (MConf.get().logFactionLeave || MConf.get().logFactionKick)
|
||||
{
|
||||
Factions.get().log("Player " + this.getName() + " was auto-removed due to inactivity.");
|
||||
}
|
||||
|
||||
// Apply
|
||||
|
||||
// Promote a new leader if required.
|
||||
if (this.getRole() == Rel.LEADER)
|
||||
{
|
||||
Faction faction = this.getFaction();
|
||||
if (faction != null)
|
||||
{
|
||||
this.getFaction().promoteNewLeader();
|
||||
}
|
||||
}
|
||||
|
||||
this.leave();
|
||||
this.detach();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// ACTIONS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void leave()
|
||||
{
|
||||
Faction myFaction = this.getFaction();
|
||||
|
||||
boolean permanent = myFaction.getFlag(MFlag.getFlagPermanent());
|
||||
|
||||
if (myFaction.getMPlayers().size() > 1)
|
||||
{
|
||||
if (!permanent && this.getRole() == Rel.LEADER)
|
||||
{
|
||||
msg("<b>You must give the leader role to someone else first.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MConf.get().canLeaveWithNegativePower && this.getPower() < 0)
|
||||
{
|
||||
msg("<b>You cannot leave until your power is positive.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Event
|
||||
EventFactionsMembershipChange membershipChangeEvent = new EventFactionsMembershipChange(this.getSender(), this, myFaction, MembershipChangeReason.LEAVE);
|
||||
membershipChangeEvent.run();
|
||||
if (membershipChangeEvent.isCancelled()) return;
|
||||
|
||||
if (myFaction.isNormal())
|
||||
{
|
||||
for (MPlayer mplayer : myFaction.getMPlayersWhereOnline(true))
|
||||
{
|
||||
mplayer.msg("%s<i> left %s<i>.", this.describeTo(mplayer, true), myFaction.describeTo(mplayer));
|
||||
}
|
||||
|
||||
if (MConf.get().logFactionLeave)
|
||||
{
|
||||
Factions.get().log(this.getName()+" left the faction: "+myFaction.getName());
|
||||
}
|
||||
}
|
||||
|
||||
this.resetFactionData();
|
||||
|
||||
if (myFaction.isNormal() && !permanent && myFaction.getMPlayers().isEmpty())
|
||||
{
|
||||
EventFactionsDisband eventFactionsDisband = new EventFactionsDisband(this.getSender(), myFaction);
|
||||
eventFactionsDisband.run();
|
||||
if ( ! eventFactionsDisband.isCancelled())
|
||||
{
|
||||
// Remove this faction
|
||||
this.msg("%s <i>was disbanded since you were the last player.", myFaction.describeTo(this, true));
|
||||
if (MConf.get().logFactionDisband)
|
||||
{
|
||||
Factions.get().log("The faction "+myFaction.getName()+" ("+myFaction.getId()+") was disbanded due to the last player ("+this.getName()+") leaving.");
|
||||
}
|
||||
myFaction.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NEW
|
||||
public boolean tryClaim(Faction newFaction, Collection<PS> pss)
|
||||
{
|
||||
return this.tryClaim(newFaction, pss, null, null);
|
||||
}
|
||||
|
||||
public boolean tryClaim(Faction newFaction, Collection<PS> pss, String formatOne, String formatMany)
|
||||
{
|
||||
// Args
|
||||
if (formatOne == null) formatOne = "<h>%s<i> %s <h>%d <i>chunk %s<i>.";
|
||||
if (formatMany == null) formatMany = "<h>%s<i> %s <h>%d <i>chunks near %s<i>.";
|
||||
|
||||
if (newFaction == null) throw new NullPointerException("newFaction");
|
||||
|
||||
if (pss == null) throw new NullPointerException("pss");
|
||||
final Set<PS> chunks = PS.getDistinctChunks(pss);
|
||||
|
||||
// NoChange
|
||||
// We clean the chunks further by removing what does not change.
|
||||
// This is also very suggested cleaning of EventFactionsChunksChange input.
|
||||
Iterator<PS> iter = chunks.iterator();
|
||||
while (iter.hasNext())
|
||||
{
|
||||
PS chunk = iter.next();
|
||||
Faction oldFaction = BoardColl.get().getFactionAt(chunk);
|
||||
if (newFaction == oldFaction) iter.remove();
|
||||
}
|
||||
if (chunks.isEmpty())
|
||||
{
|
||||
msg("%s<i> already owns this land.", newFaction.describeTo(this, true));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Event
|
||||
// NOTE: We listen to this event ourselves at LOW.
|
||||
// NOTE: That is where we apply the standard checks.
|
||||
CommandSender sender = this.getSender();
|
||||
if (sender == null)
|
||||
{
|
||||
msg("<b>ERROR: Your \"CommandSender Link\" has been severed. This shouldn't happen.");
|
||||
msg("<b>Help the Factions developers by reporting this at: <aqua>https://github.com/MassiveCraft/Factions/issues");
|
||||
msg("<b>Describe what you were doing, what client you are using, if this is your first time on the server etc. The more the better.");
|
||||
msg("<g>Relogging to the server should fix the issue.");
|
||||
return false;
|
||||
}
|
||||
EventFactionsChunksChange event = new EventFactionsChunksChange(sender, chunks, newFaction);
|
||||
event.run();
|
||||
if (event.isCancelled()) return false;
|
||||
|
||||
// Apply
|
||||
for (PS chunk : chunks)
|
||||
{
|
||||
BoardColl.get().setFactionAt(chunk, newFaction);
|
||||
}
|
||||
|
||||
// Inform
|
||||
for (Entry<Faction, Set<PS>> entry : event.getOldFactionChunks().entrySet())
|
||||
{
|
||||
final Faction oldFaction = entry.getKey();
|
||||
final Set<PS> oldChunks = entry.getValue();
|
||||
final PS oldChunk = oldChunks.iterator().next();
|
||||
final Set<MPlayer> informees = getClaimInformees(this, oldFaction, newFaction);
|
||||
final EventFactionsChunkChangeType type = EventFactionsChunkChangeType.get(oldFaction, newFaction, this.getFaction());
|
||||
|
||||
String chunkString = oldChunk.toString(PSFormatHumanSpace.get());
|
||||
String typeString = type.past;
|
||||
|
||||
for (MPlayer informee : informees)
|
||||
{
|
||||
informee.msg((oldChunks.size() == 1 ? formatOne : formatMany), this.describeTo(informee, true), typeString, oldChunks.size(), chunkString);
|
||||
informee.msg(" <h>%s<i> --> <h>%s", oldFaction.describeTo(informee, true), newFaction.describeTo(informee, true));
|
||||
}
|
||||
}
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UTIL
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static Set<MPlayer> getClaimInformees(MPlayer msender, Faction... factions)
|
||||
{
|
||||
Set<MPlayer> ret = new HashSet<MPlayer>();
|
||||
|
||||
if (msender != null) ret.add(msender);
|
||||
|
||||
for (Faction faction : factions)
|
||||
{
|
||||
if (faction == null) continue;
|
||||
if (faction.isNone()) continue;
|
||||
ret.addAll(faction.getMPlayers());
|
||||
}
|
||||
|
||||
if (MConf.get().logLandClaims)
|
||||
{
|
||||
ret.add(MPlayer.get(IdUtil.getConsole()));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
68
src/com/massivecraft/factions/entity/MPlayerColl.java
Normal file
68
src/com/massivecraft/factions/entity/MPlayerColl.java
Normal file
@ -0,0 +1,68 @@
|
||||
package com.massivecraft.factions.entity;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import com.massivecraft.factions.Const;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.massivecore.store.MStore;
|
||||
import com.massivecraft.massivecore.store.SenderColl;
|
||||
import com.massivecraft.massivecore.util.IdUtil;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
|
||||
public class MPlayerColl extends SenderColl<MPlayer>
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static MPlayerColl i = new MPlayerColl();
|
||||
public static MPlayerColl get() { return i; }
|
||||
private MPlayerColl()
|
||||
{
|
||||
super(Const.COLLECTION_MPLAYER, MPlayer.class, MStore.getDb(), Factions.get());
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// EXTRAS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void clean()
|
||||
{
|
||||
for (MPlayer mplayer : this.getAll())
|
||||
{
|
||||
String factionId = mplayer.getFactionId();
|
||||
if (FactionColl.get().containsId(factionId)) continue;
|
||||
|
||||
mplayer.resetFactionData();
|
||||
|
||||
String message = Txt.parse("<i>Reset data for <h>%s <i>. Unknown factionId <h>%s", mplayer.getDisplayName(IdUtil.getConsole()), factionId);
|
||||
Factions.get().log(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void considerRemovePlayerMillis()
|
||||
{
|
||||
// If the config option is 0 or below that means the server owner want it disabled.
|
||||
if (MConf.get().removePlayerMillisDefault <= 0.0) return;
|
||||
|
||||
// For each of the offline players...
|
||||
// NOTE: If the player is currently online it's most definitely not inactive.
|
||||
// NOTE: This check catches some important special cases like the @console "player".
|
||||
final Collection<MPlayer> mplayersOffline = this.getAllOffline();
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(Factions.get(), new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
for (MPlayer mplayer : mplayersOffline)
|
||||
{
|
||||
mplayer.considerRemovePlayerMillis(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user