PandacraftUtils/src/net/mc_pandacraft/java/plugin/pandacraftutils/modules/PrivateMessagesManager.java

593 lines
17 KiB
Java
Raw Normal View History

2015-05-11 04:44:19 +02:00
package net.mc_pandacraft.java.plugin.pandacraftutils.modules;
import java.sql.Date;
import java.sql.SQLException;
import java.text.DateFormat;
import java.util.ArrayList;
2015-05-11 04:44:19 +02:00
import java.util.List;
import java.util.Locale;
import java.util.Random;
import mkremins.fanciful.FancyMessage;
import net.mc_pandacraft.java.plugin.pandacraftutils.PandacraftUtils;
import net.mc_pandacraft.java.plugin.pandacraftutils.commands.AbstractCommandExecutor;
import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.MPGroupElement;
import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.MPGroupTable;
import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.MPGroupUserElement;
import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.MPGroupUserTable;
import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.MPMessageElement;
import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.MPMessageTable;
import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.MPWebSessionElement;
import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.MPWebSessionTable;
2015-05-11 04:44:19 +02:00
import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.ORM;
import net.mc_pandacraft.java.plugin.pandacraftutils.players.OffPlayer;
import net.mc_pandacraft.java.plugin.pandacraftutils.players.OnlinePlayer;
import net.mc_pandacraft.java.plugin.pandacraftutils.players.OnlinePlayerManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import de.luricos.bukkit.xAuth.events.xAuthLoginEvent;
2015-05-11 04:44:35 +02:00
2015-05-11 04:44:19 +02:00
public class PrivateMessagesManager extends BukkitRunnable {
private PandacraftUtils plugin = PandacraftUtils.getInstance();
private static final long TIMEOUT_WEB_SESSION = 10000; // msec
2015-05-11 04:44:19 +02:00
public PrivateMessagesManager()
{
plugin.getServer().getScheduler().runTaskTimer(plugin, this, 2L, 10L);
2015-05-11 04:44:35 +02:00
// récupération des /mail
/*
2015-05-11 04:44:35 +02:00
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable() {
@Override
public void run() {
UserMap players = EssentialsInterface.getPlugin().getUserMap();
plugin.getLogger().info("Importing player's /mail from Essentials data ...");
if (players == null) return;
plugin.getLogger().info("There are "+players.getUniqueUsers()+" players files in Essentials/userdata");
Set<String> users = players.getAllUniqueUsers();
for (String su : users) {
User u = players.getUser(su);
if (u.getBase() != null && u.getBase().isOnline()) continue;
List<String> mails = u.getMails();
if (mails.isEmpty()) continue;
for (String mail : mails) {
String[] split = mail.split(":", 2);
String sourceName = split[0].trim();
String message = split[1].trim();
try {
inputMessage(new MessageSender(sourceName), u.getName(), message);
} catch (MessageSendingException e) {
plugin.getLogger().severe(e.getMessage());
}
}
u.setMails(null);
}
players.reloadConfig();
}
}, 1L);
*/
2015-05-11 04:44:19 +02:00
}
@Override
public void run() {
// récupération des messages non synchronisé :
try {
List<MPMessageElement> messages = ((MPMessageTable)ORM.getTable("mp_message")).getAllUnsyncMessage();
for (MPMessageElement message : messages) {
if (message.getViewerNick().equals(message.getSourceNick()))
tryDisplayMessageToConsole(message);
tryDisplayMessage(message);
message.setServerSync(true);
message.save();
}
2015-05-11 04:44:35 +02:00
2015-05-11 04:44:19 +02:00
} catch (SQLException e) {
plugin.getLogger().severe("Impossible de récupérer les messages privés de la base de donnée");
e.printStackTrace();
}
}
/**
* @param sender l'origine du message
* @param message le message
* @throws MessageSendingException
*/
public void respondMessage(MessageSender sender, String message) throws MessageSendingException {
OnlinePlayer op = OnlinePlayerManager.get(Bukkit.getPlayer(sender.senderName));
if (op == null)
throw new MessageSendingException("Seul les joueurs en ligne peuvent utiliser /r");
2015-05-11 04:44:19 +02:00
if (op.getLastMessageTarget() == null)
throw new MessageSendingException("Vous n'avez pas encore envoyé de message. Utilisez /msg");
inputMessage(sender, op.getLastMessageTarget(), message);
}
/**
* @param sender l'origine du message
* @param dest pseudo du destinataire ou "g:" suivi du nom du groupe destinataire (insensible à la casse)
* @param message le message
* @throws MessageSendingException
*/
public void inputMessage(MessageSender sender, String dest, String message) throws MessageSendingException {
if (dest.startsWith("g:") || dest.startsWith("G:")) {
// groupe
String groupe = dest.substring(2);
if (!AbstractCommandExecutor.isValidPlayerName(groupe))
throw new MessageSendingException("Le nom du groupe n'est pas valide (lettres, chiffres, §7_§r et entre 2 et 16 caractères)");
MPGroupElement groupEl = null;
try {
groupEl = ((MPGroupTable)ORM.getTable("mp_group")).getFirst("groupName LIKE '"+groupe+ "'", "id");
if (groupEl == null)
throw new MessageSendingException("Ce groupe n'existe pas");
// on vérifie si le joueur source est dans le groupe
if (sender.isPlayer()) {
MPGroupUserElement userInGroup = ((MPGroupUserTable)ORM.getTable("mp_group_user")).getPlayerInGroup(groupEl, sender.senderName);
if (userInGroup == null)
throw new MessageSendingException("Vous n'êtes pas dans ce groupe");
}
List<MPGroupUserElement> groupUsers = groupEl.getUsers();
long time = System.currentTimeMillis();
int secKey = new Random().nextInt();
for (MPGroupUserElement userInGroup : groupUsers) {
MPMessageElement messEl = new MPMessageElement(time, secKey, userInGroup.getPlayerName(), sender.senderName, message, (userInGroup.getPlayerName().equalsIgnoreCase(sender.senderName)), true);
messEl.setDestGroup(groupEl.getId());
messEl.save();
tryDisplayMessage(messEl);
if (userInGroup.getPlayerName().equalsIgnoreCase(sender.senderName)
|| (!(sender.isPlayer()) && userInGroup == groupUsers.get(0))) // affiche aussi les messages provenant de la console, vers les groupes
2015-05-11 04:44:19 +02:00
tryDisplayMessageToConsole(messEl);
}
if (sender.isPlayer()) {
OnlinePlayer op = OnlinePlayerManager.get(plugin.getServer().getPlayer(sender.senderName));
if (op != null)
op.setLastMessageTarget("g:"+groupEl.getGroupName());
}
2015-05-11 04:44:19 +02:00
} catch (SQLException e) {
e.printStackTrace();
throw new MessageSendingException("Erreur lors de la récupération du groupe ou de ses membres");
}
}
else {
// joueur
if (!AbstractCommandExecutor.isValidPlayerName(dest))
throw new MessageSendingException("Le pseudo n'est pas valide");
2015-05-11 04:44:19 +02:00
OffPlayer offP = new OffPlayer(dest);
if (!offP.hasPlayedBefore()) {
2015-05-11 04:44:19 +02:00
throw new MessageSendingException("Le joueur n'a jamais existé");
}
String destUserName = offP.getCastCorrectedName();
long time = System.currentTimeMillis();
int secKey = new Random().nextInt();
if (sender.isPlayer() && !destUserName.equalsIgnoreCase(sender.senderName)) {
2015-05-11 04:44:19 +02:00
MPMessageElement el = new MPMessageElement(time, secKey, sender.senderName, sender.senderName, message, true, true);
el.setDestNick(destUserName);
el.save();
tryDisplayMessage(el);
}
2015-05-11 04:44:35 +02:00
MPMessageElement elCible = new MPMessageElement(time, secKey, destUserName, sender.senderName, message, false, true);
2015-05-11 04:44:19 +02:00
elCible.setDestNick(destUserName);
elCible.save();
tryDisplayMessage(elCible);
tryDisplayMessageToConsole(elCible);
2015-05-11 04:44:35 +02:00
if (sender.isPlayer()) {
OnlinePlayer op = OnlinePlayerManager.get(plugin.getServer().getPlayer(sender.senderName));
if (op != null)
op.setLastMessageTarget(destUserName);
}
2015-05-11 04:44:19 +02:00
}
}
/**
*
* @param player le joueur qui veut voir ses messages non lus
* @return vrai si le joueur a bien des messages non lu, faux sinon. Retourne vrai en cas d'erreur lors de la récupération des messages
*/
public boolean displayUnreadMessages(Player player) {
try {
List<MPMessageElement> messages = ((MPMessageTable)ORM.getTable("mp_message")).getAllUnreadForPlayer(player.getName());
if (messages.size() == 0) {
player.sendMessage(ChatColor.GRAY+"Vous n'avez pas de messages non lus");
return false;
}
for(MPMessageElement mess : messages)
tryDisplayMessage(mess);
return true;
} catch (SQLException e) {
e.printStackTrace();
player.sendMessage(ChatColor.RED+"Impossible de lire les messages non lus");
return true;
}
}
/**
* Tente d'afficher le message dans le cas le joueur cible est en ligne. Si ce
* joueur est en ligne, le message est marqué comme lu. Si le joueur cible ignore
* la source du message, la copie du message est supprimé de la base.
* @param message le message à afficher
*/
private void tryDisplayMessage(MPMessageElement message) {
try {
OffPlayer offP = new OffPlayer(message.getViewerNick());
2015-05-11 04:44:19 +02:00
MessageSender sender = new MessageSender(message.getSourceNick());
boolean isIgnoring = sender.isPlayer() && offP.getEssentialsUser().isIgnoredPlayer(new OffPlayer(message.getSourceNick()).getEssentialsUser());
2015-05-11 04:44:19 +02:00
if (isIgnoring) {
message.delete();
return;
2015-05-11 04:44:19 +02:00
}
OnlinePlayer op = OnlinePlayerManager.get(offP.getBukkitOnlinePlayer());
if (op == null) return; // la cible n'est pas en ligne
if (!op.isAuthenticated()) return; // la cible n'a pas fait son /login
message.setRead(true);
message.save();
// le message est affiché sur l'écran de la source du message
boolean dispToSender = (message.getViewerNick().equalsIgnoreCase(message.getSourceNick()));
// -------
// tooltip
// -------
Date d = new Date(message.getTime());
DateFormat date = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.FRANCE);
DateFormat hour = DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.FRANCE);
String affDate = date.format(d) + " à " + hour.format(d);
List<String> tooltipLines = new ArrayList<String>();
tooltipLines.add(ChatColor.GRAY+affDate);
tooltipLines.add(ChatColor.GRAY+"de "+ChatColor.RESET+new MessageSender(message.getSourceNick()).getDisplayName()+ChatColor.GRAY+" ("+displayablePlayerStatus(getPlayerStatut(message.getSourceNick()))+ChatColor.GRAY+")");
if (message.getDestGroup() == null) // vers un joueur
tooltipLines.add(ChatColor.GRAY+"vers "+ChatColor.RESET+new OffPlayer(message.getDestNick()).getDisplayName()+ChatColor.GRAY+" ("+displayablePlayerStatus(getPlayerStatut(message.getDestNick()))+ChatColor.GRAY+")");
else { // vers un groupe
MPGroupElement groupEl = message.getDestGroupElement();
tooltipLines.add(ChatColor.GRAY+"vers le groupe "+ChatColor.GOLD+groupEl.getGroupName());
2015-05-11 04:44:19 +02:00
List<MPGroupUserElement> groupUsers = groupEl.getUsers();
for (MPGroupUserElement gUser : groupUsers) {
if (!gUser.getPlayerName().equalsIgnoreCase(message.getSourceNick()))
tooltipLines.add(ChatColor.GRAY+"- "+ChatColor.RESET+new OffPlayer(gUser.getPlayerName()).getDisplayName()+ChatColor.GRAY+" ("+displayablePlayerStatus(getPlayerStatut(gUser.getPlayerName()))+ChatColor.GRAY+")");
}
2015-05-11 04:44:19 +02:00
}
// -------
if (dispToSender) {
String destAff = (message.getDestGroup() == null)?
( (message.getDestNick().equalsIgnoreCase(message.getViewerNick())) ?
"moi":
new OffPlayer(message.getDestNick()).getDisplayName()
):
ChatColor.GOLD+"g:"+message.getDestGroupElement().getGroupName();
String destCommand = (message.getDestGroup() == null)?
message.getDestNick():
"g:"+message.getDestGroupElement().getGroupName();
2015-05-11 04:44:19 +02:00
tooltipLines.add(0, ChatColor.GRAY+"(Cliquez pour répondre)");
new FancyMessage("")
.then("§6<§rmoi§6 → §r"+destAff+"§r§6>")
.suggest("/m "+destCommand+" ")
.tooltip(tooltipLines)
.then(" §6"+ChatColor.translateAlternateColorCodes('&', message.getMessage()).replace("§r", "§r§6"))
.color(ChatColor.GOLD)
.send(op.getPlayer());
}
else {
2015-05-11 04:44:19 +02:00
String senderAff = new MessageSender(message.getSourceNick()).getDisplayName();
2015-05-11 04:44:19 +02:00
String destAff = (message.getDestGroup() == null)?
((message.getDestNick().equalsIgnoreCase(message.getViewerNick()))?
"moi":
new OffPlayer(message.getDestNick()).getDisplayName()):
ChatColor.GOLD+"g:"+message.getDestGroupElement().getGroupName();
String destCommand = (message.getDestGroup() == null)?
message.getSourceNick():
"g:"+message.getDestGroupElement().getGroupName();
2015-05-11 04:44:19 +02:00
if (message.getSourceNick() != null)
tooltipLines.add(0, ChatColor.GRAY+"(Cliquez pour répondre)");
2015-05-11 04:44:19 +02:00
FancyMessage fm = new FancyMessage("")
.then("§6<§r"+senderAff+"§r§6 → §r"+destAff+"§r§6>");
if (message.getSourceNick() != null)
fm.suggest("/m "+destCommand+" ");
fm.tooltip(tooltipLines)
.then(" §6"+ChatColor.translateAlternateColorCodes('&', message.getMessage()).replace("§r", "§r§6"))
.color(ChatColor.GOLD)
.send(op.getPlayer());
2015-05-11 04:44:19 +02:00
// op.getPlayer().playSound(op.getPlayer().getLocation(), Sound.ORB_PICKUP, 1, 0.3F);
2015-05-11 04:44:19 +02:00
}
2015-05-11 04:44:19 +02:00
} catch (SQLException e) {
plugin.getLogger().severe("Impossible d'afficher un message");
e.printStackTrace();
}
}
private void tryDisplayMessageToConsole(MPMessageElement message) {
try {
String senderAff = new MessageSender(message.getSourceNick()).getDisplayName();
String destAff = (message.getDestGroup() == null)?
new OffPlayer(message.getDestNick()).getDisplayName():
"g:"+message.getDestGroupElement().getGroupName();
plugin.getServer().getConsoleSender().sendMessage("§6<§r"+senderAff+"§r§6 → §r"+destAff+"§r§6> §6"+ChatColor.translateAlternateColorCodes('&', message.getMessage()).replace("§r", "§r§6"));
2015-05-11 04:44:19 +02:00
} catch (SQLException e) {
plugin.getLogger().severe("Impossible d'afficher un message");
e.printStackTrace();
}
}
public void onxAuthLogin(xAuthLoginEvent event) {
try {
List<MPMessageElement> messages = ((MPMessageTable)ORM.getTable("mp_message")).getAllUnreadForPlayer(event.getPlayer().getName());
if (messages.size() == 0) return;
String[] m = new String[] {
ChatColor.GOLD+"--------------- Messagerie privée ---------------",
ChatColor.GOLD+"Vous avez "+messages.size()+" message"+((messages.size()>1)?"s":"")+" non lu"+((messages.size()>1)?"s":""),
ChatColor.GOLD+"Faites "+ChatColor.GRAY+"/m"+ChatColor.GOLD+" pour voir le"+((messages.size()>1)?"s":"")+" message"+((messages.size()>1)?"s":""),
ChatColor.GOLD+"----------------------------------------------",
};
event.getPlayer().sendMessage(m);
} catch(SQLException e) {
e.printStackTrace();
}
}
2015-05-11 04:44:19 +02:00
/**
*
* @param playerName le pseudo du joueur, insensible à la casse.
* @return Le statut du joueur passé en paramètre.<br/>
* <code>null</code> si le paramètre est <code>null</code>.
*/
private PlayerStatut getPlayerStatut(String playerName) {
if (playerName == null)
return null;
if (!AbstractCommandExecutor.isValidPlayerName(playerName))
return PlayerStatut.OFFLINE;
OnlinePlayer op = OnlinePlayerManager.get(playerName);
if (op != null)
return op.isAfk() ? PlayerStatut.AFK_IG : PlayerStatut.ONLINE_IG;
try {
MPWebSessionElement webSession = ((MPWebSessionTable)ORM.getTable("mp_web_session")).getFirst("playerName LIKE '"+playerName+"'", null);
if (webSession != null) {
long lastWebActivity = webSession.getLastWebActivity();
if (System.currentTimeMillis() - lastWebActivity < TIMEOUT_WEB_SESSION)
return PlayerStatut.ONLINE_WEB;
}
} catch (SQLException e) {
e.printStackTrace();
}
return PlayerStatut.OFFLINE;
}
private String displayablePlayerStatus(PlayerStatut ps) {
if (ps == PlayerStatut.ONLINE_IG)
return ChatColor.GREEN+"En ligne, IG";
if (ps == PlayerStatut.AFK_IG)
return ChatColor.YELLOW+"AFK, IG";
if (ps == PlayerStatut.ONLINE_WEB)
return ChatColor.GOLD+"En ligne, web";
if (ps == PlayerStatut.OFFLINE)
return ChatColor.GRAY+"Hors ligne";
return ChatColor.WHITE+"N/A";
}
public enum PlayerStatut {
ONLINE_IG, AFK_IG, ONLINE_WEB, OFFLINE
}
2015-05-11 04:44:19 +02:00
public static class MessageSender {
public final String senderName;
public MessageSender(String pName) {
senderName = pName;
}
public MessageSender() {
this((String)null);
}
public MessageSender(OffPlayer p) {
this(p.getName());
}
public MessageSender(CommandSender sender) {
this((sender instanceof Player)?sender.getName():null);
}
public boolean isPlayer() {
return senderName != null;
}
public String getDisplayName() {
if (isPlayer())
return new OffPlayer(senderName).getDisplayName();
else
return ChatColor.GOLD+"Système"+ChatColor.RESET;
}
}
@SuppressWarnings("serial")
public class MessageSendingException extends Exception {
private MessageSendingException(String mess) {
super(mess);
}
}
}