package net.aufdemrand.denizen.events.player; import net.aufdemrand.denizen.BukkitScriptEntryData; import net.aufdemrand.denizen.Settings; import net.aufdemrand.denizen.events.BukkitScriptEvent; import net.aufdemrand.denizen.objects.dEntity; import net.aufdemrand.denizen.objects.dPlayer; import net.aufdemrand.denizen.scripts.containers.core.FormatScriptContainer; import net.aufdemrand.denizen.utilities.DenizenAPI; import net.aufdemrand.denizen.utilities.debugging.dB; import net.aufdemrand.denizencore.objects.Element; import net.aufdemrand.denizencore.objects.dList; import net.aufdemrand.denizencore.objects.dObject; import net.aufdemrand.denizencore.scripts.ScriptEntryData; import net.aufdemrand.denizencore.scripts.ScriptRegistry; import net.aufdemrand.denizencore.scripts.containers.ScriptContainer; import net.aufdemrand.denizencore.utilities.CoreUtilities; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerChatEvent; import java.util.HashSet; import java.util.List; import java.util.Set; public class ChatScriptEvent extends BukkitScriptEvent implements Listener { // TODO: in area // <--[event] // @Events // player chats (in <area>) // // @Regex ^on player chats( in ((notable (cuboid|ellipsoid))|([^\s]+)))?$ // // @Cancellable true // // @Warning Using this will forcibly sync the chat thread. // // @Triggers when a player chats. // @Context // <context.message> returns the player's message as an Element. // <context.format> returns the chat message's format. // <context.recipients> returns a list of all players that will receive the chat. // // @Determine // Element to change the message. // "FORMAT:" + dScript to set the format script the message should use. // "RECIPIENTS:" + dList(dPlayer) to set the list of players that will receive the message. // // --> public ChatScriptEvent() { instance = this; } public static ChatScriptEvent instance; public PlayerChatEvent pcEvent; public AsyncPlayerChatEvent apcEvent; public Element message; public Element format; public dPlayer player; public Set<Player> recipients; public SyncChatHandler sch = new SyncChatHandler(); public AsyncChatHandler asch = new AsyncChatHandler(); @Override public boolean couldMatch(ScriptContainer scriptContainer, String s) { String lower = CoreUtilities.toLowerCase(s); return lower.startsWith("player chats"); } @Override public boolean matches(ScriptContainer scriptContainer, String s) { return runInCheck(scriptContainer, s, CoreUtilities.toLowerCase(s), player.getLocation()); } @Override public String getName() { return "Chat"; } boolean async = false; @Override public void init() { async = Settings.worldScriptChatEventAsynchronous(); if (async) { Bukkit.getServer().getPluginManager().registerEvents(asch, DenizenAPI.getCurrentInstance()); } else { Bukkit.getServer().getPluginManager().registerEvents(sch, DenizenAPI.getCurrentInstance()); } } @Override public void destroy() { if (async) { AsyncPlayerChatEvent.getHandlerList().unregister(asch); } else { PlayerChatEvent.getHandlerList().unregister(sch); } } @Override public boolean applyDetermination(ScriptContainer container, String determination) { String lower = CoreUtilities.toLowerCase(determination); if (lower.startsWith("format:")) { String name = determination.substring(7); FormatScriptContainer formatscr = ScriptRegistry.getScriptContainer(name); if (formatscr == null) { dB.echoError("Could not find format script matching '" + name + '\''); } else { String formatstr = formatscr.getFormatText(null, player); if (net.aufdemrand.denizencore.utilities.debugging.dB.verbose) { dB.log("Setting format to " + formatstr); } format = new Element(formatstr); } } else if (lower.startsWith("recipients:")) { String rec_new = determination.substring(11); dList recs = dList.valueOf(rec_new); List<dPlayer> players = recs.filter(dPlayer.class); recipients.clear(); for (dPlayer player : players) { recipients.add(player.getPlayerEntity()); } } else if (!lower.startsWith("cancelled")) { message = new Element(determination); } else { return super.applyDetermination(container, determination); } return true; } @Override public ScriptEntryData getScriptEntryData() { return new BukkitScriptEntryData(player, null); } @Override public dObject getContext(String name) { if (name.equals("message")) { return message; } else if (name.equals("format")) { return format; } if (name.equals("recipients")) { dList list = new dList(); for (Player tplayer : recipients) { list.add(dPlayer.mirrorBukkitPlayer(tplayer).identify()); } return list; } return super.getContext(name); } class SyncChatHandler implements Listener { @EventHandler public void onSyncChat(PlayerChatEvent event) { message = new Element(event.getMessage()); format = new Element(event.getFormat()); cancelled = event.isCancelled(); recipients = new HashSet<Player>(event.getRecipients()); pcEvent = event; apcEvent = null; player = dEntity.getPlayerFrom(event.getPlayer()); fire(); event.setCancelled(cancelled); event.setMessage(message.asString()); event.setFormat(format.asString()); event.getRecipients().clear(); event.getRecipients().addAll(recipients); } } class AsyncChatHandler implements Listener { @EventHandler public void onAsyncChat(AsyncPlayerChatEvent event) { message = new Element(event.getMessage()); format = new Element(event.getFormat()); cancelled = event.isCancelled(); recipients = new HashSet<Player>(event.getRecipients()); pcEvent = null; apcEvent = event; player = dEntity.getPlayerFrom(event.getPlayer()); fire(); event.setCancelled(cancelled); event.setMessage(message.asString()); event.setFormat(format.asString()); event.getRecipients().clear(); event.getRecipients().addAll(recipients); } } }