1
0
mirror of https://github.com/essentials/Essentials.git synced 2025-09-25 05:41:36 +02:00

Added EssentialsXMPP from newplugins branch.

Updated to work with trunk.

git-svn-id: https://svn.java.net/svn/essentials~svn/trunk@1564 e251c2fe-e539-e718-e476-b85c1f46cddb
This commit is contained in:
snowleo
2011-06-02 13:24:26 +00:00
parent ba86a338c2
commit 2d038579ba
19 changed files with 1991 additions and 4 deletions

View File

@@ -0,0 +1,26 @@
package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.User;
import com.earth2me.essentials.commands.EssentialsCommand;
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
import org.bukkit.Server;
public class Commandsetxmpp extends EssentialsCommand
{
public Commandsetxmpp()
{
super("setxmpp");
}
@Override
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception
{
if (args.length < 1)
{
throw new NotEnoughArgumentsException();
}
EssentialsXMPP.getInstance().setAddress(user, args[0]);
}
}

View File

@@ -0,0 +1,39 @@
package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.Console;
import com.earth2me.essentials.commands.EssentialsCommand;
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class Commandxmpp extends EssentialsCommand
{
public Commandxmpp()
{
super("xmpp");
}
@Override
protected void run(Server server, CommandSender sender, String commandLabel, String[] args) throws Exception
{
if (args.length < 2)
{
throw new NotEnoughArgumentsException();
}
final String message = getFinalArg(args, 1);
final String address = EssentialsXMPP.getInstance().getAddress(args[0]);
if (address == null)
{
sender.sendMessage("§cThere are no players matching that name.");
}
else
{
final String senderName = sender instanceof Player ? ess.getUser(sender).getDisplayName() : Console.NAME;
sender.sendMessage("[" + senderName + ">" + address + "] " + message);
EssentialsXMPP.getInstance().sendMessage(address, "[" + senderName + "] " + message);
}
}
}

View File

@@ -0,0 +1,46 @@
package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.commands.EssentialsCommand;
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
import java.util.List;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class Commandxmppspy extends EssentialsCommand
{
public Commandxmppspy()
{
super("xmppspy");
}
@Override
protected void run(Server server, CommandSender sender, String commandLabel, String[] args) throws Exception
{
if (args.length < 1)
{
throw new NotEnoughArgumentsException();
}
final List<Player> matches = server.matchPlayer(args[0]);
if (matches.isEmpty())
{
sender.sendMessage("§cThere are no players matching that name.");
}
for (Player p : matches)
{
try
{
final boolean toggle = EssentialsXMPP.getInstance().toggleSpy(p);
sender.sendMessage("XMPP Spy " + (toggle ? "enabled" : "disabled") + " for " + p.getDisplayName());
}
catch (Exception ex)
{
sender.sendMessage("Error: " + ex.getMessage());
}
}
}
}

View File

@@ -0,0 +1,115 @@
package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.IEssentials;
import com.earth2me.essentials.Util;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event.Type;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
public class EssentialsXMPP extends JavaPlugin implements IEssentialsXMPP
{
private static final Logger LOGGER = Logger.getLogger("Minecraft");
private static EssentialsXMPP instance = null;
private transient UserManager users;
private transient XMPPManager xmpp;
public static IEssentialsXMPP getInstance()
{
return instance;
}
@Override
public void onEnable()
{
instance = this;
final IEssentials ess = Essentials.getStatic();
if (ess == null)
{
LOGGER.log(Level.SEVERE, "Failed to load Essentials before EssentialsXMPP");
}
final PluginManager pluginManager = getServer().getPluginManager();
final EssentialsXMPPPlayerListener playerListener = new EssentialsXMPPPlayerListener(ess);
pluginManager.registerEvent(Type.PLAYER_JOIN, playerListener, Priority.Monitor, this);
pluginManager.registerEvent(Type.PLAYER_CHAT, playerListener, Priority.Monitor, this);
pluginManager.registerEvent(Type.PLAYER_QUIT, playerListener, Priority.Monitor, this);
users = new UserManager(this.getDataFolder());
xmpp = new XMPPManager(this);
ess.addReloadListener(users);
if (!this.getDescription().getVersion().equals(Essentials.getStatic().getDescription().getVersion())) {
LOGGER.log(Level.WARNING, Util.i18n("versionMismatchAll"));
}
LOGGER.info(Util.format("loadinfo", this.getDescription().getName(), this.getDescription().getVersion(), Essentials.AUTHORS));
}
@Override
public void onDisable()
{
xmpp.disconnect();
}
@Override
public boolean onCommand(final CommandSender sender, final Command command, final String commandLabel, final String[] args)
{
return Essentials.getStatic().onCommandEssentials(sender, command, commandLabel, args, EssentialsXMPP.class.getClassLoader(), "com.earth2me.essentials.xmpp.Command");
}
@Override
public void setAddress(final Player user, final String address) throws Exception
{
final String username = user.getName().toLowerCase();
instance.users.setAddress(username, address);
}
@Override
public String getAddress(final String name)
{
return instance.users.getAddress(name);
}
@Override
public boolean toggleSpy(final Player user) throws Exception
{
final String username = user.getName().toLowerCase();
final boolean spy = !instance.users.isSpy(username);
instance.users.setSpy(username, spy);
return spy;
}
@Override
public String getAddress(final Player user)
{
return instance.users.getAddress(user.getName());
}
@Override
public void sendMessage(final Player user, final String message)
{
instance.xmpp.sendMessage(instance.users.getAddress(user.getName()), message);
}
@Override
public void sendMessage(final String address, final String message)
{
instance.xmpp.sendMessage(address, message);
}
@Override
public List<String> getSpyUsers()
{
return instance.users.getSpyUsers();
}
}

View File

@@ -0,0 +1,55 @@
package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.IEssentials;
import com.earth2me.essentials.User;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.event.player.PlayerQuitEvent;
class EssentialsXMPPPlayerListener extends PlayerListener
{
private final transient IEssentials ess;
EssentialsXMPPPlayerListener(final IEssentials ess)
{
super();
this.ess = ess;
}
@Override
public void onPlayerJoin(final PlayerJoinEvent event)
{
final User user = ess.getUser(event.getPlayer());
sendMessageToSpyUsers("Player " + user.getDisplayName() + " joined the game");
}
@Override
public void onPlayerChat(final PlayerChatEvent event)
{
final User user = ess.getUser(event.getPlayer());
sendMessageToSpyUsers(String.format(event.getFormat(), user.getDisplayName(), event.getMessage()));
}
@Override
public void onPlayerQuit(final PlayerQuitEvent event)
{
final User user = ess.getUser(event.getPlayer());
sendMessageToSpyUsers("Player " + user.getDisplayName() + " left the game");
}
private void sendMessageToSpyUsers(final String message)
{
try
{
for (String address : EssentialsXMPP.getInstance().getSpyUsers())
{
EssentialsXMPP.getInstance().sendMessage(address, message);
}
}
catch (Exception ex)
{
}
}
}

View File

@@ -0,0 +1,78 @@
package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.EssentialsConf;
import com.earth2me.essentials.IConf;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UserManager implements IConf
{
private final transient EssentialsConf users;
private final transient List<String> spyusers = new ArrayList<String>();
private final static String ADDRESS = "address";
private final static String SPY = "spy";
public UserManager(final File folder)
{
users = new EssentialsConf(new File(folder, "users.yml"));
reloadConfig();
}
public final boolean isSpy(final String username)
{
return users.getBoolean(username.toLowerCase() + "." + SPY, false);
}
public void setSpy(final String username, boolean spy) throws Exception
{
setUser(username.toLowerCase(), getAddress(username), spy);
}
public final String getAddress(final String username)
{
return users.getString(username.toLowerCase() + "." + ADDRESS, null);
}
public void setAddress(final String username, final String address) throws Exception
{
setUser(username.toLowerCase(), address, isSpy(username));
}
public List<String> getSpyUsers()
{
return spyusers;
}
private void setUser(String username, String address, boolean spy) throws Exception
{
final Map<String, Object> userdata = new HashMap<String, Object>();
userdata.put(ADDRESS, address);
userdata.put(SPY, spy);
users.setProperty(username, userdata);
users.save();
reloadConfig();
}
@Override
public final void reloadConfig()
{
users.load();
spyusers.clear();
final List<String> keys = users.getKeys(null);
for (String key : keys)
{
if (isSpy(key))
{
final String address = getAddress(key);
if (address != null)
{
spyusers.add(address);
}
}
}
}
}

View File

@@ -0,0 +1,283 @@
package com.earth2me.essentials.xmpp;
import com.earth2me.essentials.EssentialsConf;
import com.earth2me.essentials.IConf;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster.SubscriptionMode;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
public class XMPPManager extends Handler implements MessageListener, ChatManagerListener, IConf
{
private static final Logger LOGGER = Logger.getLogger("Minecraft");
private final transient EssentialsConf config;
private transient XMPPConnection connection;
private transient ChatManager chatManager;
private final transient Map<String, Chat> chats = Collections.synchronizedMap(new HashMap<String, Chat>());
private final transient JavaPlugin parent;
private transient List<String> logUsers;
private transient Level logLevel;
private transient boolean ignoreLagMessages = true;
public XMPPManager(final JavaPlugin parent)
{
super();
this.parent = parent;
config = new EssentialsConf(new File(parent.getDataFolder(), "config.yml"));
config.setTemplateName("/config.yml", EssentialsXMPP.class);
reloadConfig();
}
public void sendMessage(final String address, final String message)
{
Chat chat = null;
try
{
if (address == null || address.isEmpty())
{
return;
}
startChat(address);
chat = chats.get(address);
if (chat == null)
{
return;
}
chat.sendMessage(message.replaceAll("§[0-9a-f]", ""));
}
catch (XMPPException ex)
{
if (chat != null)
{
chat.removeMessageListener(this);
chats.remove(address);
LOGGER.log(Level.WARNING, "Failed to send xmpp message.", ex);
}
}
}
@Override
public void processMessage(final Chat chat, final Message msg)
{
final String message = msg.getBody();
if (message.length() > 0)
{
switch (message.charAt(0))
{
case '@':
sendPrivateMessage(chat, message);
break;
case '/':
sendCommand(chat, message);
break;
default:
parent.getServer().broadcastMessage("<XMPP:" + chat.getParticipant() + "> " + message);
}
}
}
private void connect()
{
final String server = config.getString("xmpp.server");
if (server == null)
{
LOGGER.log(Level.WARNING, "config broken for xmpp");
return;
}
final int port = config.getInt("xmpp.port", 5222);
final String serviceName = config.getString("xmpp.servicename", server);
final String xmppuser = config.getString("xmpp.user");
final String password = config.getString("xmpp.password");
final ConnectionConfiguration cc = new ConnectionConfiguration(server, port, serviceName);
final StringBuilder sb = new StringBuilder();
sb.append("Connecting to xmpp server ").append(server).append(":").append(port);
sb.append(" as user ").append(xmppuser).append(".");
LOGGER.log(Level.INFO, sb.toString());
cc.setSASLAuthenticationEnabled(config.getBoolean("xmpp.sasl-enabled", false));
cc.setSendPresence(true);
cc.setReconnectionAllowed(true);
connection = new XMPPConnection(cc);
try
{
connection.connect();
connection.login(xmppuser, password);
connection.getRoster().setSubscriptionMode(SubscriptionMode.accept_all);
chatManager = connection.getChatManager();
chatManager.addChatListener(this);
}
catch (XMPPException ex)
{
LOGGER.log(Level.WARNING, "Failed to connect to server: " + server, ex);
}
}
public final void disconnect()
{
if (connection != null)
{
connection.disconnect(new Presence(Presence.Type.unavailable));
}
}
@Override
public void chatCreated(final Chat chat, final boolean createdLocally)
{
if (!createdLocally)
{
chat.addMessageListener(this);
final Chat old = chats.put(chat.getParticipant(), chat);
if (old != null)
{
old.removeMessageListener(this);
}
}
}
@Override
public final void reloadConfig()
{
config.load();
synchronized (chats)
{
disconnect();
chats.clear();
connect();
}
LOGGER.removeHandler(this);
if (config.getBoolean("log-enabled", false))
{
LOGGER.addHandler(this);
logUsers = config.getStringList("log-users", new ArrayList<String>());
final String level = config.getString("log-level", "info");
try
{
logLevel = Level.parse(level.toUpperCase());
}
catch (IllegalArgumentException e)
{
logLevel = Level.INFO;
}
ignoreLagMessages = config.getBoolean("ignore-lag-messages", true);
}
}
@Override
public void publish(final LogRecord logRecord)
{
try
{
if (ignoreLagMessages && logRecord.getMessage().equals("Can't keep up! Did the system time change, or is the server overloaded?"))
{
return;
}
if (logRecord.getLevel().intValue() >= logLevel.intValue())
{
for (String user : logUsers)
{
startChat(user);
final Chat chat = chats.get(user);
if (chat != null)
{
chat.sendMessage(String.format("[" + logRecord.getLevel().getLocalizedName() + "] " + logRecord.getMessage(), logRecord.getParameters()));
}
}
}
}
catch (Exception e)
{
// Ignore all exception and just print them to the console
// Otherwise we create a loop.
System.out.println(e.getMessage());
e.printStackTrace();
}
}
@Override
public void flush()
{
}
@Override
public void close() throws SecurityException
{
}
private void startChat(final String address) throws XMPPException
{
if (chatManager == null)
{
return;
}
synchronized (chats)
{
if (!chats.containsKey(address))
{
final Chat chat = chatManager.createChat(address, this);
if (chat == null)
{
throw new XMPPException("Could not start Chat with " + address);
}
chats.put(address, chat);
}
}
}
private void sendPrivateMessage(final Chat chat, final String message)
{
final String[] parts = message.split(" ", 2);
if (parts.length == 2)
{
final List<Player> matches = parent.getServer().matchPlayer(parts[0].substring(1));
if (matches.isEmpty())
{
try
{
chat.sendMessage("User " + parts[0] + " not found");
}
catch (XMPPException ex)
{
LOGGER.log(Level.WARNING, "Failed to send xmpp message.", ex);
}
} else {
for (Player p : matches)
{
p.sendMessage("[" + chat.getParticipant() + ">" + p.getDisplayName() + "] " + message);
}
}
}
}
private void sendCommand(final Chat chat, final String message)
{
if (config.getStringList("op-users", new ArrayList<String>()).contains(chat.getParticipant()))
{
final CraftServer craftServer = (CraftServer)parent.getServer();
if (craftServer != null)
{
craftServer.dispatchCommand(new ConsoleCommandSender(craftServer), message.substring(1));
}
}
}
}

View File

@@ -0,0 +1,17 @@
xmpp:
server: 'example.com'
user: 'name@example.com'
password: 'password'
# servicename: 'example.com'
# port: 5222
# sasl-enabled: false
op-users:
# - 'name@example.com'
log-enabled: false
# Level is minimum level that should be send: info, warning, severe
log-level: warning
log-users:
# - 'name@example.com'

View File

@@ -0,0 +1,20 @@
# This determines the command prefix when there are conflicts (/name:home, /name:help, etc.)
name: EssentialsXMPP
main: com.earth2me.essentials.xmpp.EssentialsXMPP
# Note to developers: This next line cannot change, or the automatic versioning system will break.
version: TeamCity
website: http://www.earth2me.net:8001/
description: Provides xmpp communication.
authors:
- snowleo
depend: [Essentials]
commands:
setxmpp:
description: set your xmpp address
usage: /<command> address
xmpp:
description: send a message to a player
usage: /<command> player message
xmppspy:
description: toggle xmpp spy for all message
usage: /<command> player