Pass 1 at adding in better chat formating

This commit is contained in:
Olof Larsson 2013-04-18 14:57:56 +02:00
parent c098171759
commit 170edc5811
27 changed files with 815 additions and 320 deletions

View File

@ -18,13 +18,16 @@ public class ConfServer extends SimpleConfig
public ConfServer() { super(Factions.get()); } public ConfServer() { super(Factions.get()); }
// -------------------------------------------- // // -------------------------------------------- //
// FIELDS // CORE
// -------------------------------------------- // // -------------------------------------------- //
public static List<String> baseCommandAliases = MUtil.list("f"); public static List<String> baseCommandAliases = MUtil.list("f");
public static String dburi = "default"; public static String dburi = "default";
// Colors // -------------------------------------------- //
// COLORS
// -------------------------------------------- //
public static ChatColor colorMember = ChatColor.GREEN; public static ChatColor colorMember = ChatColor.GREEN;
public static ChatColor colorAlly = ChatColor.DARK_PURPLE; public static ChatColor colorAlly = ChatColor.DARK_PURPLE;
public static ChatColor colorTruce = ChatColor.LIGHT_PURPLE; public static ChatColor colorTruce = ChatColor.LIGHT_PURPLE;
@ -35,6 +38,10 @@ public class ConfServer extends SimpleConfig
public static ChatColor colorFriendlyFire = ChatColor.DARK_RED; public static ChatColor colorFriendlyFire = ChatColor.DARK_RED;
//public static ChatColor colorWilderness = ChatColor.DARK_GREEN; //public static ChatColor colorWilderness = ChatColor.DARK_GREEN;
// -------------------------------------------- //
// DOUBTFULLY CONFIGURABLE DEFAULTS (TODO)
// -------------------------------------------- //
public static Map<FFlag, Boolean> factionFlagDefaults; public static Map<FFlag, Boolean> factionFlagDefaults;
//public static Map<FFlag, Boolean> factionFlagIsChangeable; //public static Map<FFlag, Boolean> factionFlagIsChangeable;
public static Map<FPerm, Set<Rel>> factionPermDefaults; public static Map<FPerm, Set<Rel>> factionPermDefaults;
@ -42,7 +49,10 @@ public class ConfServer extends SimpleConfig
// TODO: Shouldn't this be a constant rather? // TODO: Shouldn't this be a constant rather?
public static Rel factionRankDefault = Rel.RECRUIT; public static Rel factionRankDefault = Rel.RECRUIT;
// Power // -------------------------------------------- //
// POWER
// -------------------------------------------- //
public static double powerMax = 10.0; public static double powerMax = 10.0;
public static double powerMin = -10.0; public static double powerMin = -10.0;
public static double powerStarting = 10.0; // New players start out with this power level public static double powerStarting = 10.0; // New players start out with this power level
@ -63,13 +73,19 @@ public class ConfServer extends SimpleConfig
public static double powerFactionMax = 0.0; // if greater than 0, the cap on how much power a faction can have (additional power from players beyond that will act as a "buffer" of sorts) public static double powerFactionMax = 0.0; // if greater than 0, the cap on how much power a faction can have (additional power from players beyond that will act as a "buffer" of sorts)
// -------------------------------------------- //
// PREFIXES
// -------------------------------------------- //
public static String prefixLeader = "**"; public static String prefixLeader = "**";
public static String prefixOfficer = "*"; public static String prefixOfficer = "*";
public static String prefixMember = "+"; public static String prefixMember = "+";
public static String prefixRecruit = "-"; public static String prefixRecruit = "-";
// -------------------------------------------- //
// CORE
// -------------------------------------------- //
public static int factionTagLengthMin = 3; public static int factionTagLengthMin = 3;
public static int factionTagLengthMax = 10; public static int factionTagLengthMax = 10;
public static boolean factionTagForceUpperCase = false; public static boolean factionTagForceUpperCase = false;
@ -81,20 +97,20 @@ public class ConfServer extends SimpleConfig
// what faction ID to start new players in when they first join the server; default is 0, "no faction" // what faction ID to start new players in when they first join the server; default is 0, "no faction"
public static String newPlayerStartingFactionID = Const.FACTIONID_NONE; public static String newPlayerStartingFactionID = Const.FACTIONID_NONE;
//public static boolean showMapFactionKey = true;
//public static boolean showNeutralFactionsOnMap = true;
//public static boolean showEnemyFactionsOnMap = true;
// Disallow joining/leaving/kicking while power is negative // Disallow joining/leaving/kicking while power is negative
public static boolean canLeaveWithNegativePower = true; public static boolean canLeaveWithNegativePower = true;
// -------------------------------------------- //
// CHAT
// -------------------------------------------- //
// Configuration on the Faction tag in chat messages. // Configuration on the Faction tag in chat messages.
public static boolean chatSetFormat = false; public static boolean chatSetFormat = false;
public static String chatSetFormatTo = "<{faction_relcolor}§l{faction_roleprefix}§r{faction_relcolor}{faction_tag_pr}"+ChatColor.WHITE.toString()+"%s> %s"; public static String chatSetFormatTo = "<{faction_relcolor}§l{faction_roleprefix}§r{faction_relcolor}{faction_tag_pr}"+ChatColor.WHITE.toString()+"%s> %s";
public static boolean chatParseTags = true; public static boolean chatParseTags = true;
public static boolean chatParseTagsColored = false;
public static Map<String, String> chatSingleFormats = new HashMap<String, String>();
public static String chatTagFormat = "%s"+ChatColor.WHITE; // This one is almost deprecated now right? or is it? public static String chatTagFormat = "%s"+ChatColor.WHITE; // This one is almost deprecated now right? or is it?
// Herochat // Herochat
@ -120,24 +136,32 @@ public class ConfServer extends SimpleConfig
public static String herochatAllyName = "Allies"; public static String herochatAllyName = "Allies";
// TODO: Does anyone toggle this feature on I wonder? // -------------------------------------------- //
// It could work for small servers but never for big ones. // AUTO LEAVE
// Why not conform to big server setups at once? // -------------------------------------------- //
// POSSIBLY: Remove this option
public static boolean broadcastDescriptionChanges = false;
public static double autoLeaveAfterDaysOfInactivity = 10.0; public static double autoLeaveAfterDaysOfInactivity = 10.0;
public static double autoLeaveRoutineRunsEveryXMinutes = 5.0; public static double autoLeaveRoutineRunsEveryXMinutes = 5.0;
public static boolean removePlayerDataWhenBanned = true; public static boolean removePlayerDataWhenBanned = true;
// -------------------------------------------- //
// INTEGRATION: WORLD GUARD
// -------------------------------------------- //
public static boolean worldGuardChecking = false; public static boolean worldGuardChecking = false;
//LWC // -------------------------------------------- //
// INTEGRATION: LWC
// -------------------------------------------- //
public static boolean lwcIntegration = false; public static boolean lwcIntegration = false;
public static boolean onUnclaimResetLwcLocks = false; public static boolean onUnclaimResetLwcLocks = false;
public static boolean onCaptureResetLwcLocks = false; public static boolean onCaptureResetLwcLocks = false;
// server logging options // -------------------------------------------- //
// LOGGING
// -------------------------------------------- //
public static boolean logFactionCreate = true; public static boolean logFactionCreate = true;
public static boolean logFactionDisband = true; public static boolean logFactionDisband = true;
public static boolean logFactionJoin = true; public static boolean logFactionJoin = true;
@ -148,12 +172,19 @@ public class ConfServer extends SimpleConfig
public static boolean logMoneyTransactions = true; public static boolean logMoneyTransactions = true;
public static boolean logPlayerCommands = true; public static boolean logPlayerCommands = true;
// prevent some potential exploits // -------------------------------------------- //
// EXPLOITS
// -------------------------------------------- //
public static boolean handleExploitObsidianGenerators = true; public static boolean handleExploitObsidianGenerators = true;
public static boolean handleExploitEnderPearlClipping = true; public static boolean handleExploitEnderPearlClipping = true;
public static boolean handleExploitInteractionSpam = true; public static boolean handleExploitInteractionSpam = true;
public static boolean handleExploitTNTWaterlog = false; public static boolean handleExploitTNTWaterlog = false;
// -------------------------------------------- //
// HOMES
// -------------------------------------------- //
public static boolean homesEnabled = true; public static boolean homesEnabled = true;
public static boolean homesMustBeInClaimedTerritory = true; public static boolean homesMustBeInClaimedTerritory = true;
public static boolean homesTeleportCommandEnabled = true; public static boolean homesTeleportCommandEnabled = true;
@ -231,7 +262,10 @@ public class ConfServer extends SimpleConfig
public static float spoutTerritoryNoticeSize = 1.5f; // text scale (size) for notice public static float spoutTerritoryNoticeSize = 1.5f; // text scale (size) for notice
public static float spoutTerritoryNoticeLeaveAfterSeconds = 2.00f; // how many seconds before the notice goes away public static float spoutTerritoryNoticeLeaveAfterSeconds = 2.00f; // how many seconds before the notice goes away
// Economy settings // -------------------------------------------- //
// INTEGRATION: ECONOMY
// -------------------------------------------- //
public static boolean econEnabled = false; public static boolean econEnabled = false;
public static String econUniverseAccount = ""; public static String econUniverseAccount = "";
public static double econCostClaimWilderness = 30.0; public static double econCostClaimWilderness = 30.0;
@ -259,7 +293,7 @@ public class ConfServer extends SimpleConfig
public static double econCostNeutral = 0.0; public static double econCostNeutral = 0.0;
public static double econCostEnemy = 0.0; public static double econCostEnemy = 0.0;
public static int econLandRewardTaskRunsEveryXMinutes = 20; public static int econLandRewardTaskRunsEveryXMinutes = 20;
public static double econLandReward = 0.00; public static double econLandReward = 0.00;
//Faction banks, to pay for land claiming and other costs instead of individuals paying for them //Faction banks, to pay for land claiming and other costs instead of individuals paying for them
@ -268,6 +302,10 @@ public class ConfServer extends SimpleConfig
public static boolean bankFactionPaysCosts = true; //The faction pays for faction command costs, such as sethome public static boolean bankFactionPaysCosts = true; //The faction pays for faction command costs, such as sethome
public static boolean bankFactionPaysLandCosts = true; //The faction pays for land claiming costs. public static boolean bankFactionPaysLandCosts = true; //The faction pays for land claiming costs.
// -------------------------------------------- //
// DERPY OVERRIDES
// -------------------------------------------- //
// mainly for other plugins/mods that use a fake player to take actions, which shouldn't be subject to our protections // mainly for other plugins/mods that use a fake player to take actions, which shouldn't be subject to our protections
public static Set<String> playersWhoBypassAllProtection = new LinkedHashSet<String>(); public static Set<String> playersWhoBypassAllProtection = new LinkedHashSet<String>();
@ -279,6 +317,10 @@ public class ConfServer extends SimpleConfig
// TODO: A better solution Would be to have One wilderness faction per world. // TODO: A better solution Would be to have One wilderness faction per world.
//public static Set<String> worldsNoWildernessProtection = new LinkedHashSet<String>(); //public static Set<String> worldsNoWildernessProtection = new LinkedHashSet<String>();
// -------------------------------------------- //
// STATIC CONSTRUCTOR TO GET RID OF (TODO)
// -------------------------------------------- //
static static
{ {
factionFlagDefaults = new LinkedHashMap<FFlag, Boolean>(); factionFlagDefaults = new LinkedHashMap<FFlag, Boolean>();
@ -292,10 +334,6 @@ public class ConfServer extends SimpleConfig
{ {
factionPermDefaults.put(perm, perm.defaultDefaultValue); factionPermDefaults.put(perm, perm.defaultDefaultValue);
} }
chatSingleFormats.put("pl", " %s");
chatSingleFormats.put("pr", "%s ");
chatSingleFormats.put("pb", " %s ");
} }
} }

View File

@ -12,7 +12,7 @@ import com.massivecraft.factions.integration.Econ;
import com.massivecraft.factions.integration.LWCFeatures; import com.massivecraft.factions.integration.LWCFeatures;
import com.massivecraft.factions.integration.SpoutFeatures; import com.massivecraft.factions.integration.SpoutFeatures;
import com.massivecraft.factions.integration.Worldguard; import com.massivecraft.factions.integration.Worldguard;
import com.massivecraft.factions.listeners.FactionsChatListener; import com.massivecraft.factions.listeners.FactionsListenerChat;
import com.massivecraft.factions.listeners.FactionsEntityListener; import com.massivecraft.factions.listeners.FactionsEntityListener;
import com.massivecraft.factions.listeners.FactionsListenerExploit; import com.massivecraft.factions.listeners.FactionsListenerExploit;
import com.massivecraft.factions.listeners.FactionsListenerMain; import com.massivecraft.factions.listeners.FactionsListenerMain;
@ -44,7 +44,7 @@ public class Factions extends MPlugin
// Listeners // Listeners
public FactionsPlayerListener playerListener; public FactionsPlayerListener playerListener;
public FactionsChatListener chatListener; public FactionsListenerChat chatListener;
public FactionsEntityListener entityListener; public FactionsEntityListener entityListener;
// -------------------------------------------- // // -------------------------------------------- //
@ -92,7 +92,7 @@ public class Factions extends MPlugin
this.playerListener = new FactionsPlayerListener(); this.playerListener = new FactionsPlayerListener();
getServer().getPluginManager().registerEvents(this.playerListener, this); getServer().getPluginManager().registerEvents(this.playerListener, this);
this.chatListener = new FactionsChatListener(); this.chatListener = new FactionsListenerChat();
getServer().getPluginManager().registerEvents(this.chatListener, this); getServer().getPluginManager().registerEvents(this.chatListener, this);
this.entityListener = new FactionsEntityListener(); this.entityListener = new FactionsEntityListener();

View File

@ -0,0 +1,182 @@
package com.massivecraft.factions.chat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* The ChatFormater is a system offered by factions for tag parsing.
*
* Note that every tag and modifier id must be lowercase.
* A tag with id "derp" is allowed but not with id "Derp". For that reason the tag {sender} will work but {Sender} wont.
*/
public class ChatFormatter
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
public final static String START = "{";
public final static String END = "}";
public final static String SEPARATOR = "|";
public final static String ESC_START = "\\"+START;
public final static String ESC_END = "\\"+END;
public final static String ESC_SEPARATOR = "\\"+SEPARATOR;
public final static Pattern pattern = Pattern.compile(ESC_START+"([^"+ESC_START+ESC_END+"]+)"+ESC_END);
// -------------------------------------------- //
// TAG REGISTER
// -------------------------------------------- //
private final static Map<String, ChatTag> idToTag = new HashMap<String, ChatTag>();
public static ChatTag getTag(String tagId) { return idToTag.get(tagId); }
public static boolean registerTag(ChatTag tag)
{
if (tag == null) throw new NullPointerException("tag");
String id = tag.getId();
if (id == null) throw new NullPointerException("tag id");
if (!id.equals(id.toLowerCase()))
{
throw new IllegalArgumentException("tag id must be lowercase");
}
ChatTag current = idToTag.get(id);
if (current != null)
{
return current.equals(tag);
}
idToTag.put(id, tag);
return true;
}
public static boolean unregisterTag(ChatTag tag)
{
if (tag == null) return false;
return idToTag.remove(tag) != null;
}
// -------------------------------------------- //
// MODIFIER REGISTER
// -------------------------------------------- //
private final static Map<String, ChatModifier> idToModifier = new HashMap<String, ChatModifier>();
public static ChatModifier getModifier(String modifierId) { return idToModifier.get(modifierId); }
public static boolean registerModifier(ChatModifier modifier)
{
if (modifier == null) throw new NullPointerException("modifier");
String id = modifier.getId();
if (id == null) throw new NullPointerException("modifier id");
if (!id.equals(id.toLowerCase()))
{
throw new IllegalArgumentException("modifier id must be lowercase");
}
ChatModifier current = idToModifier.get(id);
if (current != null)
{
return current.equals(modifier);
}
idToModifier.put(id, modifier);
return true;
}
public static boolean unregisterModifier(ChatModifier modifier)
{
if (modifier == null) return false;
return idToModifier.remove(modifier) != null;
}
// -------------------------------------------- //
// FORMAT
// -------------------------------------------- //
public static String format(String msg, String senderId, String sendeeId, String recipientId)
{
// We build the return value in this string buffer
StringBuffer ret = new StringBuffer();
// A matcher to match all the tags in the msg
Matcher matcher = pattern.matcher(msg);
// For each tag we find
while (matcher.find())
{
// The fullmatch is something like "{sender|lp|rp}"
String fullmatch = matcher.group(0);
// The submatch is something like "sender|lp|rp"
String submatch = matcher.group(1);
// The parts are something like ["sender", "lp", "rp"]
String[] parts = submatch.split(ESC_SEPARATOR);
// The modifier ids are something like ["lp", "rp"] and tagId something like "sender"
List<String> modifierIds = new ArrayList<String>(Arrays.asList(parts));
String tagId = modifierIds.remove(0);
// Fetch tag for the id
ChatTag tag = getTag(tagId);
String replacement;
if (tag == null)
{
// No change if tag wasn't found
replacement = fullmatch;
}
else
{
replacement = compute(tag, modifierIds, senderId, sendeeId, recipientId);
if (replacement == null)
{
// If a tag or modifier returns null it's the same as opting out.
replacement = fullmatch;
}
}
matcher.appendReplacement(ret, replacement);
}
// Append the rest
matcher.appendTail(ret);
// And finally we return the string value of the buffer we built
return ret.toString();
}
// -------------------------------------------- //
// TAG COMPUTE
// -------------------------------------------- //
public static String compute(ChatTag tag, List<String> modifierIds, String senderId, String sendeeId, String recipientId)
{
String ret = tag.getReplacement(senderId, sendeeId, recipientId);
if (ret == null) return null;
for (String modifierId : modifierIds)
{
// Find the modifier or skip
ChatModifier modifier = getModifier(modifierId);
if (modifier == null) continue;
// Modify and ignore change if null.
// Modifier can't get or return null.
String modified = modifier.getModified(ret, senderId, sendeeId, recipientId);
if (modified == null) continue;
ret = modified;
}
return ret;
}
}

View File

@ -0,0 +1,10 @@
package com.massivecraft.factions.chat;
public interface ChatModifier
{
public String getId();
public String getModified(String subject, String senderId, String sendeeId, String recipientId);
public boolean register();
public boolean unregister();
}

View File

@ -0,0 +1,37 @@
package com.massivecraft.factions.chat;
public abstract class ChatModifierAbstract implements ChatModifier
{
// -------------------------------------------- //
// FIELDS & RAWDATA GET/SET
// -------------------------------------------- //
private final String id;
@Override public String getId() { return this.id; }
// -------------------------------------------- //
// OVERRIDES
// -------------------------------------------- //
@Override
public boolean register()
{
return ChatFormatter.registerModifier(this);
}
@Override
public boolean unregister()
{
return ChatFormatter.unregisterModifier(this);
}
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public ChatModifierAbstract(final String id)
{
this.id = id.toLowerCase();
}
}

View File

@ -0,0 +1,9 @@
package com.massivecraft.factions.chat;
public interface ChatTag
{
public String getId();
public String getReplacement(String senderId, String sendeeId, String recipientId);
public boolean register();
public boolean unregister();
}

View File

@ -0,0 +1,37 @@
package com.massivecraft.factions.chat;
public abstract class ChatTagAbstract implements ChatTag
{
// -------------------------------------------- //
// FIELDS & RAWDATA GET/SET
// -------------------------------------------- //
private final String id;
@Override public String getId() { return this.id; }
// -------------------------------------------- //
// OVERRIDES
// -------------------------------------------- //
@Override
public boolean register()
{
return ChatFormatter.registerTag(this);
}
@Override
public boolean unregister()
{
return ChatFormatter.unregisterTag(this);
}
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public ChatTagAbstract(final String id)
{
this.id = id.toLowerCase();
}
}

View File

@ -0,0 +1,25 @@
package com.massivecraft.factions.chat.modifier;
import com.massivecraft.factions.chat.ChatModifierAbstract;
public class ChatModifierLc extends ChatModifierAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatModifierLc() { super("lc"); }
private static ChatModifierLc i = new ChatModifierLc();
public static ChatModifierLc get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getModified(String subject, String senderId, String sendeeId, String recipientId)
{
return subject.toLowerCase();
}
}

View File

@ -0,0 +1,27 @@
package com.massivecraft.factions.chat.modifier;
import com.massivecraft.factions.chat.ChatModifierAbstract;
public class ChatModifierLp extends ChatModifierAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatModifierLp() { super("lp"); }
private static ChatModifierLp i = new ChatModifierLp();
public static ChatModifierLp get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getModified(String subject, String senderId, String sendeeId, String recipientId)
{
if (subject.equals("")) return subject;
return " "+subject;
}
}

View File

@ -0,0 +1,26 @@
package com.massivecraft.factions.chat.modifier;
import com.massivecraft.factions.chat.ChatModifierAbstract;
import com.massivecraft.mcore.util.Txt;
public class ChatModifierParse extends ChatModifierAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatModifierParse() { super("parse"); }
private static ChatModifierParse i = new ChatModifierParse();
public static ChatModifierParse get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getModified(String subject, String senderId, String sendeeId, String recipientId)
{
return Txt.parse(subject);
}
}

View File

@ -0,0 +1,26 @@
package com.massivecraft.factions.chat.modifier;
import com.massivecraft.factions.chat.ChatModifierAbstract;
public class ChatModifierRp extends ChatModifierAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatModifierRp() { super("rp"); }
private static ChatModifierRp i = new ChatModifierRp();
public static ChatModifierRp get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getModified(String subject, String senderId, String sendeeId, String recipientId)
{
if (subject.equals("")) return subject;
return subject+" ";
}
}

View File

@ -0,0 +1,25 @@
package com.massivecraft.factions.chat.modifier;
import com.massivecraft.factions.chat.ChatModifierAbstract;
public class ChatModifierUc extends ChatModifierAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatModifierUc() { super("uc"); }
private static ChatModifierUc i = new ChatModifierUc();
public static ChatModifierUc get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getModified(String subject, String senderId, String sendeeId, String recipientId)
{
return subject.toUpperCase();
}
}

View File

@ -0,0 +1,26 @@
package com.massivecraft.factions.chat.modifier;
import com.massivecraft.factions.chat.ChatModifierAbstract;
import com.massivecraft.mcore.util.Txt;
public class ChatModifierUcf extends ChatModifierAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatModifierUcf() { super("ucf"); }
private static ChatModifierUcf i = new ChatModifierUcf();
public static ChatModifierUcf get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getModified(String subject, String senderId, String sendeeId, String recipientId)
{
return Txt.upperCaseFirst(subject);
}
}

View File

@ -0,0 +1,36 @@
package com.massivecraft.factions.chat.tag;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayerColl;
import com.massivecraft.factions.chat.ChatTagAbstract;
public class ChatTagFactionRelcolor extends ChatTagAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatTagFactionRelcolor() { super("factions_relcolor"); }
private static ChatTagFactionRelcolor i = new ChatTagFactionRelcolor();
public static ChatTagFactionRelcolor get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getReplacement(String senderId, String sendeeId, String recipientId)
{
if (senderId == null) return "";
if (recipientId == null) return "";
FPlayer fsender = FPlayerColl.get().get(senderId);
FPlayer frecipient = FPlayerColl.get().get(recipientId);
if (fsender == null) return "";
if (frecipient == null) return "";
return frecipient.getRelationTo(fsender).getColor().toString();
}
}

View File

@ -0,0 +1,29 @@
package com.massivecraft.factions.chat.tag;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayerColl;
import com.massivecraft.factions.chat.ChatTagAbstract;
import com.massivecraft.mcore.util.Txt;
public class ChatTagFactionRole extends ChatTagAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatTagFactionRole() { super("factions_role"); }
private static ChatTagFactionRole i = new ChatTagFactionRole();
public static ChatTagFactionRole get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getReplacement(String senderId, String sendeeId, String recipientId)
{
FPlayer fsender = FPlayerColl.get().get(senderId);
return Txt.upperCaseFirst(fsender.getRole().toString().toLowerCase());
}
}

View File

@ -0,0 +1,28 @@
package com.massivecraft.factions.chat.tag;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayerColl;
import com.massivecraft.factions.chat.ChatTagAbstract;
public class ChatTagFactionRoleprefix extends ChatTagAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatTagFactionRoleprefix() { super("factions_roleprefix"); }
private static ChatTagFactionRoleprefix i = new ChatTagFactionRoleprefix();
public static ChatTagFactionRoleprefix get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getReplacement(String senderId, String sendeeId, String recipientId)
{
FPlayer fsender = FPlayerColl.get().get(senderId);
return fsender.getRole().getPrefix();
}
}

View File

@ -0,0 +1,29 @@
package com.massivecraft.factions.chat.tag;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayerColl;
import com.massivecraft.factions.chat.ChatTagAbstract;
public class ChatTagFactionTag extends ChatTagAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatTagFactionTag() { super("factions_tag"); }
private static ChatTagFactionTag i = new ChatTagFactionTag();
public static ChatTagFactionTag get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getReplacement(String senderId, String sendeeId, String recipientId)
{
FPlayer fsender = FPlayerColl.get().get(senderId);
if (!fsender.hasFaction()) return "";
return fsender.getFaction().getTag();
}
}

View File

@ -0,0 +1,28 @@
package com.massivecraft.factions.chat.tag;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayerColl;
import com.massivecraft.factions.chat.ChatTagAbstract;
public class ChatTagFactionTagforce extends ChatTagAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatTagFactionTagforce() { super("factions_tagforce"); }
private static ChatTagFactionTagforce i = new ChatTagFactionTagforce();
public static ChatTagFactionTagforce get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getReplacement(String senderId, String sendeeId, String recipientId)
{
FPlayer fsender = FPlayerColl.get().get(senderId);
return fsender.getFaction().getTag();
}
}

View File

@ -0,0 +1,28 @@
package com.massivecraft.factions.chat.tag;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayerColl;
import com.massivecraft.factions.chat.ChatTagAbstract;
public class ChatTagFactionTitle extends ChatTagAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatTagFactionTitle() { super("factions_title"); }
private static ChatTagFactionTitle i = new ChatTagFactionTitle();
public static ChatTagFactionTitle get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getReplacement(String senderId, String sendeeId, String recipientId)
{
FPlayer fsender = FPlayerColl.get().get(sendeeId);
return fsender.getTitle();
}
}

View File

@ -0,0 +1,26 @@
package com.massivecraft.factions.chat.tag;
import com.massivecraft.factions.chat.ChatTagAbstract;
import com.massivecraft.mcore.mixin.Mixin;
public class ChatTagSendee extends ChatTagAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatTagSendee() { super("sendee"); }
private static ChatTagSendee i = new ChatTagSendee();
public static ChatTagSendee get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getReplacement(String senderId, String sendeeId, String recipientId)
{
return Mixin.getDisplayName(sendeeId);
}
}

View File

@ -0,0 +1,26 @@
package com.massivecraft.factions.chat.tag;
import com.massivecraft.factions.chat.ChatTagAbstract;
import com.massivecraft.mcore.mixin.Mixin;
public class ChatTagSendeeId extends ChatTagAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatTagSendeeId() { super("sendeeid"); }
private static ChatTagSendeeId i = new ChatTagSendeeId();
public static ChatTagSendeeId get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getReplacement(String senderId, String sendeeId, String recipientId)
{
return Mixin.tryFix(sendeeId);
}
}

View File

@ -0,0 +1,26 @@
package com.massivecraft.factions.chat.tag;
import com.massivecraft.factions.chat.ChatTagAbstract;
import com.massivecraft.mcore.mixin.Mixin;
public class ChatTagSender extends ChatTagAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatTagSender() { super("sender"); }
private static ChatTagSender i = new ChatTagSender();
public static ChatTagSender get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getReplacement(String senderId, String sendeeId, String recipientId)
{
return Mixin.getDisplayName(senderId);
}
}

View File

@ -0,0 +1,26 @@
package com.massivecraft.factions.chat.tag;
import com.massivecraft.factions.chat.ChatTagAbstract;
import com.massivecraft.mcore.mixin.Mixin;
public class ChatTagSenderId extends ChatTagAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private ChatTagSenderId() { super("senderid"); }
private static ChatTagSenderId i = new ChatTagSenderId();
public static ChatTagSenderId get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getReplacement(String senderId, String sendeeId, String recipientId)
{
return Mixin.tryFix(senderId);
}
}

View File

@ -1,12 +1,11 @@
package com.massivecraft.factions.cmd; package com.massivecraft.factions.cmd;
import com.massivecraft.factions.ConfServer; import com.massivecraft.factions.ConfServer;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayerColl;
import com.massivecraft.factions.Perm; import com.massivecraft.factions.Perm;
import com.massivecraft.factions.Rel; import com.massivecraft.factions.Rel;
import com.massivecraft.factions.cmd.req.ReqRoleIsAtLeast; import com.massivecraft.factions.cmd.req.ReqRoleIsAtLeast;
import com.massivecraft.mcore.cmd.req.ReqHasPerm; import com.massivecraft.mcore.cmd.req.ReqHasPerm;
import com.massivecraft.mcore.mixin.Mixin;
public class CmdFactionsDescription extends FCommand public class CmdFactionsDescription extends FCommand
{ {
@ -27,21 +26,9 @@ public class CmdFactionsDescription extends FCommand
// if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay
if ( ! payForCommand(ConfServer.econCostDesc, "to change faction description", "for changing faction description")) return; if ( ! payForCommand(ConfServer.econCostDesc, "to change faction description", "for changing faction description")) return;
if (ConfServer.broadcastDescriptionChanges) myFaction.setDescription(this.argConcatFrom(1));
{
// Broadcast the description to everyone
for (FPlayer fplayer : FPlayerColl.get().getAllOnline())
{
fplayer.msg("<h>%s<i> changed their description to:", myFaction.describeTo(fplayer));
fplayer.sendMessage(myFaction.getDescription());
}
}
else
{
fme.msg("You have changed the description for <h>%s<i> to:", myFaction.describeTo(fme));
fme.sendMessage(myFaction.getDescription());
}
myFaction.msg("<i>%s <i>set your faction description to:\n%s", Mixin.getDisplayName(sender), myFaction.getDescription());
} }
} }

View File

@ -1,6 +1,5 @@
package com.massivecraft.factions.integration.herochat; package com.massivecraft.factions.integration.herochat;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -8,10 +7,8 @@ import org.bukkit.event.Listener;
import com.dthielke.herochat.ChannelChatEvent; import com.dthielke.herochat.ChannelChatEvent;
import com.dthielke.herochat.Herochat; import com.dthielke.herochat.Herochat;
import com.massivecraft.factions.ConfServer; import com.massivecraft.factions.ConfServer;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayerColl;
import com.massivecraft.factions.Factions; import com.massivecraft.factions.Factions;
import com.massivecraft.factions.listeners.FactionsChatListener; import com.massivecraft.factions.chat.ChatFormatter;
public class HerochatListener implements Listener public class HerochatListener implements Listener
{ {
@ -32,14 +29,9 @@ public class HerochatListener implements Listener
// Should we even parse? // Should we even parse?
if ( ! ConfServer.chatParseTags) return; if ( ! ConfServer.chatParseTags) return;
Player from = event.getSender().getPlayer();
FPlayer fpfrom = FPlayerColl.get().get(from);
String format = event.getFormat(); String format = event.getFormat();
format = format.replaceAll("&r", "§r"); format = format.replaceAll("&r", "§r");
format = ChatFormatter.format(format, event.getSender().getName(), null, null);
String formatWithoutColor = FactionsChatListener.parseTags(format, from, fpfrom); event.setFormat(format);
event.setFormat(formatWithoutColor);
} }
} }

View File

@ -1,266 +0,0 @@
package com.massivecraft.factions.listeners;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.plugin.AuthorNagException;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredListener;
import com.massivecraft.factions.ConfServer;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayerColl;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.Rel;
public class FactionsChatListener implements Listener
{
public static Field fieldRegisteredListenerDotPriority;
public static final Pattern parsePattern;
static
{
try
{
fieldRegisteredListenerDotPriority = RegisteredListener.class.getDeclaredField("priority");
fieldRegisteredListenerDotPriority.setAccessible(true);
}
catch (Exception e)
{
Factions.get().log(Level.SEVERE, "A reflection trick is broken! This will lead to glitchy relation-colored-chat.");
}
parsePattern = Pattern.compile("[{\\[]factions?_([a-zA-Z_]+)[}\\]]");
}
/**
* We offer an optional and very simple chat formating functionality.
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled=true)
public void lowPlayerChatEvent(AsyncPlayerChatEvent event)
{
if (ConfServer.chatSetFormat)
{
event.setFormat(ConfServer.chatSetFormatTo);
}
}
// this is for handling insertion of the player's faction tag, set at highest priority to give other plugins a chance to modify chat first
/**
* At the Highest event priority we apply chat formating.
* Relation colored faction tags may or may not be disabled (Conf.chatParseTagsColored)
* If color is disabled it works flawlessly.
* If however color is enabled we face a limitation in Bukkit.
* Bukkit does not support the same message looking different for each recipient.
* The method we use to get around this is a bit hacky:
* 1. We cancel the chat event on EventPriority.HIGHEST
* 2. We trigger EventPriority.MONITOR manually without relation color.
* 3. We log in console the way it's usually done (as in nms.NetServerHandler line~793).
* 4. We send out the messages to each player with relation color.
* The side effect is that other plugins at EventPriority.HIGHEST may experience the event as cancelled.
*/
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled=true)
public void onPlayerChat(AsyncPlayerChatEvent event)
{
// Should we even parse?
if ( ! ConfServer.chatParseTags) return;
// TODO: Replace this one with a detailed EventPriority + boolean.
//if (ConfServer.chatTagHandledByAnotherPlugin) return;
Player from = event.getPlayer();
FPlayer fpfrom = FPlayerColl.get().get(from);
String format = event.getFormat();
String message = event.getMessage();
String formatWithoutColor = parseTags(format, from, fpfrom);
if ( ! ConfServer.chatParseTagsColored)
{
// The case without color is really this simple (:
event.setFormat(formatWithoutColor);
return;
}
// So you want color eh? You monster :O
// 1. We cancel the chat event on EventPriority.HIGHEST
event.setCancelled(true);
// 2. We trigger EventPriority.MONITOR manually without relation color.
AsyncPlayerChatEvent monitorOnlyEvent = new AsyncPlayerChatEvent(false, from, message, new HashSet<Player>(Arrays.asList(Bukkit.getOnlinePlayers())));
monitorOnlyEvent.setFormat(formatWithoutColor);
callEventAtMonitorOnly(monitorOnlyEvent);
// 3. We log in console the way it's usually done (as in nms.NetServerHandler line~793).
Bukkit.getConsoleSender().sendMessage(String.format(monitorOnlyEvent.getFormat(), monitorOnlyEvent.getPlayer().getDisplayName(), monitorOnlyEvent.getMessage()));
// 4. We send out the messages to each player with relation color.
for (Player to : event.getRecipients())
{
FPlayer fpto = FPlayerColl.get().get(to);
String formatWithColor = parseTags(format, from, fpfrom, to, fpto);
to.sendMessage(String.format(formatWithColor, from.getDisplayName(), message));
}
}
/**
* This is some nasty woodo - I know :/
* I should make a pull request to Bukkit and CraftBukkit to support this feature natively
*/
public static void callEventAtMonitorOnly(Event event)
{
synchronized(Bukkit.getPluginManager())
{
HandlerList handlers = event.getHandlers();
RegisteredListener[] listeners = handlers.getRegisteredListeners();
for (RegisteredListener registration : listeners)
{
try
{
EventPriority priority = (EventPriority) fieldRegisteredListenerDotPriority.get(registration);
if (priority != EventPriority.MONITOR) continue;
}
catch (Exception e)
{
e.printStackTrace();
continue;
}
// This rest is almost copy pasted from SimplePluginManager in Bukkit:
if (!registration.getPlugin().isEnabled()) {
continue;
}
try {
registration.callEvent(event);
} catch (AuthorNagException ex) {
Plugin plugin = registration.getPlugin();
if (plugin.isNaggable()) {
plugin.setNaggable(false);
String author = "<NoAuthorGiven>";
if (plugin.getDescription().getAuthors().size() > 0) {
author = plugin.getDescription().getAuthors().get(0);
}
Bukkit.getServer().getLogger().log(Level.SEVERE, String.format(
"Nag author: '%s' of '%s' about the following: %s",
author,
plugin.getDescription().getName(),
ex.getMessage()
));
}
} catch (Throwable ex) {
Bukkit.getServer().getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to " + registration.getPlugin().getDescription().getName(), ex);
}
}
}
}
public static String parseTags(String str, Player from)
{
FPlayer fpfrom = FPlayerColl.get().get(from);
return parseTags(str, from, fpfrom, null, null);
}
public static String parseTags(String str, Player from, FPlayer fpfrom)
{
return parseTags(str, from, fpfrom, null, null);
}
public static String parseTags(String str, Player from, Player to)
{
FPlayer fpfrom = FPlayerColl.get().get(from);
FPlayer fpto = FPlayerColl.get().get(to);
return parseTags(str, from, fpfrom, to, fpto);
}
public static String parseTags(String str, Player from, FPlayer fpfrom, Player to, FPlayer fpto)
{
StringBuffer ret = new StringBuffer();
Matcher matcher = parsePattern.matcher(str);
while (matcher.find())
{
String[] parts = matcher.group(1).toLowerCase().split("_");
List<String> args = new ArrayList<String>(Arrays.asList(parts));
String tag = args.remove(0);
matcher.appendReplacement(ret, produceTag(tag, args, from, fpfrom, to, fpto));
}
matcher.appendTail(ret);
return ret.toString();
}
public static String produceTag(String tag, List<String> args, Player from, FPlayer fpfrom, Player to, FPlayer fpto)
{
String ret = "";
if (tag.equals("relcolor"))
{
if (fpto == null)
{
ret = Rel.NEUTRAL.getColor().toString();
}
else
{
ret = fpfrom.getRelationTo(fpto).getColor().toString();
}
}
else if (tag.startsWith("roleprefix"))
{
ret = fpfrom.getRole().getPrefix();
}
else if (tag.equals("title"))
{
if (fpfrom.hasTitle())
{
ret = fpfrom.getTitle();
}
}
else if (tag.equals("tag"))
{
if (fpfrom.hasFaction())
{
ret = fpfrom.getFaction().getTag();
}
}
else if (tag.startsWith("tagforce"))
{
ret = fpfrom.getFaction().getTag();
}
if (ret == null) ret = "";
return applyFormatsByName(ret, args);
}
public static String applyFormatsByName(String str, List<String> formatNames)
{
if (str.length() == 0) return str;
for (String formatName : formatNames)
{
String format = ConfServer.chatSingleFormats.get(formatName);
try
{
str = String.format(format, str);
}
catch (Exception e) { }
}
return str;
}
}

View File

@ -0,0 +1,32 @@
package com.massivecraft.factions.listeners;
import org.bukkit.Bukkit;
import org.bukkit.event.Listener;
import com.massivecraft.factions.Factions;
public class FactionsListenerChat implements Listener
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static FactionsListenerChat i = new FactionsListenerChat();
public static FactionsListenerChat get() { return i; }
// -------------------------------------------- //
// SETUP
// -------------------------------------------- //
public void setup()
{
Bukkit.getPluginManager().registerEvents(this, Factions.get());
}
// -------------------------------------------- //
// LISTENER
// -------------------------------------------- //
// TODO:
}