/* This file is a part of the SteamWar software. Copyright (C) 2022 SteamWar.de-Serverteam This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package de.steamwar.messages; import de.steamwar.bungeecore.*; import de.steamwar.bungeecore.bot.listeners.DiscordChatListener; import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.UserPerm; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.hover.content.Text; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.LoginEvent; import net.md_5.bungee.command.ConsoleCommandSender; import java.text.DateFormat; import java.text.MessageFormat; import java.util.Date; import java.util.Locale; import java.util.ResourceBundle; import java.util.function.BiConsumer; import java.util.logging.Level; import java.util.stream.Stream; public interface ChatSender { static Stream all() { return ProxyServer.getInstance().getPlayers().stream(); } static Stream allReceivers() { return all().map(ChatSender::of); } static Stream globalReceivers() { return all().filter(player -> { Subserver subserver = Subserver.getSubserver(player); return subserver == null || !(subserver.getType() == Servertype.ARENA && subserver.getServer() == player.getServer().getInfo()); }).map(ChatSender::of); } static Stream serverteamReceivers() { return allReceivers().filter(player -> player.user().hasPerm(UserPerm.TEAM)); } SteamwarUser user(); Locale getLocale(); boolean chatShown(); void sendMessage(ChatMessageType type, BaseComponent... msg); default void chat(Message message) { send(false, ChatMessageType.CHAT, null, null, message); } default void system(String format, Object... params) { system(new Message(format, params)); } default void system(Message message) { send(true, ChatMessageType.SYSTEM, null, null, message); } default void system(String format, Message onHover, ClickEvent onClick, Object... params) { send(true, ChatMessageType.SYSTEM, onHover, onClick, new Message(format, params)); } default void prefixless(String format, Object... params) { prefixless(format, null, null, params); } default void prefixless(String format, Message onHover, ClickEvent onClick, Object... params) { send(false, ChatMessageType.SYSTEM, onHover, onClick, new Message(format, params)); } default void send(boolean prefixed, ChatMessageType type, Message onHover, ClickEvent onClick, Message message) { TextComponent msg = parseToComponent(prefixed, message); if(onHover != null) msg.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(parse(false, onHover)))); if(onClick != null) msg.setClickEvent(onClick); sendMessage(type, msg); } default TextComponent parseToComponent(boolean prefixed, Message message) { return new TextComponent(parse(prefixed, message)); } default String parseToPlain(String format, Object... params) { return parseToPlain(new Message(format, params)); } default String parseToPlain(Message message) { return parseToComponent(false, message).toPlainText(); } default String parseToLegacy(String format, Object... params) { return parseToLegacy(new Message(format, params)); } default String parseToLegacy(Message message) { return parseToComponent(false, message).toLegacyText(); } default BaseComponent[] parse(boolean prefixed, String format, Object... params) { return parse(prefixed, new Message(format, params)); } default BaseComponent[] parse(boolean prefixed, Message message) { Locale locale = getLocale(); ResourceBundle resourceBundle = SteamwarResourceBundle.getResourceBundle(locale); String pattern = ""; if(prefixed) pattern = resourceBundle.getObject("PREFIX") + " "; pattern += (String)resourceBundle.getObject(message.getFormat()); MessageFormat format = new MessageFormat(pattern, locale); Object[] params = message.getParams(); for (int i = 0; i < params.length; i++) { if(params[i] instanceof Message) { params[i] = parseToLegacy((Message) params[i]); } else if(params[i] instanceof Date) { params[i] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale).format((Date) params[i]); } else if(params[i] instanceof SteamwarUser) { params[i] = ((SteamwarUser) params[i]).getUserName(); } else if(params[i] instanceof ProxiedPlayer) { params[i] = ((ProxiedPlayer) params[i]).getName(); } else if(params[i] instanceof ChatSender) { params[i] = ((ChatSender) params[i]).user().getUserName(); } } return TextComponent.fromLegacyText(format.format(params)); } static ChatSender ofProxiedPlayer(ProxiedPlayer player, BiConsumer sendMessage) { return new ChatSender() { @Override public SteamwarUser user() { return SteamwarUser.get(player.getUniqueId()); } @Override public Locale getLocale() { return user().getLocale(); } @Override public boolean chatShown() { return player.getChatMode() == ProxiedPlayer.ChatMode.SHOWN; } @Override public void sendMessage(ChatMessageType type, BaseComponent... msg) { sendMessage.accept(type, msg); } }; } static ChatSender of(ProxiedPlayer player) { return ofProxiedPlayer(player, player::sendMessage); } static ChatSender disconnect(ProxiedPlayer player) { return ofProxiedPlayer(player, (type, msg) -> player.disconnect(msg)); } static ChatSender of(CommandSender sender) { if(sender instanceof ProxiedPlayer) return of((ProxiedPlayer) sender); //Console return new ChatSender() { @Override public SteamwarUser user() { return SteamwarUser.get(-1); } @Override public Locale getLocale() { return Locale.getDefault(); } @Override public boolean chatShown() { return true; } @Override public void sendMessage(ChatMessageType type, BaseComponent... msg) { sender.sendMessage(msg); } }; } static ChatSender console() { return of(ConsoleCommandSender.getInstance()); } static ChatSender of(LoginEvent event) { return new ChatSender() { @Override public SteamwarUser user() { return SteamwarUser.get(event.getConnection().getUniqueId()); } @Override public Locale getLocale() { return Locale.getDefault(); } @Override public boolean chatShown() { return false; } @Override public void sendMessage(ChatMessageType type, BaseComponent... msg) { event.setCancelReason(msg); } }; } static ChatSender discordChannel(DiscordChatListener channel) { return new ChatSender() { @Override public SteamwarUser user() { return SteamwarUser.get(-1); } @Override public Locale getLocale() { return Locale.getDefault(); } @Override public boolean chatShown() { return true; } @Override public void sendMessage(ChatMessageType type, BaseComponent... msg) { try { channel.send(" " + new TextComponent(msg).toPlainText()); } catch (Exception e) { BungeeCore.get().getLogger().log(Level.SEVERE, "Could not send chat message to discord", e); } } }; } static ChatSender of(net.dv8tion.jda.api.entities.Message message, SteamwarUser user) { return new ChatSender() { @Override public SteamwarUser user() { return user; } @Override public Locale getLocale() { return Locale.getDefault(); } @Override public boolean chatShown() { return true; } @Override public void sendMessage(ChatMessageType type, BaseComponent... msg) { try { message.delete().queue(); } catch (Exception e) { BungeeCore.get().getLogger().log(Level.SEVERE, "Could not send chat reply to discord user", e); } } }; } }