593 lines
17 KiB
Java
593 lines
17 KiB
Java
package net.mc_pandacraft.java.plugin.pandacraftutils.modules;
|
|
|
|
import java.sql.Date;
|
|
import java.sql.SQLException;
|
|
import java.text.DateFormat;
|
|
import java.util.ArrayList;
|
|
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;
|
|
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;
|
|
|
|
public class PrivateMessagesManager extends BukkitRunnable {
|
|
private PandacraftUtils plugin = PandacraftUtils.getInstance();
|
|
|
|
|
|
private static final long TIMEOUT_WEB_SESSION = 10000; // msec
|
|
|
|
|
|
|
|
public PrivateMessagesManager()
|
|
{
|
|
plugin.getServer().getScheduler().runTaskTimer(plugin, this, 2L, 10L);
|
|
|
|
|
|
|
|
|
|
// récupération des /mail
|
|
/*
|
|
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);
|
|
*/
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} 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");
|
|
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
|
|
tryDisplayMessageToConsole(messEl);
|
|
}
|
|
|
|
if (sender.isPlayer()) {
|
|
OnlinePlayer op = OnlinePlayerManager.get(plugin.getServer().getPlayer(sender.senderName));
|
|
if (op != null)
|
|
op.setLastMessageTarget("g:"+groupEl.getGroupName());
|
|
}
|
|
|
|
|
|
} 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");
|
|
|
|
OffPlayer offP = new OffPlayer(dest);
|
|
if (!offP.hasPlayedBefore()) {
|
|
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)) {
|
|
MPMessageElement el = new MPMessageElement(time, secKey, sender.senderName, sender.senderName, message, true, true);
|
|
el.setDestNick(destUserName);
|
|
el.save();
|
|
tryDisplayMessage(el);
|
|
}
|
|
|
|
MPMessageElement elCible = new MPMessageElement(time, secKey, destUserName, sender.senderName, message, false, true);
|
|
elCible.setDestNick(destUserName);
|
|
elCible.save();
|
|
tryDisplayMessage(elCible);
|
|
|
|
|
|
tryDisplayMessageToConsole(elCible);
|
|
|
|
if (sender.isPlayer()) {
|
|
OnlinePlayer op = OnlinePlayerManager.get(plugin.getServer().getPlayer(sender.senderName));
|
|
if (op != null)
|
|
op.setLastMessageTarget(destUserName);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
*
|
|
* @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 où 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());
|
|
|
|
MessageSender sender = new MessageSender(message.getSourceNick());
|
|
|
|
boolean isIgnoring = sender.isPlayer() && offP.getEssentialsUser().isIgnoredPlayer(new OffPlayer(message.getSourceNick()).getEssentialsUser());
|
|
|
|
|
|
if (isIgnoring) {
|
|
message.delete();
|
|
return;
|
|
}
|
|
|
|
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());
|
|
|
|
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+")");
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// -------
|
|
|
|
|
|
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();
|
|
|
|
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 {
|
|
|
|
|
|
String senderAff = new MessageSender(message.getSourceNick()).getDisplayName();
|
|
|
|
|
|
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();
|
|
|
|
if (message.getSourceNick() != null)
|
|
tooltipLines.add(0, ChatColor.GRAY+"(Cliquez pour répondre)");
|
|
|
|
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());
|
|
|
|
// op.getPlayer().playSound(op.getPlayer().getLocation(), Sound.ORB_PICKUP, 1, 0.3F);
|
|
}
|
|
|
|
|
|
|
|
} 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"));
|
|
|
|
|
|
} 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();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
*
|
|
* @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
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
|
|
}
|