diff --git a/src/com/massivecraft/factions/ConfServer.java b/src/com/massivecraft/factions/ConfServer.java index 2f00afdd..e85d69ad 100644 --- a/src/com/massivecraft/factions/ConfServer.java +++ b/src/com/massivecraft/factions/ConfServer.java @@ -18,13 +18,16 @@ public class ConfServer extends SimpleConfig public ConfServer() { super(Factions.get()); } // -------------------------------------------- // - // FIELDS + // CORE // -------------------------------------------- // public static List baseCommandAliases = MUtil.list("f"); public static String dburi = "default"; - // Colors + // -------------------------------------------- // + // COLORS + // -------------------------------------------- // + public static ChatColor colorMember = ChatColor.GREEN; public static ChatColor colorAlly = ChatColor.DARK_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 colorWilderness = ChatColor.DARK_GREEN; + // -------------------------------------------- // + // DOUBTFULLY CONFIGURABLE DEFAULTS (TODO) + // -------------------------------------------- // + public static Map factionFlagDefaults; //public static Map factionFlagIsChangeable; public static Map> factionPermDefaults; @@ -42,7 +49,10 @@ public class ConfServer extends SimpleConfig // TODO: Shouldn't this be a constant rather? public static Rel factionRankDefault = Rel.RECRUIT; - // Power + // -------------------------------------------- // + // POWER + // -------------------------------------------- // + public static double powerMax = 10.0; public static double powerMin = -10.0; 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) - + // -------------------------------------------- // + // PREFIXES + // -------------------------------------------- // public static String prefixLeader = "**"; public static String prefixOfficer = "*"; public static String prefixMember = "+"; public static String prefixRecruit = "-"; + // -------------------------------------------- // + // CORE + // -------------------------------------------- // + public static int factionTagLengthMin = 3; public static int factionTagLengthMax = 10; 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" 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 public static boolean canLeaveWithNegativePower = true; + // -------------------------------------------- // + // CHAT + // -------------------------------------------- // + // Configuration on the Faction tag in chat messages. 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 boolean chatParseTags = true; - public static boolean chatParseTagsColored = false; - public static Map chatSingleFormats = new HashMap(); + + public static String chatTagFormat = "%s"+ChatColor.WHITE; // This one is almost deprecated now right? or is it? // Herochat @@ -120,24 +136,32 @@ public class ConfServer extends SimpleConfig 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. - // Why not conform to big server setups at once? - // POSSIBLY: Remove this option - public static boolean broadcastDescriptionChanges = false; + // -------------------------------------------- // + // AUTO LEAVE + // -------------------------------------------- // public static double autoLeaveAfterDaysOfInactivity = 10.0; public static double autoLeaveRoutineRunsEveryXMinutes = 5.0; public static boolean removePlayerDataWhenBanned = true; + // -------------------------------------------- // + // INTEGRATION: WORLD GUARD + // -------------------------------------------- // + public static boolean worldGuardChecking = false; - //LWC + // -------------------------------------------- // + // INTEGRATION: LWC + // -------------------------------------------- // + public static boolean lwcIntegration = false; public static boolean onUnclaimResetLwcLocks = false; public static boolean onCaptureResetLwcLocks = false; - // server logging options + // -------------------------------------------- // + // LOGGING + // -------------------------------------------- // + public static boolean logFactionCreate = true; public static boolean logFactionDisband = true; public static boolean logFactionJoin = true; @@ -148,12 +172,19 @@ public class ConfServer extends SimpleConfig public static boolean logMoneyTransactions = true; public static boolean logPlayerCommands = true; - // prevent some potential exploits + // -------------------------------------------- // + // EXPLOITS + // -------------------------------------------- // + public static boolean handleExploitObsidianGenerators = true; public static boolean handleExploitEnderPearlClipping = true; public static boolean handleExploitInteractionSpam = true; public static boolean handleExploitTNTWaterlog = false; + // -------------------------------------------- // + // HOMES + // -------------------------------------------- // + public static boolean homesEnabled = true; public static boolean homesMustBeInClaimedTerritory = 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 spoutTerritoryNoticeLeaveAfterSeconds = 2.00f; // how many seconds before the notice goes away - // Economy settings + // -------------------------------------------- // + // INTEGRATION: ECONOMY + // -------------------------------------------- // + public static boolean econEnabled = false; public static String econUniverseAccount = ""; public static double econCostClaimWilderness = 30.0; @@ -259,7 +293,7 @@ public class ConfServer extends SimpleConfig public static double econCostNeutral = 0.0; public static double econCostEnemy = 0.0; - public static int econLandRewardTaskRunsEveryXMinutes = 20; + public static int econLandRewardTaskRunsEveryXMinutes = 20; public static double econLandReward = 0.00; //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 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 public static Set playersWhoBypassAllProtection = new LinkedHashSet(); @@ -279,6 +317,10 @@ public class ConfServer extends SimpleConfig // TODO: A better solution Would be to have One wilderness faction per world. //public static Set worldsNoWildernessProtection = new LinkedHashSet(); + // -------------------------------------------- // + // STATIC CONSTRUCTOR TO GET RID OF (TODO) + // -------------------------------------------- // + static { factionFlagDefaults = new LinkedHashMap(); @@ -292,10 +334,6 @@ public class ConfServer extends SimpleConfig { factionPermDefaults.put(perm, perm.defaultDefaultValue); } - - chatSingleFormats.put("pl", " %s"); - chatSingleFormats.put("pr", "%s "); - chatSingleFormats.put("pb", " %s "); } } diff --git a/src/com/massivecraft/factions/Factions.java b/src/com/massivecraft/factions/Factions.java index ac1b0107..d1ded278 100644 --- a/src/com/massivecraft/factions/Factions.java +++ b/src/com/massivecraft/factions/Factions.java @@ -12,7 +12,7 @@ import com.massivecraft.factions.integration.Econ; import com.massivecraft.factions.integration.LWCFeatures; import com.massivecraft.factions.integration.SpoutFeatures; 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.FactionsListenerExploit; import com.massivecraft.factions.listeners.FactionsListenerMain; @@ -44,7 +44,7 @@ public class Factions extends MPlugin // Listeners public FactionsPlayerListener playerListener; - public FactionsChatListener chatListener; + public FactionsListenerChat chatListener; public FactionsEntityListener entityListener; // -------------------------------------------- // @@ -92,7 +92,7 @@ public class Factions extends MPlugin this.playerListener = new FactionsPlayerListener(); getServer().getPluginManager().registerEvents(this.playerListener, this); - this.chatListener = new FactionsChatListener(); + this.chatListener = new FactionsListenerChat(); getServer().getPluginManager().registerEvents(this.chatListener, this); this.entityListener = new FactionsEntityListener(); diff --git a/src/com/massivecraft/factions/chat/ChatFormatter.java b/src/com/massivecraft/factions/chat/ChatFormatter.java new file mode 100644 index 00000000..a293d661 --- /dev/null +++ b/src/com/massivecraft/factions/chat/ChatFormatter.java @@ -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 idToTag = new HashMap(); + 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 idToModifier = new HashMap(); + 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 modifierIds = new ArrayList(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 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; + } + +} diff --git a/src/com/massivecraft/factions/chat/ChatModifier.java b/src/com/massivecraft/factions/chat/ChatModifier.java new file mode 100644 index 00000000..a106626f --- /dev/null +++ b/src/com/massivecraft/factions/chat/ChatModifier.java @@ -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(); +} diff --git a/src/com/massivecraft/factions/chat/ChatModifierAbstract.java b/src/com/massivecraft/factions/chat/ChatModifierAbstract.java new file mode 100644 index 00000000..f368bb31 --- /dev/null +++ b/src/com/massivecraft/factions/chat/ChatModifierAbstract.java @@ -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(); + } + +} diff --git a/src/com/massivecraft/factions/chat/ChatTag.java b/src/com/massivecraft/factions/chat/ChatTag.java new file mode 100644 index 00000000..a7e62c62 --- /dev/null +++ b/src/com/massivecraft/factions/chat/ChatTag.java @@ -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(); +} diff --git a/src/com/massivecraft/factions/chat/ChatTagAbstract.java b/src/com/massivecraft/factions/chat/ChatTagAbstract.java new file mode 100644 index 00000000..5949453e --- /dev/null +++ b/src/com/massivecraft/factions/chat/ChatTagAbstract.java @@ -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(); + } + +} diff --git a/src/com/massivecraft/factions/chat/modifier/ChatModifierLc.java b/src/com/massivecraft/factions/chat/modifier/ChatModifierLc.java new file mode 100644 index 00000000..495f06a0 --- /dev/null +++ b/src/com/massivecraft/factions/chat/modifier/ChatModifierLc.java @@ -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(); + } + +} diff --git a/src/com/massivecraft/factions/chat/modifier/ChatModifierLp.java b/src/com/massivecraft/factions/chat/modifier/ChatModifierLp.java new file mode 100644 index 00000000..492d54ae --- /dev/null +++ b/src/com/massivecraft/factions/chat/modifier/ChatModifierLp.java @@ -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; + } + +} diff --git a/src/com/massivecraft/factions/chat/modifier/ChatModifierParse.java b/src/com/massivecraft/factions/chat/modifier/ChatModifierParse.java new file mode 100644 index 00000000..63f286c8 --- /dev/null +++ b/src/com/massivecraft/factions/chat/modifier/ChatModifierParse.java @@ -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); + } + +} diff --git a/src/com/massivecraft/factions/chat/modifier/ChatModifierRp.java b/src/com/massivecraft/factions/chat/modifier/ChatModifierRp.java new file mode 100644 index 00000000..30642ad5 --- /dev/null +++ b/src/com/massivecraft/factions/chat/modifier/ChatModifierRp.java @@ -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+" "; + } + +} diff --git a/src/com/massivecraft/factions/chat/modifier/ChatModifierUc.java b/src/com/massivecraft/factions/chat/modifier/ChatModifierUc.java new file mode 100644 index 00000000..d560ccab --- /dev/null +++ b/src/com/massivecraft/factions/chat/modifier/ChatModifierUc.java @@ -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(); + } + +} diff --git a/src/com/massivecraft/factions/chat/modifier/ChatModifierUcf.java b/src/com/massivecraft/factions/chat/modifier/ChatModifierUcf.java new file mode 100644 index 00000000..e3293639 --- /dev/null +++ b/src/com/massivecraft/factions/chat/modifier/ChatModifierUcf.java @@ -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); + } + +} diff --git a/src/com/massivecraft/factions/chat/tag/ChatTagFactionRelcolor.java b/src/com/massivecraft/factions/chat/tag/ChatTagFactionRelcolor.java new file mode 100644 index 00000000..79e74fcb --- /dev/null +++ b/src/com/massivecraft/factions/chat/tag/ChatTagFactionRelcolor.java @@ -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(); + } + +} diff --git a/src/com/massivecraft/factions/chat/tag/ChatTagFactionRole.java b/src/com/massivecraft/factions/chat/tag/ChatTagFactionRole.java new file mode 100644 index 00000000..27fecd3f --- /dev/null +++ b/src/com/massivecraft/factions/chat/tag/ChatTagFactionRole.java @@ -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()); + } + +} diff --git a/src/com/massivecraft/factions/chat/tag/ChatTagFactionRoleprefix.java b/src/com/massivecraft/factions/chat/tag/ChatTagFactionRoleprefix.java new file mode 100644 index 00000000..e1aee863 --- /dev/null +++ b/src/com/massivecraft/factions/chat/tag/ChatTagFactionRoleprefix.java @@ -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(); + } + +} diff --git a/src/com/massivecraft/factions/chat/tag/ChatTagFactionTag.java b/src/com/massivecraft/factions/chat/tag/ChatTagFactionTag.java new file mode 100644 index 00000000..b2ff5d6a --- /dev/null +++ b/src/com/massivecraft/factions/chat/tag/ChatTagFactionTag.java @@ -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(); + } + +} diff --git a/src/com/massivecraft/factions/chat/tag/ChatTagFactionTagforce.java b/src/com/massivecraft/factions/chat/tag/ChatTagFactionTagforce.java new file mode 100644 index 00000000..822708f7 --- /dev/null +++ b/src/com/massivecraft/factions/chat/tag/ChatTagFactionTagforce.java @@ -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(); + } + +} diff --git a/src/com/massivecraft/factions/chat/tag/ChatTagFactionTitle.java b/src/com/massivecraft/factions/chat/tag/ChatTagFactionTitle.java new file mode 100644 index 00000000..adbf1f2d --- /dev/null +++ b/src/com/massivecraft/factions/chat/tag/ChatTagFactionTitle.java @@ -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(); + } + +} diff --git a/src/com/massivecraft/factions/chat/tag/ChatTagSendee.java b/src/com/massivecraft/factions/chat/tag/ChatTagSendee.java new file mode 100644 index 00000000..9b7a8e8e --- /dev/null +++ b/src/com/massivecraft/factions/chat/tag/ChatTagSendee.java @@ -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); + } + +} diff --git a/src/com/massivecraft/factions/chat/tag/ChatTagSendeeId.java b/src/com/massivecraft/factions/chat/tag/ChatTagSendeeId.java new file mode 100644 index 00000000..5e038663 --- /dev/null +++ b/src/com/massivecraft/factions/chat/tag/ChatTagSendeeId.java @@ -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); + } + +} diff --git a/src/com/massivecraft/factions/chat/tag/ChatTagSender.java b/src/com/massivecraft/factions/chat/tag/ChatTagSender.java new file mode 100644 index 00000000..3aefb1c3 --- /dev/null +++ b/src/com/massivecraft/factions/chat/tag/ChatTagSender.java @@ -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); + } + +} diff --git a/src/com/massivecraft/factions/chat/tag/ChatTagSenderId.java b/src/com/massivecraft/factions/chat/tag/ChatTagSenderId.java new file mode 100644 index 00000000..bdcfeabf --- /dev/null +++ b/src/com/massivecraft/factions/chat/tag/ChatTagSenderId.java @@ -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); + } + +} diff --git a/src/com/massivecraft/factions/cmd/CmdFactionsDescription.java b/src/com/massivecraft/factions/cmd/CmdFactionsDescription.java index ef1409f0..176f652a 100644 --- a/src/com/massivecraft/factions/cmd/CmdFactionsDescription.java +++ b/src/com/massivecraft/factions/cmd/CmdFactionsDescription.java @@ -1,12 +1,11 @@ package com.massivecraft.factions.cmd; import com.massivecraft.factions.ConfServer; -import com.massivecraft.factions.FPlayer; -import com.massivecraft.factions.FPlayerColl; import com.massivecraft.factions.Perm; import com.massivecraft.factions.Rel; import com.massivecraft.factions.cmd.req.ReqRoleIsAtLeast; import com.massivecraft.mcore.cmd.req.ReqHasPerm; +import com.massivecraft.mcore.mixin.Mixin; 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 ( ! payForCommand(ConfServer.econCostDesc, "to change faction description", "for changing faction description")) return; - if (ConfServer.broadcastDescriptionChanges) - { - // Broadcast the description to everyone - for (FPlayer fplayer : FPlayerColl.get().getAllOnline()) - { - fplayer.msg("%s changed their description to:", myFaction.describeTo(fplayer)); - fplayer.sendMessage(myFaction.getDescription()); - } - } - else - { - fme.msg("You have changed the description for %s to:", myFaction.describeTo(fme)); - fme.sendMessage(myFaction.getDescription()); - } + myFaction.setDescription(this.argConcatFrom(1)); + myFaction.msg("%s set your faction description to:\n%s", Mixin.getDisplayName(sender), myFaction.getDescription()); } } diff --git a/src/com/massivecraft/factions/integration/herochat/HerochatListener.java b/src/com/massivecraft/factions/integration/herochat/HerochatListener.java index 1c45dd9e..eaf39573 100644 --- a/src/com/massivecraft/factions/integration/herochat/HerochatListener.java +++ b/src/com/massivecraft/factions/integration/herochat/HerochatListener.java @@ -1,6 +1,5 @@ package com.massivecraft.factions.integration.herochat; -import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -8,10 +7,8 @@ import org.bukkit.event.Listener; import com.dthielke.herochat.ChannelChatEvent; import com.dthielke.herochat.Herochat; import com.massivecraft.factions.ConfServer; -import com.massivecraft.factions.FPlayer; -import com.massivecraft.factions.FPlayerColl; import com.massivecraft.factions.Factions; -import com.massivecraft.factions.listeners.FactionsChatListener; +import com.massivecraft.factions.chat.ChatFormatter; public class HerochatListener implements Listener { @@ -32,14 +29,9 @@ public class HerochatListener implements Listener // Should we even parse? if ( ! ConfServer.chatParseTags) return; - Player from = event.getSender().getPlayer(); - FPlayer fpfrom = FPlayerColl.get().get(from); String format = event.getFormat(); - format = format.replaceAll("&r", "§r"); - - String formatWithoutColor = FactionsChatListener.parseTags(format, from, fpfrom); - - event.setFormat(formatWithoutColor); + format = ChatFormatter.format(format, event.getSender().getName(), null, null); + event.setFormat(format); } } diff --git a/src/com/massivecraft/factions/listeners/FactionsChatListener.java b/src/com/massivecraft/factions/listeners/FactionsChatListener.java deleted file mode 100644 index e39f38fc..00000000 --- a/src/com/massivecraft/factions/listeners/FactionsChatListener.java +++ /dev/null @@ -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(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 = ""; - - 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 args = new ArrayList(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 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 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; - } - -} diff --git a/src/com/massivecraft/factions/listeners/FactionsListenerChat.java b/src/com/massivecraft/factions/listeners/FactionsListenerChat.java new file mode 100644 index 00000000..b32857ef --- /dev/null +++ b/src/com/massivecraft/factions/listeners/FactionsListenerChat.java @@ -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: + +}