Reworked chat completely. Added Herochat integration. New tag-parsing system. Non-monitor-breaking relation colored chat.
This commit is contained in:
parent
06d22549e2
commit
1459c9c057
BIN
lib/Herochat.jar
Normal file
BIN
lib/Herochat.jar
Normal file
Binary file not shown.
@ -64,21 +64,18 @@ public class Conf
|
||||
// Disallow joining/leaving/kicking while power is negative
|
||||
public static boolean canLeaveWithNegativePower = true;
|
||||
|
||||
// Configuration for faction-only chat
|
||||
public static boolean factionOnlyChat = true;
|
||||
// Configuration on the Faction tag in chat messages.
|
||||
public static boolean chatTagEnabled = true;
|
||||
public static transient boolean chatTagHandledByAnotherPlugin = false;
|
||||
public static boolean chatTagRelationColored = true;
|
||||
public static String chatTagReplaceString = "[FACTION]";
|
||||
public static String chatTagInsertAfterString = "";
|
||||
public static String chatTagInsertBeforeString = "";
|
||||
public static int chatTagInsertIndex = 1;
|
||||
public static boolean chatTagPadBefore = false;
|
||||
public static boolean chatTagPadAfter = true;
|
||||
public static String chatTagFormat = "%s"+ChatColor.WHITE;
|
||||
public static String factionChatFormat = "%s:"+ChatColor.WHITE+" %s";
|
||||
public static String allianceChatFormat = ChatColor.LIGHT_PURPLE+"%s:"+ChatColor.WHITE+" %s";
|
||||
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 = true;
|
||||
public static Map<String, String> chatSingleFormats = new HashMap<String, String>();
|
||||
public static transient boolean chatTagHandledByAnotherPlugin = false; // Why do we need this? (Olof asks)
|
||||
public static String chatTagFormat = "%s"+ChatColor.WHITE; // This one is almost deprecated now right? or is it?
|
||||
|
||||
// Herochat
|
||||
public static String herochatFactionChannelName = "Faction";
|
||||
public static String herochatAllyChannelName = "Allies";
|
||||
|
||||
public static double autoLeaveAfterDaysOfInactivity = 10.0;
|
||||
public static double autoLeaveRoutineRunsEveryXMinutes = 5.0;
|
||||
@ -260,6 +257,10 @@ public class Conf
|
||||
factionPermDefaults.put(perm, perm.defaultDefaultValue);
|
||||
}
|
||||
|
||||
chatSingleFormats.put("pl", " %s");
|
||||
chatSingleFormats.put("pr", "%s ");
|
||||
chatSingleFormats.put("pb", " %s ");
|
||||
|
||||
territoryEnemyDenyCommands.add("home");
|
||||
territoryEnemyDenyCommands.add("sethome");
|
||||
territoryEnemyDenyCommands.add("spawn");
|
||||
|
@ -16,7 +16,6 @@ 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.struct.ChatMode;
|
||||
import com.massivecraft.factions.struct.FFlag;
|
||||
import com.massivecraft.factions.struct.FPerm;
|
||||
import com.massivecraft.factions.struct.Rel;
|
||||
@ -99,23 +98,6 @@ public class FPlayer extends PlayerEntity implements EconomyParticipator
|
||||
// FIELD: loginPvpDisabled
|
||||
private transient boolean loginPvpDisabled;
|
||||
|
||||
// FIELD: chatMode
|
||||
private ChatMode chatMode;
|
||||
public void setChatMode(ChatMode chatMode) { this.chatMode = chatMode; }
|
||||
public ChatMode getChatMode()
|
||||
{
|
||||
if(this.factionId.equals("0") || ! Conf.factionOnlyChat)
|
||||
{
|
||||
this.chatMode = ChatMode.PUBLIC;
|
||||
}
|
||||
return chatMode;
|
||||
}
|
||||
|
||||
// FIELD: chatSpy
|
||||
private transient boolean spyingChat = false;
|
||||
public void setSpyingChat(boolean chatSpying) { this.spyingChat = chatSpying; }
|
||||
public boolean isSpyingChat() { return spyingChat; }
|
||||
|
||||
// FIELD: account
|
||||
public String getAccountId() { return this.getId(); }
|
||||
|
||||
@ -153,7 +135,6 @@ public class FPlayer extends PlayerEntity implements EconomyParticipator
|
||||
}
|
||||
|
||||
this.factionId = "0"; // The default neutral faction
|
||||
this.chatMode = ChatMode.PUBLIC;
|
||||
this.role = Rel.MEMBER;
|
||||
this.title = "";
|
||||
this.autoClaimFor = null;
|
||||
|
@ -24,6 +24,7 @@ import com.massivecraft.factions.cmd.*;
|
||||
import com.massivecraft.factions.integration.capi.CapiFeatures;
|
||||
import com.massivecraft.factions.integration.Econ;
|
||||
import com.massivecraft.factions.integration.EssentialsFeatures;
|
||||
import com.massivecraft.factions.integration.HerochatFeatures;
|
||||
import com.massivecraft.factions.integration.LWCFeatures;
|
||||
import com.massivecraft.factions.integration.SpoutFeatures;
|
||||
import com.massivecraft.factions.integration.Worldguard;
|
||||
@ -34,7 +35,6 @@ import com.massivecraft.factions.listeners.FactionsExploitListener;
|
||||
import com.massivecraft.factions.listeners.FactionsHealthBarListener;
|
||||
import com.massivecraft.factions.listeners.FactionsPlayerListener;
|
||||
import com.massivecraft.factions.listeners.FactionsServerListener;
|
||||
import com.massivecraft.factions.struct.ChatMode;
|
||||
import com.massivecraft.factions.struct.FFlag;
|
||||
import com.massivecraft.factions.struct.FPerm;
|
||||
import com.massivecraft.factions.struct.Rel;
|
||||
@ -105,6 +105,7 @@ public class P extends MPlugin
|
||||
SpoutFeatures.setup();
|
||||
Econ.setup();
|
||||
CapiFeatures.setup();
|
||||
HerochatFeatures.setup();
|
||||
LWCFeatures.setup();
|
||||
|
||||
if(Conf.worldGuardChecking)
|
||||
@ -241,13 +242,12 @@ public class P extends MPlugin
|
||||
|
||||
// Does player have Faction Chat enabled? If so, chat plugins should preferably not do channels,
|
||||
// local chat, or anything else which targets individual recipients, so Faction Chat can be done
|
||||
/**
|
||||
* @deprecated As of release 1.8, there is no built in faction chat.
|
||||
*/
|
||||
public boolean isPlayerFactionChatting(Player player)
|
||||
{
|
||||
if (player == null) return false;
|
||||
FPlayer me = FPlayers.i.get(player);
|
||||
|
||||
if (me == null)return false;
|
||||
return me.getChatMode().isAtLeast(ChatMode.ALLIANCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is this chat message actually a Factions command, and thus should be left alone by other plugins?
|
||||
@ -276,7 +276,7 @@ public class P extends MPlugin
|
||||
return tag;
|
||||
|
||||
// if listener isn't set, or config option is disabled, give back uncolored tag
|
||||
if (listener == null || !Conf.chatTagRelationColored) {
|
||||
if (listener == null || !Conf.chatParseTagsColored) {
|
||||
tag = me.getChatTag().trim();
|
||||
} else {
|
||||
FPlayer you = FPlayers.i.get(listener);
|
||||
|
@ -1,77 +0,0 @@
|
||||
package com.massivecraft.factions.cmd;
|
||||
|
||||
import com.massivecraft.factions.Conf;
|
||||
import com.massivecraft.factions.struct.ChatMode;
|
||||
import com.massivecraft.factions.struct.Permission;
|
||||
|
||||
public class CmdChat extends FCommand
|
||||
{
|
||||
|
||||
public CmdChat()
|
||||
{
|
||||
super();
|
||||
this.aliases.add("c");
|
||||
this.aliases.add("chat");
|
||||
|
||||
//this.requiredArgs.add("");
|
||||
this.optionalArgs.put("mode", "next");
|
||||
|
||||
this.permission = Permission.CHAT.node;
|
||||
this.disableOnLock = false;
|
||||
|
||||
senderMustBePlayer = true;
|
||||
senderMustBeMember = true;
|
||||
senderMustBeOfficer = false;
|
||||
senderMustBeLeader = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void perform()
|
||||
{
|
||||
if ( ! Conf.factionOnlyChat )
|
||||
{
|
||||
msg("<b>The built in chat chat channels are disabled on this server.");
|
||||
return;
|
||||
}
|
||||
|
||||
String modeString = this.argAsString(0);
|
||||
ChatMode modeTarget = fme.getChatMode().getNext();
|
||||
|
||||
if (modeString != null)
|
||||
{
|
||||
modeString.toLowerCase();
|
||||
if(modeString.startsWith("p"))
|
||||
{
|
||||
modeTarget = ChatMode.PUBLIC;
|
||||
}
|
||||
else if (modeString.startsWith("a"))
|
||||
{
|
||||
modeTarget = ChatMode.ALLIANCE;
|
||||
}
|
||||
else if(modeString.startsWith("f"))
|
||||
{
|
||||
modeTarget = ChatMode.FACTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg("<b>Unrecognised chat mode. <i>Please enter either 'a','f' or 'p'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fme.setChatMode(modeTarget);
|
||||
|
||||
if(fme.getChatMode() == ChatMode.PUBLIC)
|
||||
{
|
||||
msg("<i>Public chat mode.");
|
||||
}
|
||||
else if (fme.getChatMode() == ChatMode.ALLIANCE )
|
||||
{
|
||||
msg("<i>Alliance only chat mode.");
|
||||
}
|
||||
else
|
||||
{
|
||||
msg("<i>Faction only chat mode.");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.massivecraft.factions.cmd;
|
||||
|
||||
import com.massivecraft.factions.P;
|
||||
import com.massivecraft.factions.struct.Permission;
|
||||
|
||||
public class CmdChatSpy extends FCommand
|
||||
{
|
||||
public CmdChatSpy()
|
||||
{
|
||||
super();
|
||||
this.aliases.add("chatspy");
|
||||
|
||||
this.optionalArgs.put("on/off", "flip");
|
||||
|
||||
this.permission = Permission.CHATSPY.node;
|
||||
this.disableOnLock = false;
|
||||
|
||||
senderMustBePlayer = true;
|
||||
senderMustBeMember = false;
|
||||
senderMustBeOfficer = false;
|
||||
senderMustBeLeader = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void perform()
|
||||
{
|
||||
fme.setSpyingChat(this.argAsBool(0, ! fme.isSpyingChat()));
|
||||
|
||||
if ( fme.isSpyingChat())
|
||||
{
|
||||
fme.msg("<i>You have enabled chat spying mode.");
|
||||
P.p.log(fme.getName() + " has ENABLED chat spying mode.");
|
||||
}
|
||||
else
|
||||
{
|
||||
fme.msg("<i>You have disabled chat spying mode.");
|
||||
P.p.log(fme.getName() + " DISABLED chat spying mode.");
|
||||
}
|
||||
}
|
||||
}
|
@ -67,7 +67,6 @@ public class CmdHelp extends FCommand
|
||||
pageLines.add( p.cmdBase.cmdPower.getUseageTemplate(true) );
|
||||
pageLines.add( p.cmdBase.cmdJoin.getUseageTemplate(true) );
|
||||
pageLines.add( p.cmdBase.cmdLeave.getUseageTemplate(true) );
|
||||
pageLines.add( p.cmdBase.cmdChat.getUseageTemplate(true) );
|
||||
pageLines.add( p.cmdBase.cmdHome.getUseageTemplate(true) );
|
||||
pageLines.add( p.txt.parse("<i>Learn how to create a faction on the next page.") );
|
||||
helpPages.add(pageLines);
|
||||
@ -166,7 +165,6 @@ public class CmdHelp extends FCommand
|
||||
|
||||
pageLines = new ArrayList<String>();
|
||||
pageLines.add(p.txt.parse("<i>More commands for server admins:"));
|
||||
pageLines.add( p.cmdBase.cmdChatSpy.getUseageTemplate(true) );
|
||||
pageLines.add( p.cmdBase.cmdPowerBoost.getUseageTemplate(true) );
|
||||
pageLines.add( p.cmdBase.cmdLock.getUseageTemplate(true) );
|
||||
pageLines.add( p.cmdBase.cmdReload.getUseageTemplate(true) );
|
||||
|
@ -9,8 +9,6 @@ public class FCmdRoot extends FCommand
|
||||
public CmdLeader cmdLeader = new CmdLeader();
|
||||
public CmdAutoClaim cmdAutoClaim = new CmdAutoClaim();
|
||||
public CmdAdmin cmdBypass = new CmdAdmin();
|
||||
public CmdChat cmdChat = new CmdChat();
|
||||
public CmdChatSpy cmdChatSpy = new CmdChatSpy();
|
||||
public CmdClaim cmdClaim = new CmdClaim();
|
||||
public CmdConfig cmdConfig = new CmdConfig();
|
||||
public CmdCreate cmdCreate = new CmdCreate();
|
||||
@ -73,8 +71,6 @@ public class FCmdRoot extends FCommand
|
||||
this.addSubCommand(this.cmdLeader);
|
||||
this.addSubCommand(this.cmdAutoClaim);
|
||||
this.addSubCommand(this.cmdBypass);
|
||||
this.addSubCommand(this.cmdChat);
|
||||
this.addSubCommand(this.cmdChatSpy);
|
||||
this.addSubCommand(this.cmdClaim);
|
||||
this.addSubCommand(this.cmdConfig);
|
||||
this.addSubCommand(this.cmdCreate);
|
||||
|
@ -11,6 +11,7 @@ import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.massivecraft.factions.Conf;
|
||||
import com.massivecraft.factions.P;
|
||||
import com.massivecraft.factions.listeners.FactionsChatListener;
|
||||
|
||||
import com.earth2me.essentials.IEssentials;
|
||||
import com.earth2me.essentials.Teleport;
|
||||
@ -105,13 +106,6 @@ public class EssentialsFeatures
|
||||
{
|
||||
Bukkit.getServer().getPluginManager().registerEvents(new LocalChatListener(), P.p);
|
||||
P.p.log("Found and will integrate chat with newer "+essChat.getDescription().getFullName());
|
||||
|
||||
// curly braces used to be accepted by the format string EssentialsChat but no longer are, so... deal with chatTagReplaceString which might need updating
|
||||
if (Conf.chatTagReplaceString.contains("{"))
|
||||
{
|
||||
Conf.chatTagReplaceString = Conf.chatTagReplaceString.replace("{", "[").replace("}", "]");
|
||||
P.p.log("NOTE: as of Essentials 2.8+, we've had to switch the default chat replacement tag from \"{FACTION}\" to \"[FACTION]\". This has automatically been updated for you.");
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodError ex)
|
||||
{
|
||||
@ -127,7 +121,9 @@ public class EssentialsFeatures
|
||||
{
|
||||
Player speaker = event.getPlayer();
|
||||
String format = event.getFormat();
|
||||
format = format.replace(Conf.chatTagReplaceString, P.p.getPlayerFactionTag(speaker)).replace("[FACTION_TITLE]", P.p.getPlayerTitle(speaker));
|
||||
|
||||
format = FactionsChatListener.parseTags(format, speaker);
|
||||
|
||||
event.setFormat(format);
|
||||
// NOTE: above doesn't do relation coloring. if/when we can get a local recipient list from EssentialsLocalChatEvent, we'll probably
|
||||
// want to pass it on to FactionsPlayerListener.onPlayerChat(PlayerChatEvent event) rather than duplicating code
|
||||
|
@ -3,8 +3,8 @@ package com.massivecraft.factions.integration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerChatEvent;
|
||||
|
||||
import com.massivecraft.factions.Conf;
|
||||
import com.massivecraft.factions.P;
|
||||
import com.massivecraft.factions.listeners.FactionsChatListener;
|
||||
|
||||
import com.earth2me.essentials.chat.EssentialsChat;
|
||||
import com.earth2me.essentials.chat.IEssentialsChatListener;
|
||||
@ -31,17 +31,11 @@ public class EssentialsOldVersionFeatures
|
||||
}
|
||||
public String modifyMessage(PlayerChatEvent event, Player target, String message)
|
||||
{
|
||||
return message.replace(Conf.chatTagReplaceString, P.p.getPlayerFactionTagRelation(event.getPlayer(), target)).replace("[FACTION_TITLE]", P.p.getPlayerTitle(event.getPlayer()));
|
||||
return FactionsChatListener.parseTags(message, event.getPlayer());
|
||||
//return message.replace(Conf.chatTagReplaceString, P.p.getPlayerFactionTagRelation(event.getPlayer(), target)).replace("[FACTION_TITLE]", P.p.getPlayerTitle(event.getPlayer()));
|
||||
}
|
||||
});
|
||||
P.p.log("Found and will integrate chat with "+essChat.getDescription().getFullName());
|
||||
|
||||
// As of Essentials 2.8+, curly braces are not accepted and are instead replaced with square braces, so... deal with it
|
||||
if (essChat.getDescription().getVersion().startsWith("2.8.") && Conf.chatTagReplaceString.contains("{"))
|
||||
{
|
||||
Conf.chatTagReplaceString = Conf.chatTagReplaceString.replace("{", "[").replace("}", "]");
|
||||
P.p.log("NOTE: as of Essentials 2.8+, we've had to switch the default chat replacement tag from \"{FACTION}\" to \"[FACTION]\". This has automatically been updated for you.");
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodError ex)
|
||||
{
|
||||
|
@ -0,0 +1,71 @@
|
||||
package com.massivecraft.factions.integration;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.dthielke.herochat.Channel;
|
||||
import com.dthielke.herochat.ChannelChatEvent;
|
||||
import com.massivecraft.factions.Conf;
|
||||
import com.massivecraft.factions.FPlayer;
|
||||
import com.massivecraft.factions.FPlayers;
|
||||
import com.massivecraft.factions.Faction;
|
||||
import com.massivecraft.factions.P;
|
||||
import com.massivecraft.factions.struct.Rel;
|
||||
|
||||
public class HerochatFeatures implements Listener
|
||||
{
|
||||
P p;
|
||||
public HerochatFeatures(P p)
|
||||
{
|
||||
this.p = p;
|
||||
}
|
||||
|
||||
public static void setup()
|
||||
{
|
||||
Plugin plug = Bukkit.getServer().getPluginManager().getPlugin("Herochat");
|
||||
if (plug != null && plug.getClass().getName().equals("com.dthielke.herochat.Herochat"))
|
||||
{
|
||||
P.p.log("Integration with Herochat successful");
|
||||
Bukkit.getPluginManager().registerEvents(new HerochatFeatures(P.p), P.p);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onChannelChatEvent(ChannelChatEvent event)
|
||||
{
|
||||
Channel ch = event.getChannel();
|
||||
boolean isFactionChat = ch.getName().equals(Conf.herochatFactionChannelName);
|
||||
boolean isAllyChat = ch.getName().equals(Conf.herochatAllyChannelName);
|
||||
if ( ! isFactionChat && ! isAllyChat) return;
|
||||
|
||||
// Do common setup
|
||||
Player sender = event.getSender().getPlayer();
|
||||
FPlayer fpsender = FPlayers.i.get(sender);
|
||||
event.getBukkitEvent().getRecipients().clear();
|
||||
if ( ! fpsender.hasFaction())
|
||||
{
|
||||
sender.sendMessage(ChatColor.YELLOW.toString()+"You must join a faction to use the "+ch.getColor().toString()+ch.getName()+ChatColor.YELLOW.toString()+"-channel.");
|
||||
event.getBukkitEvent().setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Faction faction = fpsender.getFaction();
|
||||
event.getBukkitEvent().getRecipients().addAll(faction.getOnlinePlayers());
|
||||
|
||||
if (isAllyChat)
|
||||
{
|
||||
for (FPlayer fplayer : FPlayers.i.getOnline())
|
||||
{
|
||||
if(faction.getRelationTo(fplayer) == Rel.ALLY)
|
||||
{
|
||||
event.getBukkitEvent().getRecipients().add(fplayer.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -77,13 +77,6 @@ public class PluginCapiListener implements Listener
|
||||
if (event.getChannel().getId().equals("faction") && myFaction.isNormal())
|
||||
{
|
||||
event.getThem().addAll(myFaction.getOnlinePlayers());
|
||||
|
||||
// Send to any players who are spying chat... could probably be implemented better than this
|
||||
for (FPlayer fplayer : FPlayers.i.getOnline())
|
||||
{
|
||||
if(fplayer.isSpyingChat() && fplayer.getFaction() != myFaction)
|
||||
fplayer.sendMessage("[FCspy] "+myFaction.getTag()+": "+event.getMessage());
|
||||
}
|
||||
}
|
||||
else if (event.getChannel().getId().equals("allies"))
|
||||
{
|
||||
@ -92,9 +85,6 @@ public class PluginCapiListener implements Listener
|
||||
FPlayer someFPlayer = FPlayers.i.get(somePlayer);
|
||||
if (someFPlayer.getRelationTo(fme).isAtLeast(Rel.ALLY))
|
||||
event.getThem().add(somePlayer);
|
||||
// Send to any players who are spying chat
|
||||
else if(someFPlayer.isSpyingChat())
|
||||
someFPlayer.sendMessage("[ACspy]: " + event.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,31 @@
|
||||
package com.massivecraft.factions.listeners;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.UnknownFormatConversionException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
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.PlayerChatEvent;
|
||||
import org.bukkit.plugin.AuthorNagException;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredListener;
|
||||
|
||||
import com.massivecraft.factions.Conf;
|
||||
import com.massivecraft.factions.FPlayer;
|
||||
import com.massivecraft.factions.FPlayers;
|
||||
import com.massivecraft.factions.Faction;
|
||||
import com.massivecraft.factions.P;
|
||||
import com.massivecraft.factions.struct.ChatMode;
|
||||
import com.massivecraft.factions.struct.Rel;
|
||||
|
||||
|
||||
public class FactionsChatListener implements Listener
|
||||
{
|
||||
public P p;
|
||||
@ -28,158 +34,232 @@ public class FactionsChatListener implements Listener
|
||||
this.p = p;
|
||||
}
|
||||
|
||||
// this is for handling slashless command usage and faction/alliance chat, set at lowest priority so Factions gets to them first
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerEarlyChat(PlayerChatEvent event)
|
||||
public static Field fieldRegisteredListenerDotPriority;
|
||||
public static final Pattern parsePattern;
|
||||
static
|
||||
{
|
||||
if (event.isCancelled()) return;
|
||||
|
||||
Player talkingPlayer = event.getPlayer();
|
||||
String msg = event.getMessage();
|
||||
FPlayer me = FPlayers.i.get(talkingPlayer);
|
||||
ChatMode chat = me.getChatMode();
|
||||
|
||||
// slashless factions commands need to be handled here if the user isn't in public chat mode
|
||||
if (chat != ChatMode.PUBLIC && p.handleCommand(talkingPlayer, msg))
|
||||
try
|
||||
{
|
||||
if (Conf.logPlayerCommands)
|
||||
Bukkit.getLogger().log(Level.INFO, "[PLAYER_COMMAND] "+talkingPlayer.getName()+": "+msg);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
fieldRegisteredListenerDotPriority = RegisteredListener.class.getDeclaredField("priority");
|
||||
fieldRegisteredListenerDotPriority.setAccessible(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
P.p.log(Level.SEVERE, "A reflection trick is broken! This will lead to glitchy relation-colored-chat.");
|
||||
}
|
||||
|
||||
// Is it a faction chat message?
|
||||
if (chat == ChatMode.FACTION)
|
||||
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(PlayerChatEvent event)
|
||||
{
|
||||
if (Conf.chatSetFormat)
|
||||
{
|
||||
Faction myFaction = me.getFaction();
|
||||
|
||||
String message = String.format(Conf.factionChatFormat, me.describeTo(myFaction), msg);
|
||||
myFaction.sendMessage(message);
|
||||
|
||||
Bukkit.getLogger().log(Level.INFO, ChatColor.stripColor("FactionChat "+myFaction.getTag()+": "+message));
|
||||
|
||||
//Send to any players who are spying chat
|
||||
for (FPlayer fplayer : FPlayers.i.getOnline())
|
||||
{
|
||||
if(fplayer.isSpyingChat() && fplayer.getFaction() != myFaction)
|
||||
fplayer.sendMessage("[FCspy] "+myFaction.getTag()+": "+message);
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
else if (chat == ChatMode.ALLIANCE)
|
||||
{
|
||||
Faction myFaction = me.getFaction();
|
||||
|
||||
String message = String.format(Conf.allianceChatFormat, ChatColor.stripColor(me.getNameAndTag()), msg);
|
||||
|
||||
//Send message to our own faction
|
||||
myFaction.sendMessage(message);
|
||||
|
||||
//Send to all our allies
|
||||
for (FPlayer fplayer : FPlayers.i.getOnline())
|
||||
{
|
||||
if(myFaction.getRelationTo(fplayer) == Rel.ALLY)
|
||||
fplayer.sendMessage(message);
|
||||
|
||||
//Send to any players who are spying chat
|
||||
else if(fplayer.isSpyingChat())
|
||||
fplayer.sendMessage("[ACspy]: " + message);
|
||||
}
|
||||
|
||||
Bukkit.getLogger().log(Level.INFO, ChatColor.stripColor("AllianceChat: "+message));
|
||||
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
event.setFormat(Conf.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
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerChat(PlayerChatEvent event)
|
||||
|
||||
/**
|
||||
* 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 synchronized void onPlayerChat(PlayerChatEvent event)
|
||||
{
|
||||
if (event.isCancelled()) return;
|
||||
// Should we even parse?
|
||||
if ( ! Conf.chatParseTags) return;
|
||||
if (Conf.chatTagHandledByAnotherPlugin) return;
|
||||
|
||||
// Are we to insert the Faction tag into the format?
|
||||
// If we are not to insert it - we are done.
|
||||
if ( ! Conf.chatTagEnabled || Conf.chatTagHandledByAnotherPlugin) return;
|
||||
Player from = event.getPlayer();
|
||||
FPlayer fpfrom = FPlayers.i.get(from);
|
||||
String format = event.getFormat();
|
||||
String message = event.getMessage();
|
||||
|
||||
Player talkingPlayer = event.getPlayer();
|
||||
String msg = event.getMessage();
|
||||
String eventFormat = event.getFormat();
|
||||
FPlayer me = FPlayers.i.get(talkingPlayer);
|
||||
int InsertIndex = 0;
|
||||
String formatWithoutColor = parseTags(format, from, fpfrom);
|
||||
|
||||
if (!Conf.chatTagReplaceString.isEmpty() && eventFormat.contains(Conf.chatTagReplaceString))
|
||||
if ( ! Conf.chatParseTagsColored)
|
||||
{
|
||||
// we're using the "replace" method of inserting the faction tags
|
||||
// if they stuck "[FACTION_TITLE]" in there, go ahead and do it too
|
||||
if (eventFormat.contains("[FACTION_TITLE]"))
|
||||
{
|
||||
eventFormat = eventFormat.replace("[FACTION_TITLE]", me.getTitle());
|
||||
}
|
||||
InsertIndex = eventFormat.indexOf(Conf.chatTagReplaceString);
|
||||
eventFormat = eventFormat.replace(Conf.chatTagReplaceString, "");
|
||||
Conf.chatTagPadAfter = false;
|
||||
Conf.chatTagPadBefore = false;
|
||||
}
|
||||
else if (!Conf.chatTagInsertAfterString.isEmpty() && eventFormat.contains(Conf.chatTagInsertAfterString))
|
||||
{
|
||||
// we're using the "insert after string" method
|
||||
InsertIndex = eventFormat.indexOf(Conf.chatTagInsertAfterString) + Conf.chatTagInsertAfterString.length();
|
||||
}
|
||||
else if (!Conf.chatTagInsertBeforeString.isEmpty() && eventFormat.contains(Conf.chatTagInsertBeforeString))
|
||||
{
|
||||
// we're using the "insert before string" method
|
||||
InsertIndex = eventFormat.indexOf(Conf.chatTagInsertBeforeString);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we'll fall back to using the index place method
|
||||
InsertIndex = Conf.chatTagInsertIndex;
|
||||
if (InsertIndex > eventFormat.length())
|
||||
return;
|
||||
// The case without color is really this simple (:
|
||||
event.setFormat(formatWithoutColor);
|
||||
return;
|
||||
}
|
||||
|
||||
String formatStart = eventFormat.substring(0, InsertIndex) + ((Conf.chatTagPadBefore && !me.getChatTag().isEmpty()) ? " " : "");
|
||||
String formatEnd = ((Conf.chatTagPadAfter && !me.getChatTag().isEmpty()) ? " " : "") + eventFormat.substring(InsertIndex);
|
||||
// So you want color eh? You monster :O
|
||||
|
||||
String nonColoredMsgFormat = formatStart + me.getChatTag().trim() + formatEnd;
|
||||
// 1. We cancel the chat event on EventPriority.HIGHEST
|
||||
event.setCancelled(true);
|
||||
|
||||
// Relation Colored?
|
||||
if (Conf.chatTagRelationColored)
|
||||
// 2. We trigger EventPriority.MONITOR manually without relation color.
|
||||
PlayerChatEvent monitorOnlyEvent = new PlayerChatEvent(from, message);
|
||||
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())
|
||||
{
|
||||
// We must choke the standard message and send out individual messages to all players
|
||||
// Why? Because the relations will differ.
|
||||
event.setCancelled(true);
|
||||
FPlayer fpto = FPlayers.i.get(to);
|
||||
String formatWithColor = parseTags(format, from, fpfrom, to, fpto);
|
||||
to.sendMessage(String.format(formatWithColor, from.getDisplayName(), message));
|
||||
}
|
||||
}
|
||||
|
||||
for (Player listeningPlayer : event.getRecipients())
|
||||
{
|
||||
FPlayer you = FPlayers.i.get(listeningPlayer);
|
||||
String yourFormat = formatStart + me.getChatTag(you).trim() + formatEnd;
|
||||
try
|
||||
/**
|
||||
* This is some nasty woodo - I know :/
|
||||
* I should make a pull request to Bukkit and CraftBukkit to support this feature natively
|
||||
*/
|
||||
public static synchronized void callEventAtMonitorOnly(Event event)
|
||||
{
|
||||
synchronized(Bukkit.getPluginManager())
|
||||
{
|
||||
HandlerList handlers = event.getHandlers();
|
||||
RegisteredListener[] listeners = handlers.getRegisteredListeners();
|
||||
|
||||
for (RegisteredListener registration : listeners)
|
||||
{
|
||||
try
|
||||
{
|
||||
listeningPlayer.sendMessage(String.format(yourFormat, talkingPlayer.getDisplayName(), msg));
|
||||
EventPriority priority = (EventPriority) fieldRegisteredListenerDotPriority.get(registration);
|
||||
if (priority != EventPriority.MONITOR) continue;
|
||||
}
|
||||
catch (UnknownFormatConversionException ex)
|
||||
catch (Exception e)
|
||||
{
|
||||
Conf.chatTagInsertIndex = 0;
|
||||
P.p.log(Level.SEVERE, "Critical error in chat message formatting!");
|
||||
P.p.log(Level.SEVERE, "NOTE: This has been automatically fixed right now by setting chatTagInsertIndex to 0.");
|
||||
P.p.log(Level.SEVERE, "For a more proper fix, please read this regarding chat configuration: http://massivecraft.com/plugins/factions/config#Chat_configuration");
|
||||
return;
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Write to the log... We will write the non colored message.
|
||||
String nonColoredMsg = ChatColor.stripColor(String.format(nonColoredMsgFormat, talkingPlayer.getDisplayName(), msg));
|
||||
Bukkit.getLogger().log(Level.INFO, nonColoredMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No relation color.
|
||||
event.setFormat(nonColoredMsgFormat);
|
||||
// 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 = FPlayers.i.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 = FPlayers.i.get(from);
|
||||
FPlayer fpto = FPlayers.i.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"))
|
||||
{
|
||||
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 = Conf.chatSingleFormats.get(formatName);
|
||||
try
|
||||
{
|
||||
str = String.format(format, str);
|
||||
}
|
||||
catch (Exception e) { }
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public abstract class SpiralTask implements Runnable
|
||||
private transient int length = -1;
|
||||
private transient int current = 0;
|
||||
|
||||
@SuppressWarnings("LeakingThisInConstructor")
|
||||
// @SuppressWarnings("LeakingThisInConstructor") This actually triggers a warning in Eclipse xD Could we find another way to suppress the error please? :)
|
||||
public SpiralTask(FLocation fLocation, int radius)
|
||||
{
|
||||
// limit is determined based on spiral leg length for given radius; see insideRadius()
|
||||
|
Loading…
Reference in New Issue
Block a user