/* * CommandBook * Copyright (C) 2011 sk89q <http://www.sk89q.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.sk89q.commandbook; import com.sk89q.commandbook.events.CommandSenderMessageEvent; import com.sk89q.commandbook.events.SharedMessageEvent; import com.sk89q.commandbook.session.AdministrativeSession; import com.sk89q.commandbook.session.SessionComponent; import com.sk89q.commandbook.session.UserSession; import com.sk89q.commandbook.util.ChatUtil; import com.sk89q.commandbook.util.InputUtil; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.zachsthings.libcomponents.ComponentInformation; import com.zachsthings.libcomponents.Depend; import com.zachsthings.libcomponents.InjectComponent; import com.zachsthings.libcomponents.bukkit.BasePlugin; import com.zachsthings.libcomponents.bukkit.BukkitComponent; import com.zachsthings.libcomponents.config.ConfigurationBase; import com.zachsthings.libcomponents.config.ConfigurationNode; import com.zachsthings.libcomponents.config.Setting; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; import java.util.HashSet; import static com.sk89q.commandbook.util.ChatUtil.replaceColorMacros; @ComponentInformation(friendlyName = "Messaging", desc = "Commands that involve direct player <-> player or player <-> admin" + "communication are handled through this component.") @Depend(components = SessionComponent.class) public class MessagingComponent extends BukkitComponent implements Listener { @InjectComponent private SessionComponent sessions; private LocalConfiguration config; @Override public void enable() { config = configure(new LocalConfiguration()); registerCommands(Commands.class); CommandBook.registerEvents(this); } @Override public void reload() { super.reload(); configure(config); } private static class LocalConfiguration extends ConfigurationBase { @Setting("console-say-format") public String consoleSayFormat = "<`r*Console`w> %s"; @Setting("broadcast-format") public String broadcastFormat = "`r[Broadcast] %s"; @Setting("pm-color") private String pmColorString = "GRAY"; @Setting("pm-text-color") private String pmTextColorString = "RESET"; public ChatColor pmColor = ChatColor.GRAY; // Color for PM label public ChatColor pmTextColor = ChatColor.RESET; // Color for text of PM @Setting("twitter-style") public boolean twitterStyle = true; @Override public void load(ConfigurationNode node) { super.load(node); boolean error = false; try { pmColor = ChatColor.valueOf(pmColorString); } catch (IllegalArgumentException e) { CommandBook.logger().warning("Unknown PM Color '" + pmColorString + "'! Resetting to GRAY"); pmColor = ChatColor.GRAY; pmColorString = "GRAY"; error = true; } try { pmTextColor = ChatColor.valueOf(pmTextColorString); } catch (IllegalArgumentException e) { CommandBook.logger().warning("Unknown PM Color '" + pmTextColorString + "'! Resetting to GRAY"); pmTextColor = ChatColor.GRAY; pmTextColorString = "GRAY"; error = true; } if (error) { save(node); } } } public void messagePlayer(CommandSender sender, String target, String message) throws CommandException { CommandSender receiver = InputUtil.PlayerParser.matchPlayerOrConsole(sender, target); UserSession receiverSession = sessions.getSession(UserSession.class, receiver); AFKComponent.AFKSession afkSession = sessions.getSession(AFKComponent.AFKSession.class, receiver); if (afkSession.isAFK()) { String status = afkSession.getIdleStatus(); sender.sendMessage(config.pmColor + ChatUtil.toColoredName(receiver, config.pmColor) + " is afk. " + "They might not see your message." + (status.trim().length() == 0 ? "" : " (" + status + ")")); } receiver.sendMessage(config.pmColor + "(From " + ChatUtil.toColoredName(sender, config.pmColor) + "): " + config.pmTextColor + message); sender.sendMessage(config.pmColor + "(To " + ChatUtil.toColoredName(receiver, config.pmColor) + "): " + config.pmTextColor + message); CommandBook.logger().info("(PM) " + ChatUtil.toColoredName(sender, ChatColor.RESET) + " -> " + ChatUtil.toColoredName(receiver, ChatColor.RESET) + ": " + message); sessions.getSession(UserSession.class, sender).setLastRecipient(receiver); // If the receiver hasn't had any player talk to them yet or hasn't // send a message, then we add it to the receiver's last message target // so s/he can /reply easily receiverSession.setNewLastRecipient(sender); } /** * Called on player chat. * * @param event Relevant event details */ @EventHandler public void onChat(AsyncPlayerChatEvent event) { if (sessions.getSession(AdministrativeSession.class, event.getPlayer()).isMute()) { event.getPlayer().sendMessage(ChatColor.RED + "You are muted."); event.setCancelled(true); } else if (event.getMessage().startsWith("@") && config.twitterStyle) { final String message = event.getMessage(); int spaceIndex = message.indexOf(" "); if (spaceIndex > -1) { try { String name = message.substring(1, spaceIndex); if (name.length() <= 0) { return; } messagePlayer(event.getPlayer(), name, message.substring(spaceIndex + 1)); } catch (CommandException e) { event.getPlayer().sendMessage(ChatColor.RED + e.getMessage()); } event.setCancelled(true); } } } public class Commands { @Command(aliases = {"me"}, usage = "<message...>", desc = "Send an action message", min = 1, max = -1) @CommandPermissions({"commandbook.say.me"}) public void me(CommandContext args, CommandSender sender) throws CommandException { if (sender instanceof Player && sessions.getSession(AdministrativeSession.class, sender).isMute()) { sender.sendMessage(ChatColor.RED + "You are muted."); return; } String name = ChatUtil.toColoredName(sender, ChatColor.YELLOW); String msg = args.getJoinedStrings(0); BasePlugin.callEvent( new SharedMessageEvent(name + " " + msg)); BasePlugin.server().broadcastMessage("* " + name + " " + msg); } @Command(aliases = {"say"}, usage = "<message...>", desc = "Send a message", min = 1, max = -1) @CommandPermissions({"commandbook.say"}) public void say(CommandContext args, CommandSender sender) throws CommandException { if (sender instanceof Player && sessions.getSession(AdministrativeSession.class, (Player) sender).isMute()) { sender.sendMessage(ChatColor.RED + "You are muted."); return; } String msg = args.getJoinedStrings(0); if (sender instanceof Player) { if (BasePlugin.callEvent( new AsyncPlayerChatEvent(false, (Player) sender, msg, new HashSet<Player>(BasePlugin.server().getOnlinePlayers()))).isCancelled()) { return; } } BasePlugin.callEvent( new CommandSenderMessageEvent(sender, msg)); if (sender instanceof Player) { BasePlugin.server().broadcastMessage( "<" + ChatUtil.toColoredName(sender, ChatColor.RESET) + "> " + args.getJoinedStrings(0)); } else { BasePlugin.server().broadcastMessage( replaceColorMacros(config.consoleSayFormat).replace( "%s", args.getJoinedStrings(0))); } } @Command(aliases = {"msg", "message", "whisper", "pm", "tell", "w"}, usage = "<target> <message...>", desc = "Private message a user", min = 2, max = -1) @CommandPermissions({"commandbook.msg"}) public void msg(CommandContext args, CommandSender sender) throws CommandException { // This will throw errors as needed messagePlayer(sender, args.getString(0), args.getJoinedStrings(1)); } @Command(aliases = {"reply", "r"}, usage = "<message...>", desc = "Reply to last user", min = 1, max = -1) @CommandPermissions({"commandbook.msg"}) public void reply(CommandContext args, CommandSender sender) throws CommandException { String lastRecipient = sessions.getSession(UserSession.class, sender).getLastRecipient(); if (lastRecipient == null) { throw new CommandException("You haven't messaged anyone."); } messagePlayer(sender, lastRecipient, args.getJoinedStrings(0)); } @Command(aliases = {"mute"}, usage = "<target>", desc = "Mute a player", flags = "o", min = 1, max = 1) @CommandPermissions({"commandbook.mute"}) public void mute(CommandContext args, CommandSender sender) throws CommandException { Player player = InputUtil.PlayerParser.matchSinglePlayer(sender, args.getString(0)); if (CommandBook.inst().hasPermission(player, "commandbook.mute.exempt") && !(args.hasFlag('o') && CommandBook.inst().hasPermission(sender, "commandbook.mute.exempt.override"))) { throw new CommandException("Player " + ChatUtil.toName(sender) + " is exempt from being muted!"); } if (!sessions.getSession(AdministrativeSession.class, player).setMute(true)) { if (player != sender) { player.sendMessage(ChatColor.YELLOW + "You've been muted by " + ChatUtil.toColoredName(sender, ChatColor.YELLOW)); } sender.sendMessage(ChatColor.YELLOW + "You've muted " + ChatUtil.toColoredName(player, ChatColor.YELLOW)); } else { throw new CommandException("Player " + ChatUtil.toName(player) + " is already muted!"); } } @Command(aliases = {"unmute"}, usage = "<target>", desc = "Unmute a player", min = 1, max = 1) @CommandPermissions({"commandbook.mute"}) public void unmute(CommandContext args, CommandSender sender) throws CommandException { Player player = InputUtil.PlayerParser.matchSinglePlayer(sender, args.getString(0)); if (sessions.getSession(AdministrativeSession.class, player).setMute(false)) { if (player != sender) { player.sendMessage(ChatColor.YELLOW + "You've been unmuted by " + ChatUtil.toColoredName(sender, ChatColor.YELLOW)); } sender.sendMessage(ChatColor.YELLOW + "You've unmuted " + ChatUtil.toColoredName(player, ChatColor.YELLOW)); } else { throw new CommandException("Player " + ChatUtil.toName(player) + " was not muted!"); } } @Command(aliases = {"broadcast"}, usage = "<message...>", desc = "Broadcast a message", min = 1, max = -1) @CommandPermissions({"commandbook.broadcast"}) public void broadcast(CommandContext args, CommandSender sender) throws CommandException { BasePlugin.server().broadcastMessage( replaceColorMacros(config.broadcastFormat).replace( "%s", args.getJoinedStrings(0))); } } }