/*
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.bungeecore.sql.SteamwarUser;
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().getUserGroup().isTeamGroup());
}
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 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, 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() {
Locale locale = player.getLocale();
if(locale == null)
locale = Locale.getDefault();
return locale;
}
@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);
}
}
};
}
}