/* * This file is part of Skript. * * Skript 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. * * Skript 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 Skript. If not, see <http://www.gnu.org/licenses/>. * * * Copyright 2011-2014 Peter Güttinger * */ package ch.njol.skript.expressions; import org.bukkit.event.Event; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerChatEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.eclipse.jdt.annotation.Nullable; import ch.njol.skript.ScriptLoader; import ch.njol.skript.Skript; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Events; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; import ch.njol.skript.events.util.PlayerChatEventHandler; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.log.ErrorQuality; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; /** * @author Peter Güttinger */ @SuppressWarnings("deprecation") @Name("Message") @Description("The (chat) message of a chat event, the join message of a join event, the quit message of a quit event, or the death message on a death event. This expression is mostly useful for being changed.") @Examples({"on chat:", " player has permission \"admin\"", " set message to \"<red>%message%\"", "", "on first join:", " set join message to \"Welcome %player% to our awesome server!\"", "on join:", " player has played before", " set join message to \"Welcome back, %player%!\"", "", "on quit:", " set quit message to \"%player% left this awesome server!\"", "", "on death:", " set the death message to \"%player% died!\""}) @Since("1.4.6 (chat message), 1.4.9 (join & quit messages), 2.0 (death message)") @Events({"chat", "join", "quit", "death"}) public class ExprMessage extends SimpleExpression<String> { @SuppressWarnings("unchecked") private static enum MessageType { CHAT("chat", "[chat( |-)]message", PlayerChatEventHandler.usesAsyncEvent ? AsyncPlayerChatEvent.class : PlayerChatEvent.class) { @Override @Nullable String get(final Event e) { if (PlayerChatEventHandler.usesAsyncEvent) return ((AsyncPlayerChatEvent) e).getMessage(); else return ((PlayerChatEvent) e).getMessage(); } @Override void set(final Event e, final String message) { if (PlayerChatEventHandler.usesAsyncEvent) ((AsyncPlayerChatEvent) e).setMessage(message); else ((PlayerChatEvent) e).setMessage(message); } }, JOIN("join", "(join|log[ ]in)( |-)message", PlayerJoinEvent.class) { @Override @Nullable String get(final Event e) { return ((PlayerJoinEvent) e).getJoinMessage(); } @Override void set(final Event e, final String message) { ((PlayerJoinEvent) e).setJoinMessage(message); } }, QUIT("quit", "(quit|leave|log[ ]out|kick)( |-)message", PlayerQuitEvent.class, PlayerKickEvent.class) { @Override @Nullable String get(final Event e) { if (e instanceof PlayerKickEvent) return ((PlayerKickEvent) e).getLeaveMessage(); else return ((PlayerQuitEvent) e).getQuitMessage(); } @Override void set(final Event e, final String message) { if (e instanceof PlayerKickEvent) ((PlayerKickEvent) e).setLeaveMessage(message); else ((PlayerQuitEvent) e).setQuitMessage(message); } }, DEATH("death", "death( |-)message", EntityDeathEvent.class) { @Override @Nullable String get(final Event e) { if (e instanceof PlayerDeathEvent) return ((PlayerDeathEvent) e).getDeathMessage(); return null; } @Override void set(final Event e, final String message) { if (e instanceof PlayerDeathEvent) ((PlayerDeathEvent) e).setDeathMessage(message); } }; final String name; private final String pattern; final Class<? extends Event>[] events; MessageType(final String name, final String pattern, final Class<? extends Event>... events) { this.name = name; this.pattern = "[the] " + pattern; this.events = events; } static String[] patterns; static { patterns = new String[values().length]; for (int i = 0; i < patterns.length; i++) patterns[i] = values()[i].pattern; } @Nullable abstract String get(Event e); abstract void set(Event e, String message); } static { Skript.registerExpression(ExprMessage.class, String.class, ExpressionType.SIMPLE, MessageType.patterns); } @SuppressWarnings("null") private MessageType type; @SuppressWarnings("null") @Override public boolean init(final Expression<?>[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { type = MessageType.values()[matchedPattern]; if (!ScriptLoader.isCurrentEvent(type.events)) { Skript.error("The " + type.name + " message can only be used in a " + type.name + " event", ErrorQuality.SEMANTIC_ERROR); return false; } return true; } @Override protected String[] get(final Event e) { for (final Class<? extends Event> c : type.events) { if (c.isInstance(e)) return new String[] {type.get(e)}; } return new String[0]; } @SuppressWarnings("unchecked") @Override @Nullable public Class<?>[] acceptChange(final ChangeMode mode) { if (mode == ChangeMode.SET) return CollectionUtils.array(String.class); return null; } @Override public void change(final Event e, final @Nullable Object[] delta, final ChangeMode mode) { assert mode == ChangeMode.SET; assert delta != null; for (final Class<? extends Event> c : type.events) { if (c.isInstance(e)) type.set(e, "" + delta[0]); } } @Override public boolean isSingle() { return true; } @Override public Class<? extends String> getReturnType() { return String.class; } @Override public String toString(final @Nullable Event e, final boolean debug) { return "the " + type.name + " message"; } }