Maven Attempt 1
This commit is contained in:
273
src/main/java/com/massivecraft/factions/integration/Econ.java
Normal file
273
src/main/java/com/massivecraft/factions/integration/Econ.java
Normal file
@@ -0,0 +1,273 @@
|
||||
package com.massivecraft.factions.integration;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.massivecraft.factions.EconomyParticipator;
|
||||
import com.massivecraft.factions.FPerm;
|
||||
import com.massivecraft.factions.entity.UConf;
|
||||
import com.massivecraft.factions.entity.UPlayer;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.util.RelationUtil;
|
||||
import com.massivecraft.massivecore.money.Money;
|
||||
|
||||
public class Econ
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// STATE
|
||||
// -------------------------------------------- //
|
||||
|
||||
// TODO: Do we really need that config option?
|
||||
// TODO: Could we not have it enabled as long as Money.enabled is true?
|
||||
public static boolean isEnabled(Object universe)
|
||||
{
|
||||
return UConf.get(universe).econEnabled && Money.enabled();
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UTIL
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static boolean payForAction(double cost, UPlayer usender, String actionDescription)
|
||||
{
|
||||
if (!isEnabled(usender)) return true;
|
||||
if (cost == 0D) return true;
|
||||
|
||||
if (usender.isUsingAdminMode()) return true;
|
||||
UConf uconf = UConf.get(usender);
|
||||
Faction usenderFaction = usender.getFaction();
|
||||
|
||||
if (uconf.bankEnabled && uconf.bankFactionPaysCosts && usenderFaction.isNormal())
|
||||
{
|
||||
return modifyMoney(usenderFaction, -cost, actionDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
return modifyMoney(usender, -cost, actionDescription);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// ASSORTED
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static void modifyUniverseMoney(Object universe, double delta)
|
||||
{
|
||||
if (!isEnabled(universe)) return;
|
||||
UConf uconf = UConf.get(universe);
|
||||
|
||||
if (uconf.econUniverseAccount == null) return;
|
||||
if (uconf.econUniverseAccount.length() == 0) return;
|
||||
|
||||
if (!Money.exists(uconf.econUniverseAccount)) return;
|
||||
|
||||
Money.spawn(uconf.econUniverseAccount, null, delta);
|
||||
}
|
||||
|
||||
public static void sendBalanceInfo(UPlayer to, EconomyParticipator about)
|
||||
{
|
||||
to.msg("<a>%s's<i> balance is <h>%s<i>.", about.describeTo(to, true), Money.format(Money.get(about)));
|
||||
}
|
||||
|
||||
public static boolean canIControllYou(EconomyParticipator i, EconomyParticipator you)
|
||||
{
|
||||
Faction fI = RelationUtil.getFaction(i);
|
||||
Faction fYou = RelationUtil.getFaction(you);
|
||||
|
||||
// This is a system invoker. Accept it.
|
||||
if (fI == null) return true;
|
||||
|
||||
// Bypassing players can do any kind of transaction
|
||||
if (i instanceof UPlayer && ((UPlayer)i).isUsingAdminMode()) return true;
|
||||
|
||||
// You can deposit to anywhere you feel like. It's your loss if you can't withdraw it again.
|
||||
if (i == you) return true;
|
||||
|
||||
// A faction can always transfer away the money of it's members and its own money...
|
||||
// This will however probably never happen as a faction does not have free will.
|
||||
// Ohh by the way... Yes it could. For daily rent to the faction.
|
||||
if (i == fI && fI == fYou) return true;
|
||||
|
||||
// Factions can be controlled by those that have permissions
|
||||
if (you instanceof Faction)
|
||||
{
|
||||
if (i instanceof Faction && FPerm.WITHDRAW.has((Faction)i, fYou)) return true;
|
||||
if (i instanceof UPlayer && FPerm.WITHDRAW.has((UPlayer)i, fYou, false)) return true;
|
||||
}
|
||||
|
||||
// Otherwise you may not! ;,,;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean transferMoney(EconomyParticipator invoker, EconomyParticipator from, EconomyParticipator to, double amount)
|
||||
{
|
||||
return transferMoney(from, to, invoker, amount, true);
|
||||
}
|
||||
public static boolean transferMoney(EconomyParticipator from, EconomyParticipator to, EconomyParticipator by, double amount, boolean notify)
|
||||
{
|
||||
if (!isEnabled(from)) return false;
|
||||
|
||||
// The amount must be positive.
|
||||
// If the amount is negative we must flip and multiply amount with -1.
|
||||
if (amount < 0)
|
||||
{
|
||||
amount *= -1;
|
||||
EconomyParticipator temp = from;
|
||||
from = to;
|
||||
to = temp;
|
||||
}
|
||||
|
||||
// Check the rights
|
||||
if ( ! canIControllYou(by, from))
|
||||
{
|
||||
by.msg("<h>%s<i> lacks permission to control <h>%s's<i> money.", by.describeTo(by, true), from.describeTo(by));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is there enough money for the transaction to happen?
|
||||
if (Money.get(from) < amount)
|
||||
{
|
||||
// There was not enough money to pay
|
||||
if (by != null && notify)
|
||||
{
|
||||
by.msg("<h>%s<b> can't afford to transfer <h>%s<b> to %s<b>.", from.describeTo(by, true), Money.format(amount), to.describeTo(by));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Transfer money
|
||||
if (Money.move(from, to, by, amount))
|
||||
{
|
||||
if (notify)
|
||||
{
|
||||
sendTransferInfo(by, from, to, amount);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we get here something with the transaction failed
|
||||
if (by != null && notify)
|
||||
{
|
||||
by.msg("Unable to transfer %s<b> to <h>%s<b> from <h>%s<b>.", Money.format(amount), to.describeTo(by), from.describeTo(by, true));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<UPlayer> getUPlayers(EconomyParticipator ep)
|
||||
{
|
||||
Set<UPlayer> uplayers = new HashSet<UPlayer>();
|
||||
|
||||
if (ep == null)
|
||||
{
|
||||
// Add nothing
|
||||
}
|
||||
else if (ep instanceof UPlayer)
|
||||
{
|
||||
uplayers.add((UPlayer)ep);
|
||||
}
|
||||
else if (ep instanceof Faction)
|
||||
{
|
||||
uplayers.addAll(((Faction)ep).getUPlayers());
|
||||
}
|
||||
|
||||
return uplayers;
|
||||
}
|
||||
|
||||
public static void sendTransferInfo(EconomyParticipator invoker, EconomyParticipator from, EconomyParticipator to, double amount)
|
||||
{
|
||||
Set<UPlayer> recipients = new HashSet<UPlayer>();
|
||||
recipients.addAll(getUPlayers(invoker));
|
||||
recipients.addAll(getUPlayers(from));
|
||||
recipients.addAll(getUPlayers(to));
|
||||
|
||||
if (invoker == null)
|
||||
{
|
||||
for (UPlayer recipient : recipients)
|
||||
{
|
||||
recipient.msg("<h>%s<i> was transfered from <h>%s<i> to <h>%s<i>.", Money.format(amount), from.describeTo(recipient), to.describeTo(recipient));
|
||||
}
|
||||
}
|
||||
else if (invoker == from)
|
||||
{
|
||||
for (UPlayer recipient : recipients)
|
||||
{
|
||||
recipient.msg("<h>%s<i> <h>gave %s<i> to <h>%s<i>.", from.describeTo(recipient, true), Money.format(amount), to.describeTo(recipient));
|
||||
}
|
||||
}
|
||||
else if (invoker == to)
|
||||
{
|
||||
for (UPlayer recipient : recipients)
|
||||
{
|
||||
recipient.msg("<h>%s<i> <h>took %s<i> from <h>%s<i>.", to.describeTo(recipient, true), Money.format(amount), from.describeTo(recipient));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UPlayer recipient : recipients)
|
||||
{
|
||||
recipient.msg("<h>%s<i> transfered <h>%s<i> from <h>%s<i> to <h>%s<i>.", invoker.describeTo(recipient, true), Money.format(amount), from.describeTo(recipient), to.describeTo(recipient));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasAtLeast(EconomyParticipator ep, double delta, String toDoThis)
|
||||
{
|
||||
if (!isEnabled(ep)) return true;
|
||||
|
||||
if (Money.get(ep) < delta)
|
||||
{
|
||||
if (toDoThis != null && !toDoThis.isEmpty())
|
||||
{
|
||||
ep.msg("<h>%s<i> can't afford <h>%s<i> %s.", ep.describeTo(ep, true), Money.format(delta), toDoThis);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean modifyMoney(EconomyParticipator ep, double delta, String actionDescription)
|
||||
{
|
||||
if (!isEnabled(ep)) return false;
|
||||
if (delta == 0) return true;
|
||||
|
||||
String You = ep.describeTo(ep, true);
|
||||
|
||||
boolean hasActionDesctription = (actionDescription != null && !actionDescription.isEmpty());
|
||||
|
||||
if (Money.spawn(ep, null, delta))
|
||||
{
|
||||
modifyUniverseMoney(ep, -delta);
|
||||
|
||||
if (hasActionDesctription)
|
||||
{
|
||||
if (delta > 0)
|
||||
{
|
||||
ep.msg("<h>%s<i> gained <h>%s<i> since did %s.", You, Money.format(delta), actionDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
ep.msg("<h>%s<i> lost <h>%s<i> since did %s.", You, Money.format(-delta), actionDescription);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasActionDesctription)
|
||||
{
|
||||
if (delta > 0)
|
||||
{
|
||||
ep.msg("<h>%s<i> would have gained <h>%s<i> since did %s, but the deposit failed.", You, Money.format(delta), actionDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
ep.msg("<h>%s<i> can't afford <h>%s<i> to %s.", You, Money.format(-delta), actionDescription);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
package com.massivecraft.factions.integration.dynmap;
|
||||
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
|
||||
public class DynmapStyle
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// FIELDS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public String lineColor = null;
|
||||
public int getLineColor() { return getColor(coalesce(this.lineColor, MConf.get().dynmapDefaultStyle.lineColor, MConf.DYNMAP_STYLE_LINE_COLOR)); }
|
||||
public DynmapStyle setStrokeColor(String strokeColor) { this.lineColor = strokeColor; return this; }
|
||||
|
||||
public Double lineOpacity = null;
|
||||
public double getLineOpacity() { return coalesce(this.lineOpacity, MConf.get().dynmapDefaultStyle.lineOpacity, MConf.DYNMAP_STYLE_LINE_OPACITY); }
|
||||
public DynmapStyle setLineOpacity(Double strokeOpacity) { this.lineOpacity = strokeOpacity; return this; }
|
||||
|
||||
public Integer lineWeight = null;
|
||||
public int getLineWeight() { return coalesce(this.lineWeight, MConf.get().dynmapDefaultStyle.lineWeight, MConf.DYNMAP_STYLE_LINE_WEIGHT); }
|
||||
public DynmapStyle setLineWeight(Integer strokeWeight) { this.lineWeight = strokeWeight; return this; }
|
||||
|
||||
public String fillColor = null;
|
||||
public int getFillColor() { return getColor(coalesce(this.fillColor, MConf.get().dynmapDefaultStyle.fillColor, MConf.DYNMAP_STYLE_FILL_COLOR)); }
|
||||
public DynmapStyle setFillColor(String fillColor) { this.fillColor = fillColor; return this; }
|
||||
|
||||
public Double fillOpacity = null;
|
||||
public double getFillOpacity() { return coalesce(this.fillOpacity, MConf.get().dynmapDefaultStyle.fillOpacity, MConf.DYNMAP_STYLE_FILL_OPACITY); }
|
||||
public DynmapStyle setFillOpacity(Double fillOpacity) { this.fillOpacity = fillOpacity; return this; }
|
||||
|
||||
// NOTE: We just return the string here. We do not return the resolved Dynmap MarkerIcon object.
|
||||
// The reason is we use this class in the MConf. For serialization to work Dynmap would have to be loaded and we can't require that.
|
||||
// Using dynmap is optional.
|
||||
public String homeMarker = null;
|
||||
public String getHomeMarker() { return coalesce(this.homeMarker, MConf.get().dynmapDefaultStyle.homeMarker, MConf.DYNMAP_STYLE_HOME_MARKER); }
|
||||
public DynmapStyle setHomeMarker(String homeMarker) { this.homeMarker = homeMarker; return this; }
|
||||
|
||||
public Boolean boost = null;
|
||||
public boolean getBoost() { return coalesce(this.boost, MConf.get().dynmapDefaultStyle.boost, MConf.DYNMAP_STYLE_BOOST); }
|
||||
public DynmapStyle setBoost(Boolean boost) { this.boost = boost; return this; }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UTIL
|
||||
// -------------------------------------------- //
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> T coalesce(T... items)
|
||||
{
|
||||
for (T item : items)
|
||||
{
|
||||
if (item != null) return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getColor(String string)
|
||||
{
|
||||
int ret = 0x00FF00;
|
||||
try
|
||||
{
|
||||
ret = Integer.parseInt(string.substring(1), 16);
|
||||
}
|
||||
catch (NumberFormatException nfx)
|
||||
{
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,959 @@
|
||||
package com.massivecraft.factions.integration.dynmap;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.dynmap.DynmapAPI;
|
||||
import org.dynmap.markers.AreaMarker;
|
||||
import org.dynmap.markers.Marker;
|
||||
import org.dynmap.markers.MarkerAPI;
|
||||
import org.dynmap.markers.MarkerSet;
|
||||
import org.dynmap.markers.PlayerSet;
|
||||
import org.dynmap.utils.TileFlags;
|
||||
|
||||
import com.massivecraft.factions.FFlag;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.TerritoryAccess;
|
||||
import com.massivecraft.factions.entity.Board;
|
||||
import com.massivecraft.factions.entity.BoardColl;
|
||||
import com.massivecraft.factions.entity.BoardColls;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.FactionColl;
|
||||
import com.massivecraft.factions.entity.FactionColls;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.factions.entity.UConf;
|
||||
import com.massivecraft.factions.entity.UPlayer;
|
||||
import com.massivecraft.massivecore.EngineAbstract;
|
||||
import com.massivecraft.massivecore.money.Money;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
import com.massivecraft.massivecore.util.TimeDiffUtil;
|
||||
import com.massivecraft.massivecore.util.TimeUnit;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
|
||||
// This source code is a heavily modified version of mikeprimms plugin Dynmap-Factions.
|
||||
public class EngineDynmap extends EngineAbstract
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// CONSTANTS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public final static int BLOCKS_PER_CHUNK = 16;
|
||||
|
||||
public final static String DYNMAP_INTEGRATION = Txt.parse("<h>Dynmap Integration: <i>");
|
||||
|
||||
public final static String FACTIONS = "factions";
|
||||
public final static String FACTIONS_ = FACTIONS + "_";
|
||||
|
||||
public final static String FACTIONS_MARKERSET = FACTIONS_ + "markerset";
|
||||
|
||||
public final static String FACTIONS_HOME = FACTIONS_ + "home";
|
||||
public final static String FACTIONS_HOME_ = FACTIONS_HOME + "_";
|
||||
|
||||
public final static String FACTIONS_PLAYERSET = FACTIONS_ + "playerset";
|
||||
public final static String FACTIONS_PLAYERSET_ = FACTIONS_PLAYERSET + "_";
|
||||
|
||||
public final static String FACTIONS_AREA = FACTIONS_ + "area";
|
||||
public final static String FACTIONS_AREA_ = FACTIONS_AREA + "_";
|
||||
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineDynmap i = new EngineDynmap();
|
||||
public static EngineDynmap get() { return i; }
|
||||
private EngineDynmap() {}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin()
|
||||
{
|
||||
return Factions.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getPeriod()
|
||||
{
|
||||
// Every 15 seconds
|
||||
return 15 * 20L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSync()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// FIELDS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public DynmapAPI dynmapApi;
|
||||
public MarkerAPI markerApi;
|
||||
public MarkerSet markerset;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// RUN: UPDATE
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
// Should we even use dynmap?
|
||||
if (!MConf.get().dynmapUse)
|
||||
{
|
||||
if (this.markerset != null)
|
||||
{
|
||||
this.markerset.deleteMarkerSet();
|
||||
this.markerset = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
long before = System.currentTimeMillis();
|
||||
|
||||
// We do what we can here.
|
||||
// You /can/ run this method from the main server thread but it's not recommended at all.
|
||||
// This method is supposed to be run async to avoid locking the main server thread.
|
||||
final Map<String, TempMarker> homes = createHomes();
|
||||
final Map<String, TempAreaMarker> areas = createAreas();
|
||||
final Map<String, Set<String>> playerSets = createPlayersets();
|
||||
|
||||
long after = System.currentTimeMillis();
|
||||
long duration = after-before;
|
||||
updateLog("Async", duration);
|
||||
|
||||
// Shedule non thread safe sync at the end!
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Factions.get(), new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
long before = System.currentTimeMillis();
|
||||
|
||||
if (!updateCore()) return;
|
||||
|
||||
// createLayer() is thread safe but it makes use of fields set in updateCore() so we must have it after.
|
||||
if (!updateLayer(createLayer())) return;
|
||||
|
||||
updateHomes(homes);
|
||||
updateAreas(areas);
|
||||
updatePlayersets(playerSets);
|
||||
|
||||
long after = System.currentTimeMillis();
|
||||
long duration = after-before;
|
||||
updateLog("Sync", duration);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
public static void updateLog(String name, long millis)
|
||||
{
|
||||
if (!MConf.get().dynmapUpdateLog) return;
|
||||
String message = Txt.parse("<i>%s took <h>%dms<i>.", "Faction Dynmap " + name, millis);
|
||||
Factions.get().log(message);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UPDATE: CORE
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Thread Safe / Asynchronous: No
|
||||
public boolean updateCore()
|
||||
{
|
||||
// Get DynmapAPI
|
||||
this.dynmapApi = (DynmapAPI) Bukkit.getPluginManager().getPlugin("dynmap");
|
||||
if (this.dynmapApi == null)
|
||||
{
|
||||
severe("Could not retrieve the DynmapAPI.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get MarkerAPI
|
||||
this.markerApi = this.dynmapApi.getMarkerAPI();
|
||||
if (this.markerApi == null)
|
||||
{
|
||||
severe("Could not retrieve the MarkerAPI.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UPDATE: Layer
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
public TempMarkerSet createLayer()
|
||||
{
|
||||
TempMarkerSet ret = new TempMarkerSet();
|
||||
ret.label = MConf.get().dynmapLayerName;
|
||||
ret.minimumZoom = MConf.get().dynmapLayerMinimumZoom;
|
||||
ret.priority = MConf.get().dynmapLayerPriority;
|
||||
ret.hideByDefault = !MConf.get().dynmapLayerVisible;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Thread Safe / Asynchronous: No
|
||||
public boolean updateLayer(TempMarkerSet temp)
|
||||
{
|
||||
this.markerset = this.markerApi.getMarkerSet(FACTIONS_MARKERSET);
|
||||
if (this.markerset == null)
|
||||
{
|
||||
this.markerset = temp.create(this.markerApi, FACTIONS_MARKERSET);
|
||||
if (this.markerset == null)
|
||||
{
|
||||
severe("Could not create the Faction Markerset/Layer");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.update(this.markerApi, this.markerset);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UPDATE: HOMES
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
public Map<String, TempMarker> createHomes()
|
||||
{
|
||||
Map<String, TempMarker> ret = new HashMap<String, TempMarker>();
|
||||
|
||||
// Loop current factions
|
||||
for (FactionColl coll : FactionColls.get().getColls())
|
||||
{
|
||||
for (Faction faction : coll.getAll())
|
||||
{
|
||||
PS ps = faction.getHome();
|
||||
if (ps == null) continue;
|
||||
|
||||
DynmapStyle style = getStyle(faction);
|
||||
|
||||
String markerId = FACTIONS_HOME_ + faction.getId();
|
||||
|
||||
TempMarker temp = new TempMarker();
|
||||
temp.label = ChatColor.stripColor(faction.getName());
|
||||
temp.world = ps.getWorld();
|
||||
temp.x = ps.getLocationX();
|
||||
temp.y = ps.getLocationY();
|
||||
temp.z = ps.getLocationZ();
|
||||
temp.iconName = style.getHomeMarker();
|
||||
temp.description = getDescription(faction);
|
||||
|
||||
ret.put(markerId, temp);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Thread Safe / Asynchronous: No
|
||||
// This method places out the faction home markers into the factions markerset.
|
||||
public void updateHomes(Map<String, TempMarker> homes)
|
||||
{
|
||||
// Put all current faction markers in a map
|
||||
Map<String, Marker> markers = new HashMap<String, Marker>();
|
||||
for (Marker marker : this.markerset.getMarkers())
|
||||
{
|
||||
markers.put(marker.getMarkerID(), marker);
|
||||
}
|
||||
|
||||
// Loop homes
|
||||
for (Entry<String, TempMarker> entry : homes.entrySet())
|
||||
{
|
||||
String markerId = entry.getKey();
|
||||
TempMarker temp = entry.getValue();
|
||||
|
||||
// Get Creative
|
||||
// NOTE: I remove from the map created just in the beginning of this method.
|
||||
// NOTE: That way what is left at the end will be outdated markers to remove.
|
||||
Marker marker = markers.remove(markerId);
|
||||
if (marker == null)
|
||||
{
|
||||
marker = temp.create(this.markerApi, this.markerset, markerId);
|
||||
if (marker == null)
|
||||
{
|
||||
EngineDynmap.severe("Could not get/create the home marker " + markerId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.update(this.markerApi, this.markerset, marker);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete Deprecated Markers
|
||||
// Only old markers should now be left
|
||||
for (Marker marker : markers.values())
|
||||
{
|
||||
marker.deleteMarker();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UPDATE: AREAS
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Thread Safe: YES
|
||||
public Map<String, TempAreaMarker> createAreas()
|
||||
{
|
||||
Map<String, Map<Faction, Set<PS>>> worldFactionChunks = createWorldFactionChunks();
|
||||
return createAreas(worldFactionChunks);
|
||||
}
|
||||
|
||||
// Thread Safe: YES
|
||||
public Map<String, Map<Faction, Set<PS>>> createWorldFactionChunks()
|
||||
{
|
||||
// Create map "world name --> faction --> set of chunk coords"
|
||||
Map<String, Map<Faction, Set<PS>>> worldFactionChunks = new HashMap<String, Map<Faction, Set<PS>>>();
|
||||
for (BoardColl coll : BoardColls.get().getColls())
|
||||
{
|
||||
// Note: The board is the world. The board id is the world name.
|
||||
for (Board board : coll.getAll())
|
||||
{
|
||||
String world = board.getId();
|
||||
|
||||
// Get the factionChunks creatively.
|
||||
Map<Faction, Set<PS>> factionChunks = worldFactionChunks.get(world);
|
||||
if (factionChunks == null)
|
||||
{
|
||||
factionChunks = new HashMap<Faction, Set<PS>>();
|
||||
worldFactionChunks.put(world, factionChunks);
|
||||
}
|
||||
|
||||
// Populate the factionChunks
|
||||
for (Entry<PS, TerritoryAccess> entry : board.getMap().entrySet())
|
||||
{
|
||||
PS chunk = entry.getKey();
|
||||
TerritoryAccess territoryAccess = entry.getValue();
|
||||
String factionId = territoryAccess.getHostFactionId();
|
||||
Faction faction = FactionColls.get().getForWorld(world).get(factionId);
|
||||
if (faction == null) continue;
|
||||
|
||||
// Get the chunks creatively.
|
||||
Set<PS> chunks = factionChunks.get(faction);
|
||||
if (chunks == null)
|
||||
{
|
||||
chunks = new HashSet<PS>();
|
||||
factionChunks.put(faction, chunks);
|
||||
}
|
||||
|
||||
chunks.add(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
return worldFactionChunks;
|
||||
}
|
||||
|
||||
// Thread Safe: YES
|
||||
public Map<String, TempAreaMarker> createAreas(Map<String, Map<Faction, Set<PS>>> worldFactionChunks)
|
||||
{
|
||||
Map<String, TempAreaMarker> ret = new HashMap<String, TempAreaMarker>();
|
||||
|
||||
// For each world
|
||||
for (Entry<String, Map<Faction, Set<PS>>> entry : worldFactionChunks.entrySet())
|
||||
{
|
||||
String world = entry.getKey();
|
||||
Map<Faction, Set<PS>> factionChunks = entry.getValue();
|
||||
|
||||
// For each faction and its chunks in that world
|
||||
for (Entry<Faction, Set<PS>> entry1 : factionChunks.entrySet())
|
||||
{
|
||||
Faction faction = entry1.getKey();
|
||||
Set<PS> chunks = entry1.getValue();
|
||||
Map<String, TempAreaMarker> worldFactionMarkers = createAreas(world, faction, chunks);
|
||||
ret.putAll(worldFactionMarkers);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Thread Safe: YES
|
||||
// Handle specific faction on specific world
|
||||
// "handle faction on world"
|
||||
public Map<String, TempAreaMarker> createAreas(String world, Faction faction, Set<PS> chunks)
|
||||
{
|
||||
Map<String, TempAreaMarker> ret = new HashMap<String, TempAreaMarker>();
|
||||
|
||||
// If the faction is visible ...
|
||||
if (!isVisible(faction, world)) return ret;
|
||||
|
||||
// ... and has any chunks ...
|
||||
if (chunks.isEmpty()) return ret;
|
||||
|
||||
// Index of polygon for given faction
|
||||
int markerIndex = 0;
|
||||
|
||||
// Create the info window
|
||||
String description = getDescription(faction);
|
||||
|
||||
// Fetch Style
|
||||
DynmapStyle style = this.getStyle(faction);
|
||||
|
||||
// Loop through chunks: set flags on chunk map
|
||||
TileFlags allChunkFlags = new TileFlags();
|
||||
LinkedList<PS> allChunks = new LinkedList<PS>();
|
||||
for (PS chunk : chunks)
|
||||
{
|
||||
allChunkFlags.setFlag(chunk.getChunkX(), chunk.getChunkZ(), true); // Set flag for chunk
|
||||
allChunks.addLast(chunk);
|
||||
}
|
||||
|
||||
// Loop through until we don't find more areas
|
||||
while (allChunks != null)
|
||||
{
|
||||
TileFlags ourChunkFlags = null;
|
||||
LinkedList<PS> ourChunks = null;
|
||||
LinkedList<PS> newChunks = null;
|
||||
|
||||
int minimumX = Integer.MAX_VALUE;
|
||||
int minimumZ = Integer.MAX_VALUE;
|
||||
for (PS chunk : allChunks)
|
||||
{
|
||||
int chunkX = chunk.getChunkX();
|
||||
int chunkZ = chunk.getChunkZ();
|
||||
|
||||
// If we need to start shape, and this block is not part of one yet
|
||||
if (ourChunkFlags == null && allChunkFlags.getFlag(chunkX, chunkZ))
|
||||
{
|
||||
ourChunkFlags = new TileFlags(); // Create map for shape
|
||||
ourChunks = new LinkedList<PS>();
|
||||
floodFillTarget(allChunkFlags, ourChunkFlags, chunkX, chunkZ); // Copy shape
|
||||
ourChunks.add(chunk); // Add it to our chunk list
|
||||
minimumX = chunkX;
|
||||
minimumZ = chunkZ;
|
||||
}
|
||||
// If shape found, and we're in it, add to our node list
|
||||
else if (ourChunkFlags != null && ourChunkFlags.getFlag(chunkX, chunkZ))
|
||||
{
|
||||
ourChunks.add(chunk);
|
||||
if (chunkX < minimumX)
|
||||
{
|
||||
minimumX = chunkX;
|
||||
minimumZ = chunkZ;
|
||||
}
|
||||
else if (chunkX == minimumX && chunkZ < minimumZ)
|
||||
{
|
||||
minimumZ = chunkZ;
|
||||
}
|
||||
}
|
||||
// Else, keep it in the list for the next polygon
|
||||
else
|
||||
{
|
||||
if (newChunks == null) newChunks = new LinkedList<PS>();
|
||||
newChunks.add(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace list (null if no more to process)
|
||||
allChunks = newChunks;
|
||||
|
||||
if (ourChunkFlags == null) continue;
|
||||
|
||||
// Trace outline of blocks - start from minx, minz going to x+
|
||||
int initialX = minimumX;
|
||||
int initialZ = minimumZ;
|
||||
int currentX = minimumX;
|
||||
int currentZ = minimumZ;
|
||||
Direction direction = Direction.XPLUS;
|
||||
ArrayList<int[]> linelist = new ArrayList<int[]>();
|
||||
linelist.add(new int[]{ initialX, initialZ }); // Add start point
|
||||
while ((currentX != initialX) || (currentZ != initialZ) || (direction != Direction.ZMINUS))
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case XPLUS: // Segment in X+ direction
|
||||
if (!ourChunkFlags.getFlag(currentX + 1, currentZ))
|
||||
{ // Right turn?
|
||||
linelist.add(new int[]{ currentX + 1, currentZ }); // Finish line
|
||||
direction = Direction.ZPLUS; // Change direction
|
||||
}
|
||||
else if (!ourChunkFlags.getFlag(currentX + 1, currentZ - 1))
|
||||
{ // Straight?
|
||||
currentX++;
|
||||
}
|
||||
else
|
||||
{ // Left turn
|
||||
linelist.add(new int[]{ currentX + 1, currentZ }); // Finish line
|
||||
direction = Direction.ZMINUS;
|
||||
currentX++;
|
||||
currentZ--;
|
||||
}
|
||||
break;
|
||||
case ZPLUS: // Segment in Z+ direction
|
||||
if (!ourChunkFlags.getFlag(currentX, currentZ + 1))
|
||||
{ // Right turn?
|
||||
linelist.add(new int[]{ currentX + 1, currentZ + 1 }); // Finish line
|
||||
direction = Direction.XMINUS; // Change direction
|
||||
}
|
||||
else if (!ourChunkFlags.getFlag(currentX + 1, currentZ + 1))
|
||||
{ // Straight?
|
||||
currentZ++;
|
||||
}
|
||||
else
|
||||
{ // Left turn
|
||||
linelist.add(new int[]{ currentX + 1, currentZ + 1 }); // Finish line
|
||||
direction = Direction.XPLUS;
|
||||
currentX++;
|
||||
currentZ++;
|
||||
}
|
||||
break;
|
||||
case XMINUS: // Segment in X- direction
|
||||
if (!ourChunkFlags.getFlag(currentX - 1, currentZ))
|
||||
{ // Right turn?
|
||||
linelist.add(new int[]{ currentX, currentZ + 1 }); // Finish line
|
||||
direction = Direction.ZMINUS; // Change direction
|
||||
}
|
||||
else if (!ourChunkFlags.getFlag(currentX - 1, currentZ + 1))
|
||||
{ // Straight?
|
||||
currentX--;
|
||||
}
|
||||
else
|
||||
{ // Left turn
|
||||
linelist.add(new int[] { currentX, currentZ + 1 }); // Finish line
|
||||
direction = Direction.ZPLUS;
|
||||
currentX--;
|
||||
currentZ++;
|
||||
}
|
||||
break;
|
||||
case ZMINUS: // Segment in Z- direction
|
||||
if (!ourChunkFlags.getFlag(currentX, currentZ - 1))
|
||||
{ // Right turn?
|
||||
linelist.add(new int[]{ currentX, currentZ }); // Finish line
|
||||
direction = Direction.XPLUS; // Change direction
|
||||
}
|
||||
else if (!ourChunkFlags.getFlag(currentX - 1, currentZ - 1))
|
||||
{ // Straight?
|
||||
currentZ--;
|
||||
}
|
||||
else
|
||||
{ // Left turn
|
||||
linelist.add(new int[] { currentX, currentZ }); // Finish line
|
||||
direction = Direction.XMINUS;
|
||||
currentX--;
|
||||
currentZ--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int sz = linelist.size();
|
||||
double[] x = new double[sz];
|
||||
double[] z = new double[sz];
|
||||
for (int i = 0; i < sz; i++)
|
||||
{
|
||||
int[] line = linelist.get(i);
|
||||
x[i] = (double) line[0] * (double) BLOCKS_PER_CHUNK;
|
||||
z[i] = (double) line[1] * (double) BLOCKS_PER_CHUNK;
|
||||
}
|
||||
|
||||
// Build information for specific area
|
||||
String markerId = FACTIONS_ + world + "__" + faction.getId() + "__" + markerIndex;
|
||||
|
||||
TempAreaMarker temp = new TempAreaMarker();
|
||||
temp.label = faction.getName();
|
||||
temp.world = world;
|
||||
temp.x = x;
|
||||
temp.z = z;
|
||||
temp.description = description;
|
||||
|
||||
temp.lineColor = style.getLineColor();
|
||||
temp.lineOpacity = style.getLineOpacity();
|
||||
temp.lineWeight = style.getLineWeight();
|
||||
|
||||
temp.fillColor = style.getFillColor();
|
||||
temp.fillOpacity = style.getFillOpacity();
|
||||
|
||||
temp.boost = style.getBoost();
|
||||
|
||||
ret.put(markerId, temp);
|
||||
|
||||
markerIndex++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Thread Safe: NO
|
||||
public void updateAreas(Map<String, TempAreaMarker> areas)
|
||||
{
|
||||
// Map Current
|
||||
Map<String, AreaMarker> markers = new HashMap<String, AreaMarker>();
|
||||
for (AreaMarker marker : this.markerset.getAreaMarkers())
|
||||
{
|
||||
markers.put(marker.getMarkerID(), marker);
|
||||
}
|
||||
|
||||
// Loop New
|
||||
for (Entry<String, TempAreaMarker> entry : areas.entrySet())
|
||||
{
|
||||
String markerId = entry.getKey();
|
||||
TempAreaMarker temp = entry.getValue();
|
||||
|
||||
// Get Creative
|
||||
// NOTE: I remove from the map created just in the beginning of this method.
|
||||
// NOTE: That way what is left at the end will be outdated markers to remove.
|
||||
AreaMarker marker = markers.remove(markerId);
|
||||
if (marker == null)
|
||||
{
|
||||
marker = temp.create(this.markerApi, this.markerset, markerId);
|
||||
if (marker == null)
|
||||
{
|
||||
severe("Could not get/create the area marker " + markerId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.update(this.markerApi, this.markerset, marker);
|
||||
}
|
||||
}
|
||||
|
||||
// Only old/outdated should now be left. Delete them.
|
||||
for (AreaMarker marker : markers.values())
|
||||
{
|
||||
marker.deleteMarker();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UPDATE: PLAYERSET
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
public String createPlayersetId(Faction faction)
|
||||
{
|
||||
if (faction == null) return null;
|
||||
if (faction.isNone()) return null;
|
||||
String factionId = faction.getId();
|
||||
if (factionId == null) return null;
|
||||
return FACTIONS_PLAYERSET_ + factionId;
|
||||
}
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
public Set<String> createPlayerset(Faction faction)
|
||||
{
|
||||
if (faction == null) return null;
|
||||
if (faction.isNone()) return null;
|
||||
|
||||
Set<String> ret = new HashSet<String>();
|
||||
|
||||
for (UPlayer uplayer : faction.getUPlayers())
|
||||
{
|
||||
// NOTE: We add both UUID and name. This might be a good idea for future proofing.
|
||||
ret.add(uplayer.getId());
|
||||
ret.add(uplayer.getName());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
public Map<String, Set<String>> createPlayersets()
|
||||
{
|
||||
if (!MConf.get().dynmapVisibilityByFaction) return null;
|
||||
|
||||
Map<String, Set<String>> ret = new HashMap<String, Set<String>>();
|
||||
|
||||
for (FactionColl coll : FactionColls.get().getColls())
|
||||
{
|
||||
for (Faction faction : coll.getAll())
|
||||
{
|
||||
String playersetId = createPlayersetId(faction);
|
||||
if (playersetId == null) continue;
|
||||
Set<String> playerIds = createPlayerset(faction);
|
||||
if (playerIds == null) continue;
|
||||
ret.put(playersetId, playerIds);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Thread Safe / Asynchronous: No
|
||||
public void updatePlayersets(Map<String, Set<String>> playersets)
|
||||
{
|
||||
// Remove
|
||||
for (PlayerSet set : this.markerApi.getPlayerSets())
|
||||
{
|
||||
if (!set.getSetID().startsWith(FACTIONS_PLAYERSET_)) continue;
|
||||
|
||||
// (Null means remove all)
|
||||
if (playersets != null && playersets.containsKey(set.getSetID())) continue;
|
||||
|
||||
set.deleteSet();
|
||||
}
|
||||
|
||||
// Add / Update
|
||||
for (Entry<String, Set<String>> entry : playersets.entrySet())
|
||||
{
|
||||
// Extract from Entry
|
||||
String setId = entry.getKey();
|
||||
Set<String> playerIds = entry.getValue();
|
||||
|
||||
// Get Creatively
|
||||
PlayerSet set = this.markerApi.getPlayerSet(setId);
|
||||
if (set == null) set = this.markerApi.createPlayerSet(
|
||||
setId, // id
|
||||
true, // symmetric
|
||||
playerIds, // players
|
||||
false // persistent
|
||||
);
|
||||
if (set == null)
|
||||
{
|
||||
severe("Could not get/create the player set " + setId);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set Content
|
||||
set.setPlayers(playerIds);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UTIL & SHARED
|
||||
// -------------------------------------------- //
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
private String getDescription(Faction faction)
|
||||
{
|
||||
String ret = "<div class=\"regioninfo\">" + MConf.get().dynmapDescription + "</div>";
|
||||
|
||||
// Name
|
||||
String name = faction.getName();
|
||||
name = ChatColor.stripColor(name);
|
||||
name = escapeHtml(name);
|
||||
ret = ret.replace("%name%", name);
|
||||
|
||||
// Description
|
||||
String description = faction.getDescription();
|
||||
description = ChatColor.stripColor(description);
|
||||
description = escapeHtml(description);
|
||||
ret = ret.replace("%description%", description);
|
||||
|
||||
// Age
|
||||
long ageMillis = faction.getCreatedAtMillis() - System.currentTimeMillis();
|
||||
LinkedHashMap<TimeUnit, Long> ageUnitcounts = TimeDiffUtil.limit(TimeDiffUtil.unitcounts(ageMillis, TimeUnit.getAllButMillisSecondsAndMinutes()), 3);
|
||||
String age = TimeDiffUtil.formatedVerboose(ageUnitcounts, "");
|
||||
age = ChatColor.stripColor(age);
|
||||
ret = ret.replace("%age%", age);
|
||||
|
||||
// Money
|
||||
String money = "unavailable";
|
||||
if (UConf.get(faction).bankEnabled && MConf.get().dynmapDescriptionMoney)
|
||||
{
|
||||
money = Money.format(Money.get(faction));
|
||||
}
|
||||
ret = ret.replace("%money%", money);
|
||||
|
||||
// Flags and Open
|
||||
Map<String, Boolean> flags = new HashMap<String, Boolean>();
|
||||
flags.put("open", faction.isOpen());
|
||||
for (FFlag fflag : FFlag.values())
|
||||
{
|
||||
flags.put(fflag.getNicename(), faction.getFlag(fflag));
|
||||
}
|
||||
for (Entry<String, Boolean> entry : flags.entrySet())
|
||||
{
|
||||
String flag = entry.getKey();
|
||||
boolean value = entry.getValue();
|
||||
|
||||
String bool = String.valueOf(value);
|
||||
String color = boolcolor(flag, value);
|
||||
String boolcolor = boolcolor(String.valueOf(value), value);
|
||||
|
||||
ret = ret.replace("%" + flag + ".bool%", bool);
|
||||
ret = ret.replace("%" + flag + ".color%", color);
|
||||
ret = ret.replace("%" + flag + ".boolcolor%", boolcolor);
|
||||
}
|
||||
|
||||
// Players
|
||||
List<UPlayer> playersList = faction.getUPlayers();
|
||||
String playersCount = String.valueOf(playersList.size());
|
||||
String players = getPlayerString(playersList);
|
||||
|
||||
UPlayer playersLeaderObject = faction.getLeader();
|
||||
String playersLeader = getPlayerName(playersLeaderObject);
|
||||
|
||||
List<UPlayer> playersOfficersList = faction.getUPlayersWhereRole(Rel.OFFICER);
|
||||
String playersOfficersCount = String.valueOf(playersOfficersList.size());
|
||||
String playersOfficers = getPlayerString(playersOfficersList);
|
||||
|
||||
List<UPlayer> playersMembersList = faction.getUPlayersWhereRole(Rel.MEMBER);
|
||||
String playersMembersCount = String.valueOf(playersMembersList.size());
|
||||
String playersMembers = getPlayerString(playersMembersList);
|
||||
|
||||
List<UPlayer> playersRecruitsList = faction.getUPlayersWhereRole(Rel.RECRUIT);
|
||||
String playersRecruitsCount = String.valueOf(playersRecruitsList.size());
|
||||
String playersRecruits = getPlayerString(playersRecruitsList);
|
||||
|
||||
|
||||
ret = ret.replace("%players%", players);
|
||||
ret = ret.replace("%players.count%", playersCount);
|
||||
ret = ret.replace("%players.leader%", playersLeader);
|
||||
ret = ret.replace("%players.officers%", playersOfficers);
|
||||
ret = ret.replace("%players.officers.count%", playersOfficersCount);
|
||||
ret = ret.replace("%players.members%", playersMembers);
|
||||
ret = ret.replace("%players.members.count%", playersMembersCount);
|
||||
ret = ret.replace("%players.recruits%", playersRecruits);
|
||||
ret = ret.replace("%players.recruits.count%", playersRecruitsCount);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String getPlayerString(List<UPlayer> uplayers)
|
||||
{
|
||||
String ret = "";
|
||||
for (UPlayer uplayer : uplayers)
|
||||
{
|
||||
if (ret.length() > 0) ret += ", ";
|
||||
ret += getPlayerName(uplayer);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String getPlayerName(UPlayer uplayer)
|
||||
{
|
||||
if (uplayer == null) return "none";
|
||||
return escapeHtml(uplayer.getName());
|
||||
}
|
||||
|
||||
public static String boolcolor(String string, boolean bool)
|
||||
{
|
||||
return "<span style=\"color: " + (bool ? "#008000" : "#800000") + ";\">" + string + "</span>";
|
||||
}
|
||||
|
||||
public static String escapeHtml(String string)
|
||||
{
|
||||
StringBuilder out = new StringBuilder(Math.max(16, string.length()));
|
||||
for (int i = 0; i < string.length(); i++)
|
||||
{
|
||||
char c = string.charAt(i);
|
||||
if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&')
|
||||
{
|
||||
out.append("&#");
|
||||
out.append((int) c);
|
||||
out.append(';');
|
||||
}
|
||||
else
|
||||
{
|
||||
out.append(c);
|
||||
}
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
private boolean isVisible(Faction faction, String world)
|
||||
{
|
||||
if (faction == null) return false;
|
||||
final String factionId = faction.getId();
|
||||
if (factionId == null) return false;
|
||||
final String factionName = faction.getName();
|
||||
if (factionName == null) return false;
|
||||
|
||||
Set<String> visible = MConf.get().dynmapVisibleFactions;
|
||||
Set<String> hidden = MConf.get().dynmapHiddenFactions;
|
||||
|
||||
if (visible.size() > 0)
|
||||
{
|
||||
if (!visible.contains(factionId) && !visible.contains(factionName) && !visible.contains("world:" + world))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (hidden.size() > 0)
|
||||
{
|
||||
if (hidden.contains(factionId) || hidden.contains(factionName) || hidden.contains("world:" + world))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
public DynmapStyle getStyle(Faction faction)
|
||||
{
|
||||
DynmapStyle ret;
|
||||
|
||||
ret = MConf.get().dynmapFactionStyles.get(faction.getId());
|
||||
if (ret != null) return ret;
|
||||
|
||||
ret = MConf.get().dynmapFactionStyles.get(faction.getName());
|
||||
if (ret != null) return ret;
|
||||
|
||||
return MConf.get().dynmapDefaultStyle;
|
||||
}
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
public static void info(String msg)
|
||||
{
|
||||
String message = DYNMAP_INTEGRATION + msg;
|
||||
Factions.get().log(message);
|
||||
}
|
||||
|
||||
// Thread Safe / Asynchronous: Yes
|
||||
public static void severe(String msg)
|
||||
{
|
||||
String message = DYNMAP_INTEGRATION + ChatColor.RED.toString() + msg;
|
||||
Factions.get().log(message);
|
||||
}
|
||||
|
||||
enum Direction
|
||||
{
|
||||
XPLUS, ZPLUS, XMINUS, ZMINUS
|
||||
};
|
||||
|
||||
// Find all contiguous blocks, set in target and clear in source
|
||||
private int floodFillTarget(TileFlags source, TileFlags destination, int x, int y)
|
||||
{
|
||||
int cnt = 0;
|
||||
ArrayDeque<int[]> stack = new ArrayDeque<int[]>();
|
||||
stack.push(new int[] { x, y });
|
||||
|
||||
while (stack.isEmpty() == false)
|
||||
{
|
||||
int[] nxt = stack.pop();
|
||||
x = nxt[0];
|
||||
y = nxt[1];
|
||||
if (source.getFlag(x, y))
|
||||
{ // Set in src
|
||||
source.setFlag(x, y, false); // Clear source
|
||||
destination.setFlag(x, y, true); // Set in destination
|
||||
cnt++;
|
||||
if (source.getFlag(x + 1, y)) stack.push(new int[] { x + 1, y });
|
||||
if (source.getFlag(x - 1, y)) stack.push(new int[] { x - 1, y });
|
||||
if (source.getFlag(x, y + 1)) stack.push(new int[] { x, y + 1 });
|
||||
if (source.getFlag(x, y - 1)) stack.push(new int[] { x, y - 1 });
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package com.massivecraft.factions.integration.dynmap;
|
||||
|
||||
import com.massivecraft.massivecore.integration.IntegrationAbstract;
|
||||
|
||||
public class IntegrationDynmap extends IntegrationAbstract
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static IntegrationDynmap i = new IntegrationDynmap();
|
||||
public static IntegrationDynmap get() { return i; }
|
||||
private IntegrationDynmap() { super("dynmap"); }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public void activate()
|
||||
{
|
||||
EngineDynmap.get().activate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate()
|
||||
{
|
||||
EngineDynmap.get().deactivate();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
package com.massivecraft.factions.integration.dynmap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.massivecore.integration.IntegrationAbstract;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
|
||||
public class IntegrationDynmapFactions extends IntegrationAbstract
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static IntegrationDynmapFactions i = new IntegrationDynmapFactions();
|
||||
public static IntegrationDynmapFactions get() { return i; }
|
||||
private IntegrationDynmapFactions() { super("Dynmap-Factions"); }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public void activate()
|
||||
{
|
||||
// Time for an error message!
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Factions.get(), new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Factions.get().log(Txt.parse("<b>I see you have the plugin Dynmap-Factions installed!"));
|
||||
Factions.get().log(Txt.parse("<b>That plugin is no longer required for Dynmap features."));
|
||||
Factions.get().log(Txt.parse("<b>Factions now ship with it's own Dynmap integration."));
|
||||
Factions.get().log(Txt.parse("<b>Now disabling Dynmap-Factions for you:"));
|
||||
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin("Dynmap-Factions");
|
||||
Bukkit.getPluginManager().disablePlugin(plugin);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,138 @@
|
||||
package com.massivecraft.factions.integration.dynmap;
|
||||
|
||||
import org.dynmap.markers.AreaMarker;
|
||||
import org.dynmap.markers.MarkerAPI;
|
||||
import org.dynmap.markers.MarkerSet;
|
||||
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
|
||||
public class TempAreaMarker
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// FIELDS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public String label;
|
||||
public String world;
|
||||
public double x[];
|
||||
public double z[];
|
||||
public String description;
|
||||
|
||||
public int lineColor;
|
||||
public double lineOpacity;
|
||||
public int lineWeight;
|
||||
|
||||
public int fillColor;
|
||||
public double fillOpacity;
|
||||
|
||||
public boolean boost;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CREATE
|
||||
// -------------------------------------------- //
|
||||
|
||||
public AreaMarker create(MarkerAPI markerApi, MarkerSet markerset, String markerId)
|
||||
{
|
||||
AreaMarker ret = markerset.createAreaMarker(
|
||||
markerId,
|
||||
this.label,
|
||||
false,
|
||||
this.world,
|
||||
this.x,
|
||||
this.z,
|
||||
false // not persistent
|
||||
);
|
||||
|
||||
if (ret == null) return null;
|
||||
|
||||
// Description
|
||||
ret.setDescription(this.description);
|
||||
|
||||
// Line Style
|
||||
ret.setLineStyle(this.lineWeight, this.lineOpacity, this.lineColor);
|
||||
|
||||
// Fill Style
|
||||
ret.setFillStyle(this.fillOpacity, this.fillColor);
|
||||
|
||||
// Boost Flag
|
||||
ret.setBoostFlag(this.boost);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UPDATE
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void update(MarkerAPI markerApi, MarkerSet markerset, AreaMarker marker)
|
||||
{
|
||||
// Corner Locations
|
||||
if (!equals(marker, this.x, this.z))
|
||||
{
|
||||
marker.setCornerLocations(this.x, this.z);
|
||||
}
|
||||
|
||||
// Label
|
||||
if (!MUtil.equals(marker.getLabel(), this.label))
|
||||
{
|
||||
marker.setLabel(this.label);
|
||||
}
|
||||
|
||||
// Description
|
||||
if (!MUtil.equals(marker.getDescription(), this.description))
|
||||
{
|
||||
marker.setDescription(this.description);
|
||||
}
|
||||
|
||||
// Line Style
|
||||
if
|
||||
(
|
||||
!MUtil.equals(marker.getLineWeight(), this.lineWeight)
|
||||
||
|
||||
!MUtil.equals(marker.getLineOpacity(), this.lineOpacity)
|
||||
||
|
||||
!MUtil.equals(marker.getLineColor(), this.lineColor)
|
||||
)
|
||||
{
|
||||
marker.setLineStyle(this.lineWeight, this.lineOpacity, this.lineColor);
|
||||
}
|
||||
|
||||
// Fill Style
|
||||
if
|
||||
(
|
||||
!MUtil.equals(marker.getFillOpacity(), this.fillOpacity)
|
||||
||
|
||||
!MUtil.equals(marker.getFillColor(), this.fillColor)
|
||||
)
|
||||
{
|
||||
marker.setFillStyle(this.fillOpacity, this.fillColor);
|
||||
}
|
||||
|
||||
// Boost Flag
|
||||
if (!MUtil.equals(marker.getBoostFlag(), this.boost))
|
||||
{
|
||||
marker.setBoostFlag(this.boost);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UTIL
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static boolean equals(AreaMarker marker, double x[], double z[])
|
||||
{
|
||||
int length = marker.getCornerCount();
|
||||
|
||||
if (x.length != length) return false;
|
||||
if (z.length != length) return false;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if (marker.getCornerX(i) != x[i]) return false;
|
||||
if (marker.getCornerZ(i) != z[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
package com.massivecraft.factions.integration.dynmap;
|
||||
|
||||
import org.dynmap.markers.Marker;
|
||||
import org.dynmap.markers.MarkerAPI;
|
||||
import org.dynmap.markers.MarkerIcon;
|
||||
import org.dynmap.markers.MarkerSet;
|
||||
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
|
||||
public class TempMarker
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// FIELDS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public String label;
|
||||
public String world;
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
public String iconName;
|
||||
public String description;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CREATE
|
||||
// -------------------------------------------- //
|
||||
|
||||
public Marker create(MarkerAPI markerApi, MarkerSet markerset, String markerId)
|
||||
{
|
||||
Marker ret = markerset.createMarker(
|
||||
markerId,
|
||||
this.label,
|
||||
this.world,
|
||||
this.x,
|
||||
this.y,
|
||||
this.z,
|
||||
getMarkerIcon(markerApi, this.iconName),
|
||||
false // not persistent
|
||||
);
|
||||
|
||||
if (ret == null) return null;
|
||||
|
||||
ret.setDescription(this.description);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UPDATE
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void update(MarkerAPI markerApi, MarkerSet markerset, Marker marker)
|
||||
{
|
||||
if
|
||||
(
|
||||
marker.getWorld() != this.world
|
||||
||
|
||||
marker.getX() != this.x
|
||||
||
|
||||
marker.getY() != this.y
|
||||
||
|
||||
marker.getZ() != this.z
|
||||
)
|
||||
{
|
||||
marker.setLocation(
|
||||
this.world,
|
||||
this.x,
|
||||
this.y,
|
||||
this.z
|
||||
);
|
||||
}
|
||||
|
||||
if (!MUtil.equals(marker.getLabel(), this.label))
|
||||
{
|
||||
marker.setLabel(this.label);
|
||||
}
|
||||
|
||||
MarkerIcon icon = getMarkerIcon(markerApi, this.iconName);
|
||||
if (!MUtil.equals(marker.getMarkerIcon(), icon))
|
||||
{
|
||||
marker.setMarkerIcon(icon);
|
||||
}
|
||||
|
||||
if (!MUtil.equals(marker.getDescription(), this.description))
|
||||
{
|
||||
marker.setDescription(this.description);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UTIL
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static MarkerIcon getMarkerIcon(MarkerAPI markerApi, String name)
|
||||
{
|
||||
MarkerIcon ret = markerApi.getMarkerIcon(name);
|
||||
if (ret == null) ret = markerApi.getMarkerIcon(MConf.DYNMAP_STYLE_HOME_MARKER);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,78 @@
|
||||
package com.massivecraft.factions.integration.dynmap;
|
||||
|
||||
import org.dynmap.markers.MarkerAPI;
|
||||
import org.dynmap.markers.MarkerSet;
|
||||
|
||||
import com.massivecraft.massivecore.util.MUtil;
|
||||
|
||||
public class TempMarkerSet
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// FIELDS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public String label;
|
||||
public int minimumZoom;
|
||||
public int priority;
|
||||
public boolean hideByDefault;
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CREATE
|
||||
// -------------------------------------------- //
|
||||
|
||||
public MarkerSet create(MarkerAPI markerApi, String id)
|
||||
{
|
||||
MarkerSet ret = markerApi.createMarkerSet(id, this.label, null, false); // ("null, false" at the end means "all icons allowed, not perisistent")
|
||||
|
||||
if (ret == null) return null;
|
||||
|
||||
// Minimum Zoom
|
||||
if (this.minimumZoom > 0)
|
||||
{
|
||||
ret.setMinZoom(this.minimumZoom);
|
||||
}
|
||||
|
||||
// Priority
|
||||
ret.setLayerPriority(this.priority);
|
||||
|
||||
// Hide by Default
|
||||
ret.setHideByDefault(this.hideByDefault);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UPDATE
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void update(MarkerAPI markerApi, MarkerSet markerset)
|
||||
{
|
||||
// Name
|
||||
if (!MUtil.equals(markerset.getMarkerSetLabel(), this.label))
|
||||
{
|
||||
markerset.setMarkerSetLabel(this.label);
|
||||
}
|
||||
|
||||
// Minimum Zoom
|
||||
if (this.minimumZoom > 0)
|
||||
{
|
||||
if (!MUtil.equals(markerset.getMinZoom(), this.minimumZoom))
|
||||
{
|
||||
markerset.setMinZoom(this.minimumZoom);
|
||||
}
|
||||
}
|
||||
|
||||
// Priority
|
||||
if (!MUtil.equals(markerset.getLayerPriority(), this.priority))
|
||||
{
|
||||
markerset.setLayerPriority(this.priority);
|
||||
}
|
||||
|
||||
// Hide by Default
|
||||
if (!MUtil.equals(markerset.getHideByDefault(), this.hideByDefault))
|
||||
{
|
||||
markerset.setHideByDefault(this.hideByDefault);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,371 @@
|
||||
package com.massivecraft.factions.integration.herochat;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.dthielke.herochat.Channel;
|
||||
import com.dthielke.herochat.ChannelChatEvent;
|
||||
import com.dthielke.herochat.ChannelStorage;
|
||||
import com.dthielke.herochat.ChatCompleteEvent;
|
||||
import com.dthielke.herochat.Chatter;
|
||||
import com.dthielke.herochat.Herochat;
|
||||
import com.dthielke.herochat.MessageFormatSupplier;
|
||||
import com.dthielke.herochat.MessageNotFoundException;
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.entity.UPlayer;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
|
||||
public abstract class ChannelFactionsAbstract implements Channel
|
||||
{
|
||||
private static final Pattern msgPattern = Pattern.compile("(.*)<(.*)%1\\$s(.*)> %2\\$s");
|
||||
private final ChannelStorage storage = Herochat.getChannelManager().getStorage();
|
||||
private final MessageFormatSupplier formatSupplier = Herochat.getChannelManager();
|
||||
|
||||
@Override
|
||||
public boolean addMember(Chatter chatter, boolean announce, boolean flagUpdate)
|
||||
{
|
||||
if (chatter.hasChannel(this)) return false;
|
||||
|
||||
if ((announce) && (this.isVerbose()))
|
||||
{
|
||||
try
|
||||
{
|
||||
this.announce(Herochat.getMessage("channel_join").replace("$1", chatter.getPlayer().getDisplayName()));
|
||||
}
|
||||
catch (MessageNotFoundException e)
|
||||
{
|
||||
Herochat.severe("Messages.properties is missing: channel_join");
|
||||
}
|
||||
}
|
||||
|
||||
chatter.addChannel(this, announce, flagUpdate);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean kickMember(Chatter chatter, boolean announce)
|
||||
{
|
||||
if (!chatter.hasChannel(this)) return false;
|
||||
this.removeMember(chatter, false, true);
|
||||
|
||||
if (announce)
|
||||
{
|
||||
try
|
||||
{
|
||||
announce(Herochat.getMessage("channel_kick").replace("$1", chatter.getPlayer().getDisplayName()));
|
||||
}
|
||||
catch (MessageNotFoundException e)
|
||||
{
|
||||
Herochat.severe("Messages.properties is missing: channel_kick");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeMember(Chatter chatter, boolean announce, boolean flagUpdate)
|
||||
{
|
||||
if (!chatter.hasChannel(this)) return false;
|
||||
chatter.removeChannel(this, announce, flagUpdate);
|
||||
|
||||
if (announce && this.isVerbose())
|
||||
{
|
||||
try
|
||||
{
|
||||
this.announce(Herochat.getMessage("channel_leave").replace("$1", chatter.getPlayer().getDisplayName()));
|
||||
}
|
||||
catch (MessageNotFoundException e)
|
||||
{
|
||||
Herochat.severe("Messages.properties is missing: channel_leave");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Chatter> getMembers()
|
||||
{
|
||||
Set<Chatter> ret = new HashSet<Chatter>();
|
||||
for (Chatter chatter : Herochat.getChatterManager().getChatters())
|
||||
{
|
||||
if(chatter.hasChannel(this)) ret.add(chatter);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void announce(String message)
|
||||
{
|
||||
String colorized = message.replaceAll("(?i)&([a-fklmno0-9])", "§$1");
|
||||
message = applyFormat(this.getFormatSupplier().getAnnounceFormat(), "").replace("%2$s", colorized);
|
||||
for (Chatter member : this.getMembers())
|
||||
{
|
||||
member.getPlayer().sendMessage(message);
|
||||
}
|
||||
Herochat.logChat(ChatColor.stripColor(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String applyFormat(String format, String originalFormat)
|
||||
{
|
||||
format = format.replace("{default}", this.getFormatSupplier().getStandardFormat());
|
||||
format = format.replace("{name}", this.getName());
|
||||
format = format.replace("{nick}", this.getNick());
|
||||
format = format.replace("{color}", this.getColor().toString());
|
||||
format = format.replace("{msg}", "%2$s");
|
||||
|
||||
Matcher matcher = msgPattern.matcher(originalFormat);
|
||||
if (matcher.matches() && matcher.groupCount() == 3)
|
||||
{
|
||||
format = format.replace("{sender}", matcher.group(1) + matcher.group(2) + "%1$s" + matcher.group(3));
|
||||
}
|
||||
else
|
||||
{
|
||||
format = format.replace("{sender}", "%1$s");
|
||||
}
|
||||
|
||||
format = format.replaceAll("(?i)&([a-fklmnor0-9])", "§$1");
|
||||
return format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String applyFormat(String format, String originalFormat, Player sender)
|
||||
{
|
||||
format = this.applyFormat(format, originalFormat);
|
||||
format = format.replace("{plainsender}", sender.getName());
|
||||
format = format.replace("{world}", sender.getWorld().getName());
|
||||
Chat chat = Herochat.getChatService();
|
||||
if (chat != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
String prefix = chat.getPlayerPrefix(sender);
|
||||
if (prefix == null || prefix == "")
|
||||
{
|
||||
prefix = chat.getPlayerPrefix((String)null, sender.getName());
|
||||
}
|
||||
String suffix = chat.getPlayerSuffix(sender);
|
||||
if (suffix == null || suffix == "")
|
||||
{
|
||||
suffix = chat.getPlayerSuffix((String)null, sender.getName());
|
||||
}
|
||||
String group = chat.getPrimaryGroup(sender);
|
||||
String groupPrefix = group == null ? "" : chat.getGroupPrefix(sender.getWorld(), group);
|
||||
if (group != null && (groupPrefix == null || groupPrefix == ""))
|
||||
{
|
||||
groupPrefix = chat.getGroupPrefix((String)null, group);
|
||||
}
|
||||
String groupSuffix = group == null ? "" : chat.getGroupSuffix(sender.getWorld(), group);
|
||||
if (group != null && (groupSuffix == null || groupSuffix == ""))
|
||||
{
|
||||
groupSuffix = chat.getGroupSuffix((String)null, group);
|
||||
}
|
||||
format = format.replace("{prefix}", prefix == null ? "" : prefix.replace("%", "%%"));
|
||||
format = format.replace("{suffix}", suffix == null ? "" : suffix.replace("%", "%%"));
|
||||
format = format.replace("{group}", group == null ? "" : group.replace("%", "%%"));
|
||||
format = format.replace("{groupprefix}", groupPrefix == null ? "" : groupPrefix.replace("%", "%%"));
|
||||
format = format.replace("{groupsuffix}", groupSuffix == null ? "" : groupSuffix.replace("%", "%%"));
|
||||
}
|
||||
catch (UnsupportedOperationException ignored)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
format = format.replace("{prefix}", "");
|
||||
format = format.replace("{suffix}", "");
|
||||
format = format.replace("{group}", "");
|
||||
format = format.replace("{groupprefix}", "");
|
||||
format = format.replace("{groupsuffix}", "");
|
||||
}
|
||||
format = format.replaceAll("(?i)&([a-fklmno0-9])", "§$1");
|
||||
return format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emote(Chatter sender, String message)
|
||||
{
|
||||
message = this.applyFormat(this.getFormatSupplier().getEmoteFormat(), "").replace("%2$s", message);
|
||||
|
||||
Set<Player> recipients = new HashSet<Player>();
|
||||
for (Chatter member : this.getMembers())
|
||||
{
|
||||
recipients.add(member.getPlayer());
|
||||
}
|
||||
|
||||
this.trimRecipients(recipients, sender);
|
||||
|
||||
for (Player recipient : recipients)
|
||||
{
|
||||
recipient.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMuted(String name)
|
||||
{
|
||||
if (this.isMuted()) return true;
|
||||
return this.getMutes().contains(name.toLowerCase());
|
||||
}
|
||||
|
||||
public abstract Set<Rel> getTargetRelations();
|
||||
|
||||
public Set<Player> getRecipients(Player sender)
|
||||
{
|
||||
Set<Player> ret = new HashSet<Player>();
|
||||
|
||||
UPlayer fpsender = UPlayer.get(sender);
|
||||
Faction faction = fpsender.getFaction();
|
||||
String universe = fpsender.getUniverse();
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
UPlayer frecipient = UPlayer.get(player);
|
||||
if (!frecipient.getUniverse().equals(universe)) continue;
|
||||
if (!this.getTargetRelations().contains(faction.getRelationTo(frecipient))) continue;
|
||||
ret.add(player);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processChat(ChannelChatEvent event)
|
||||
{
|
||||
Player player = event.getSender().getPlayer();
|
||||
|
||||
String format = this.applyFormat(event.getFormat(), event.getBukkitFormat(), player);
|
||||
|
||||
Chatter sender = Herochat.getChatterManager().getChatter(player);
|
||||
|
||||
// NOTE: This line is not standard deobfuscation. It's altered to achieve the recipient limitations.
|
||||
Set<Player> recipients = this.getRecipients(player);
|
||||
|
||||
this.trimRecipients(recipients, sender);
|
||||
String msg = String.format(format, new Object[] { player.getDisplayName(), event.getMessage() });
|
||||
for (Player recipient : recipients)
|
||||
{
|
||||
recipient.sendMessage(msg);
|
||||
}
|
||||
|
||||
Bukkit.getPluginManager().callEvent(new ChatCompleteEvent(sender, this, msg));
|
||||
Herochat.logChat(msg);
|
||||
}
|
||||
|
||||
public boolean isMessageHeard(Set<Player> recipients, Chatter sender)
|
||||
{
|
||||
if (!isLocal()) return true;
|
||||
|
||||
Player senderPlayer = sender.getPlayer();
|
||||
for (Player recipient : recipients)
|
||||
{
|
||||
if (recipient.equals(senderPlayer)) continue;
|
||||
if (recipient.hasPermission("herochat.admin.stealth")) continue;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void trimRecipients(Set<Player> recipients, Chatter sender)
|
||||
{
|
||||
World world = sender.getPlayer().getWorld();
|
||||
|
||||
Set<Chatter> members = this.getMembers();
|
||||
Iterator<Player> iterator = recipients.iterator();
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
Chatter recipient = Herochat.getChatterManager().getChatter(iterator.next());
|
||||
if (recipient == null) continue;
|
||||
World recipientWorld = recipient.getPlayer().getWorld();
|
||||
|
||||
if (!members.contains(recipient))
|
||||
iterator.remove();
|
||||
else if ((isLocal()) && (!sender.isInRange(recipient, this.getDistance())))
|
||||
iterator.remove();
|
||||
else if (!hasWorld(recipientWorld))
|
||||
iterator.remove();
|
||||
else if (recipient.isIgnoring(sender))
|
||||
iterator.remove();
|
||||
else if ((!this.isCrossWorld()) && (!world.equals(recipientWorld)))
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
if (other == this) return true;
|
||||
if (other == null) return false;
|
||||
if (!(other instanceof Channel)) return false;
|
||||
Channel channel = (Channel)other;
|
||||
return (this.getName().equalsIgnoreCase(channel.getName())) || (this.getName().equalsIgnoreCase(channel.getNick()));
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (this.getName() == null ? 0 : this.getName().toLowerCase().hashCode());
|
||||
result = prime * result + (this.getNick() == null ? 0 : this.getNick().toLowerCase().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override public boolean isTransient() { return false; }
|
||||
@Override public String getPassword() { return ""; }
|
||||
@Override public void setPassword(String password) {}
|
||||
@Override public boolean isVerbose() { return false; }
|
||||
@Override public void setVerbose(boolean verbose) {}
|
||||
@Override public boolean isHidden() { return false; }
|
||||
@Override public boolean isLocal() { return this.getDistance() != 0; }
|
||||
@Override public void attachStorage(ChannelStorage storage) { }
|
||||
@Override public boolean banMember(Chatter chatter, boolean announce) { return false; }
|
||||
@Override public Set<String> getBans() { return Collections.emptySet(); }
|
||||
@Override public Set<String> getModerators() { return Collections.emptySet(); }
|
||||
@Override public Set<String> getMutes() { return Collections.emptySet(); }
|
||||
@Override public ChannelStorage getStorage() { return this.storage; }
|
||||
@Override public boolean hasWorld(String world) { return (this.getWorlds().isEmpty()) || (this.getWorlds().contains(world)); }
|
||||
@Override public boolean hasWorld(World world) { return this.hasWorld(world.getName()); }
|
||||
@Override public boolean isBanned(String name) { return this.getBans().contains(name.toLowerCase()); }
|
||||
@Override public boolean isMember(Chatter chatter) { return this.getMembers().contains(chatter); }
|
||||
@Override public boolean isModerator(String name) { return this.getModerators().contains(name.toLowerCase()); }
|
||||
|
||||
@Override public void onFocusGain(Chatter chatter) {}
|
||||
@Override public void onFocusLoss(Chatter chatter) {}
|
||||
|
||||
@Override public void removeWorld(String world) { this.getWorlds().remove(world); }
|
||||
@Override public void setBanned(String name, boolean banned) {}
|
||||
@Override public void setBans(Set<String> bans) {}
|
||||
@Override public void setModerator(String name, boolean moderator) {}
|
||||
@Override public void setModerators(Set<String> moderators) { }
|
||||
@Override public void setMuted(String name, boolean muted) {}
|
||||
@Override public void setMutes(Set<String> mutes) {}
|
||||
|
||||
@Override
|
||||
public MessageFormatSupplier getFormatSupplier()
|
||||
{
|
||||
return this.formatSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendRawMessage(String rawMessage)
|
||||
{
|
||||
for (Chatter member : this.getMembers())
|
||||
{
|
||||
member.getPlayer().sendMessage(rawMessage);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
package com.massivecraft.factions.integration.herochat;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
|
||||
public class ChannelFactionsAllies extends ChannelFactionsAbstract
|
||||
{
|
||||
public static final Set<Rel> targetRelations = EnumSet.of(Rel.MEMBER, Rel.RECRUIT, Rel.ALLY);
|
||||
@Override public Set<Rel> getTargetRelations() { return targetRelations; }
|
||||
|
||||
@Override public String getName() { return MConf.get().herochatAlliesName; }
|
||||
|
||||
@Override public String getNick() { return MConf.get().herochatAlliesNick; }
|
||||
@Override public void setNick(String nick) { MConf.get().herochatAlliesNick = nick; }
|
||||
|
||||
@Override public String getFormat() { return MConf.get().herochatAlliesFormat; }
|
||||
@Override public void setFormat(String format) { MConf.get().herochatAlliesFormat = format; }
|
||||
|
||||
@Override public ChatColor getColor() { return MConf.get().herochatAlliesColor; }
|
||||
@Override public void setColor(ChatColor color) { MConf.get().herochatAlliesColor = color; }
|
||||
|
||||
@Override public int getDistance() { return MConf.get().herochatAlliesDistance; }
|
||||
@Override public void setDistance(int distance) { MConf.get().herochatAlliesDistance = distance; }
|
||||
|
||||
@Override public void addWorld(String world) { MConf.get().herochatAlliesWorlds.add(world); }
|
||||
@Override public Set<String> getWorlds() { return MConf.get().herochatAlliesWorlds; }
|
||||
@Override public void setWorlds(Set<String> worlds) { MConf.get().herochatAlliesWorlds = worlds; }
|
||||
|
||||
@Override public boolean isShortcutAllowed() { return MConf.get().herochatAlliesIsShortcutAllowed; }
|
||||
@Override public void setShortcutAllowed(boolean shortcutAllowed) { MConf.get().herochatAlliesIsShortcutAllowed = shortcutAllowed; }
|
||||
|
||||
@Override public boolean isCrossWorld() { return MConf.get().herochatAlliesCrossWorld; }
|
||||
@Override public void setCrossWorld(boolean crossWorld) { MConf.get().herochatAlliesCrossWorld = crossWorld; }
|
||||
|
||||
@Override public boolean isMuted() { return MConf.get().herochatAlliesMuted; }
|
||||
@Override public void setMuted(boolean value) { MConf.get().herochatAlliesMuted = value; }
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
package com.massivecraft.factions.integration.herochat;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import com.massivecraft.factions.Rel;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
|
||||
public class ChannelFactionsFaction extends ChannelFactionsAbstract
|
||||
{
|
||||
public static final Set<Rel> targetRelations = EnumSet.of(Rel.MEMBER, Rel.RECRUIT);
|
||||
@Override public Set<Rel> getTargetRelations() { return targetRelations; }
|
||||
|
||||
@Override public String getName() { return MConf.get().herochatFactionName; }
|
||||
|
||||
@Override public String getNick() { return MConf.get().herochatFactionNick; }
|
||||
@Override public void setNick(String nick) { MConf.get().herochatFactionNick = nick; }
|
||||
|
||||
@Override public String getFormat() { return MConf.get().herochatFactionFormat; }
|
||||
@Override public void setFormat(String format) { MConf.get().herochatFactionFormat = format; }
|
||||
|
||||
@Override public ChatColor getColor() { return MConf.get().herochatFactionColor; }
|
||||
@Override public void setColor(ChatColor color) { MConf.get().herochatFactionColor = color; }
|
||||
|
||||
@Override public int getDistance() { return MConf.get().herochatFactionDistance; }
|
||||
@Override public void setDistance(int distance) { MConf.get().herochatFactionDistance = distance; }
|
||||
|
||||
@Override public void addWorld(String world) { MConf.get().herochatFactionWorlds.add(world); }
|
||||
@Override public Set<String> getWorlds() { return new HashSet<String>(MConf.get().herochatFactionWorlds); }
|
||||
@Override public void setWorlds(Set<String> worlds) { MConf.get().herochatFactionWorlds = worlds; }
|
||||
|
||||
@Override public boolean isShortcutAllowed() { return MConf.get().herochatFactionIsShortcutAllowed; }
|
||||
@Override public void setShortcutAllowed(boolean shortcutAllowed) { MConf.get().herochatFactionIsShortcutAllowed = shortcutAllowed; }
|
||||
|
||||
@Override public boolean isCrossWorld() { return MConf.get().herochatFactionCrossWorld; }
|
||||
@Override public void setCrossWorld(boolean crossWorld) { MConf.get().herochatFactionCrossWorld = crossWorld; }
|
||||
|
||||
@Override public boolean isMuted() { return MConf.get().herochatFactionMuted; }
|
||||
@Override public void setMuted(boolean value) { MConf.get().herochatFactionMuted = value; }
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
package com.massivecraft.factions.integration.herochat;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import com.dthielke.herochat.ChannelChatEvent;
|
||||
import com.dthielke.herochat.Herochat;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.chat.ChatFormatter;
|
||||
import com.massivecraft.factions.entity.MConf;
|
||||
|
||||
|
||||
public class EngineHerochat implements Listener
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineHerochat i = new EngineHerochat();
|
||||
public static EngineHerochat get() { return i; }
|
||||
private EngineHerochat() {}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// ACTIVATE & DEACTIVATE
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void activate()
|
||||
{
|
||||
Herochat.getChannelManager().addChannel(new ChannelFactionsFaction());
|
||||
Herochat.getChannelManager().addChannel(new ChannelFactionsAllies());
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(this, Factions.get());
|
||||
}
|
||||
|
||||
public void deactivate()
|
||||
{
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// LISTENER
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onChannelChatEvent(ChannelChatEvent event)
|
||||
{
|
||||
// Should we even parse?
|
||||
if ( ! MConf.get().chatParseTags) return;
|
||||
|
||||
String format = event.getFormat();
|
||||
|
||||
// We trigger a replace of HeroChats tag {default} here
|
||||
// This way we can replace faction tags hidden withing {default} as well.
|
||||
format = format.replace("{default}", event.getChannel().getFormatSupplier().getStandardFormat());
|
||||
|
||||
format = ChatFormatter.format(format, event.getSender().getPlayer(), null);
|
||||
event.setFormat(format);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package com.massivecraft.factions.integration.herochat;
|
||||
|
||||
import com.massivecraft.massivecore.integration.IntegrationAbstract;
|
||||
|
||||
public class IntegrationHerochat extends IntegrationAbstract
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static IntegrationHerochat i = new IntegrationHerochat();
|
||||
public static IntegrationHerochat get() { return i; }
|
||||
private IntegrationHerochat() { super("Herochat"); }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public void activate()
|
||||
{
|
||||
EngineHerochat.get().activate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate()
|
||||
{
|
||||
EngineHerochat.get().deactivate();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,116 @@
|
||||
package com.massivecraft.factions.integration.lwc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import com.griefcraft.lwc.LWC;
|
||||
import com.griefcraft.model.Protection;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.entity.Faction;
|
||||
import com.massivecraft.factions.entity.UConf;
|
||||
import com.massivecraft.factions.entity.UPlayer;
|
||||
import com.massivecraft.factions.event.EventFactionsChunkChange;
|
||||
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
|
||||
import com.massivecraft.massivecore.ps.PS;
|
||||
|
||||
|
||||
public class EngineLwc implements Listener
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static EngineLwc i = new EngineLwc();
|
||||
public static EngineLwc get() { return i; }
|
||||
private EngineLwc() {}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// ACTIVATE & DEACTIVATE
|
||||
// -------------------------------------------- //
|
||||
|
||||
public void activate()
|
||||
{
|
||||
Bukkit.getPluginManager().registerEvents(this, Factions.get());
|
||||
}
|
||||
|
||||
public void deactivate()
|
||||
{
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// LISTENER
|
||||
// -------------------------------------------- //
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void removeProtectionsOnChunkChange(EventFactionsChunkChange event)
|
||||
{
|
||||
// If we are supposed to clear at this chunk change type ...
|
||||
Faction newFaction = event.getNewFaction();
|
||||
UConf uconf = UConf.get(newFaction);
|
||||
EventFactionsChunkChangeType type = event.getType();
|
||||
Boolean remove = uconf.lwcRemoveOnChange.get(type);
|
||||
if (remove == null) return;
|
||||
if (remove == false) return;
|
||||
|
||||
// ... then remove for all other factions than the new one.
|
||||
removeAlienProtections(event.getChunk(), newFaction);
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// UTIL
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static void removeAlienProtections(PS chunkPs, Faction faction)
|
||||
{
|
||||
List<UPlayer> nonAliens = faction.getUPlayers();
|
||||
for (Protection protection : getProtectionsInChunk(chunkPs))
|
||||
{
|
||||
UPlayer owner = UPlayer.get(protection.getOwner());
|
||||
if (nonAliens.contains(owner)) continue;
|
||||
protection.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Protection> getProtectionsInChunk(PS chunkPs)
|
||||
{
|
||||
List<Protection> ret = new ArrayList<Protection>();
|
||||
|
||||
// Get the chunk
|
||||
Chunk chunk = null;
|
||||
try
|
||||
{
|
||||
chunk = chunkPs.asBukkitChunk(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (BlockState blockState : chunk.getTileEntities())
|
||||
{
|
||||
// TODO: Can something else be protected by LWC? Or is it really only chests?
|
||||
// TODO: How about we run through each block in the chunk just to be on the safe side?
|
||||
if (blockState.getType() != Material.CHEST) continue;
|
||||
Block block = blockState.getBlock();
|
||||
|
||||
Protection protection = LWC.getInstance().findProtection(block);
|
||||
if (protection == null) continue;
|
||||
|
||||
ret.add(protection);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package com.massivecraft.factions.integration.lwc;
|
||||
|
||||
import com.massivecraft.massivecore.integration.IntegrationAbstract;
|
||||
|
||||
public class IntegrationLwc extends IntegrationAbstract
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static IntegrationLwc i = new IntegrationLwc();
|
||||
public static IntegrationLwc get() { return i; }
|
||||
private IntegrationLwc() { super("LWC"); }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// OVERRIDE
|
||||
// -------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public void activate()
|
||||
{
|
||||
EngineLwc.get().activate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate()
|
||||
{
|
||||
EngineLwc.get().deactivate();
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user