forked from SteamWar/SteamWar
285 lines
9.4 KiB
Java
285 lines
9.4 KiB
Java
/*
|
|
* This file is a part of the SteamWar software.
|
|
*
|
|
* Copyright (C) 2025 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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package de.steamwar.messages;
|
|
|
|
import com.velocitypowered.api.command.CommandSource;
|
|
import com.velocitypowered.api.event.ResultedEvent;
|
|
import com.velocitypowered.api.event.connection.LoginEvent;
|
|
import com.velocitypowered.api.proxy.Player;
|
|
import com.velocitypowered.api.proxy.ServerConnection;
|
|
import de.steamwar.persistent.Subserver;
|
|
import de.steamwar.sql.SteamwarUser;
|
|
import de.steamwar.sql.UserPerm;
|
|
import de.steamwar.velocitycore.VelocityCore;
|
|
import de.steamwar.velocitycore.commands.StreamingCommand;
|
|
import net.kyori.adventure.text.Component;
|
|
import net.kyori.adventure.text.event.ClickEvent;
|
|
import net.kyori.adventure.text.event.HoverEvent;
|
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
|
|
|
import java.text.DateFormat;
|
|
import java.text.MessageFormat;
|
|
import java.util.Date;
|
|
import java.util.Locale;
|
|
import java.util.ResourceBundle;
|
|
import java.util.UUID;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Function;
|
|
import java.util.function.Supplier;
|
|
import java.util.stream.Stream;
|
|
|
|
public interface Chatter {
|
|
LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.builder().extractUrls().build();
|
|
|
|
static Stream<Player> allPlayers() {
|
|
return VelocityCore.getProxy().getAllPlayers().stream();
|
|
}
|
|
|
|
static Stream<Chatter> allStream() {
|
|
return Stream.concat(Stream.of(Chatter.console()), allPlayers().map(Chatter::of));
|
|
}
|
|
|
|
static ChatterGroup broadcast() {
|
|
return new ChatterGroup(allStream());
|
|
}
|
|
|
|
static ChatterGroup globalChat() {
|
|
return new ChatterGroup(Stream.concat(Stream.of(Chatter.console()), allPlayers().filter(player -> {
|
|
Subserver subserver = Subserver.getSubserver(player);
|
|
return !(Subserver.isArena(subserver) && subserver.getServer() == player.getCurrentServer().map(ServerConnection::getServerInfo).orElse(null));
|
|
}).map(Chatter::of)));
|
|
}
|
|
|
|
static ChatterGroup serverteam() {
|
|
return new ChatterGroup(allStream()
|
|
.filter(player -> player.user().hasPerm(UserPerm.TEAM))
|
|
.filter(StreamingCommand::isNotStreaming));
|
|
}
|
|
|
|
SteamwarUser user();
|
|
|
|
Locale getLocale();
|
|
boolean chatShown();
|
|
void sendMessage(Component msg);
|
|
Player getPlayer();
|
|
|
|
default <T> T withPlayerOrOffline(Function<Player, T> withPlayer, Supplier<T> withOffline) {
|
|
Player player = getPlayer();
|
|
if(player == null)
|
|
return withOffline.get();
|
|
else
|
|
return withPlayer.apply(player);
|
|
}
|
|
default void withPlayerOrOffline(Consumer<Player> withPlayer, Runnable withOffline) {
|
|
Player player = getPlayer();
|
|
if(player == null) {
|
|
withOffline.run();
|
|
} else {
|
|
withPlayer.accept(player);
|
|
}
|
|
}
|
|
default void withPlayer(Consumer<Player> function) {
|
|
withPlayerOrOffline(function, () -> {});
|
|
}
|
|
|
|
default void system(String format, Object... params) {
|
|
system(new Message(format, params));
|
|
}
|
|
|
|
default void system(Message message) {
|
|
send(true, null, null, message);
|
|
}
|
|
|
|
default void system(String format, Message onHover, ClickEvent onClick, Object... params) {
|
|
send(true, 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, onHover, onClick, new Message(format, params));
|
|
}
|
|
|
|
default void send(boolean prefixed, Message onHover, ClickEvent onClick, Message message) {
|
|
Component msg = parse(prefixed, message);
|
|
if(onHover != null)
|
|
msg = msg.hoverEvent(HoverEvent.showText(parse(false, onHover)));
|
|
if(onClick != null)
|
|
msg = msg.clickEvent(onClick);
|
|
sendMessage(msg);
|
|
}
|
|
|
|
default String parseToPlain(String format, Object... params) {
|
|
return parseToPlain(new Message(format, params));
|
|
}
|
|
|
|
default String parseToPlain(Message message) {
|
|
return PlainTextComponentSerializer.plainText().serialize(parse(message));
|
|
}
|
|
|
|
default String parseToLegacy(String format, Object... params) {
|
|
return parseToLegacy(new Message(format, params));
|
|
}
|
|
|
|
default String parseToLegacy(Message message) {
|
|
return SERIALIZER.serialize(parse(message));
|
|
}
|
|
|
|
default Component parse(String format, Object... params) {
|
|
return parse(false, new Message(format, params));
|
|
}
|
|
|
|
default Component parse(Message message) {
|
|
return parse(false, message);
|
|
}
|
|
|
|
default Component parse(boolean prefixed, String format, Object... params) {
|
|
return parse(prefixed, new Message(format, params));
|
|
}
|
|
|
|
default Component 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.format());
|
|
|
|
MessageFormat format = new MessageFormat(pattern, locale);
|
|
Object[] params = message.params();
|
|
for (int i = 0; i < params.length; i++) {
|
|
if(params[i] instanceof Message msg) {
|
|
params[i] = parseToLegacy(msg);
|
|
} else if(params[i] instanceof Date date) {
|
|
params[i] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale).format(date);
|
|
} else if(params[i] instanceof SteamwarUser user) {
|
|
params[i] = user.getUserName();
|
|
} else if(params[i] instanceof Player player) {
|
|
params[i] = player.getUsername();
|
|
} else if(params[i] instanceof Chatter chatter) {
|
|
params[i] = chatter.user().getUserName();
|
|
} else if(params[i] instanceof Function func) {
|
|
params[i] = func.apply(this);
|
|
}
|
|
}
|
|
return SERIALIZER.deserialize(format.format(params));
|
|
}
|
|
|
|
static PlayerChatter of(Player player) {
|
|
return new PlayerChatter(player, player::sendMessage);
|
|
}
|
|
|
|
static PlayerChatter disconnect(Player player) {
|
|
return new PlayerChatter(player, player::disconnect);
|
|
}
|
|
|
|
static Chatter of(CommandSource sender) {
|
|
if(sender instanceof Player player)
|
|
return of(player);
|
|
|
|
//Console
|
|
return new PlayerlessChatter() {
|
|
@Override
|
|
public SteamwarUser user() {
|
|
return SteamwarUser.get(-1);
|
|
}
|
|
|
|
@Override
|
|
public boolean chatShown() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void sendMessage(Component msg) {
|
|
sender.sendMessage(msg);
|
|
}
|
|
};
|
|
}
|
|
|
|
static Chatter of(SteamwarUser user) {
|
|
return of(user.getUUID(), false);
|
|
}
|
|
|
|
static Chatter of(UUID uuid) {
|
|
return of(uuid, false);
|
|
}
|
|
|
|
static Chatter of(UUID uuid, boolean playerlessChatShown) {
|
|
Player player = VelocityCore.getProxy().getPlayer(uuid).orElse(null);
|
|
if(player != null)
|
|
return Chatter.of(player);
|
|
|
|
return new PlayerlessChatter() {
|
|
@Override
|
|
public SteamwarUser user() {
|
|
return SteamwarUser.get(uuid);
|
|
}
|
|
|
|
@Override
|
|
public boolean chatShown() {
|
|
return playerlessChatShown;
|
|
}
|
|
|
|
@Override
|
|
public void sendMessage(Component msg) {
|
|
// Nowhere to send
|
|
}
|
|
};
|
|
}
|
|
|
|
static Chatter console() {
|
|
return of(VelocityCore.getProxy().getConsoleCommandSource());
|
|
}
|
|
|
|
static Chatter of(LoginEvent event) {
|
|
return new PlayerlessChatter() {
|
|
@Override
|
|
public SteamwarUser user() {
|
|
return SteamwarUser.get(event.getPlayer().getUniqueId());
|
|
}
|
|
|
|
@Override
|
|
public boolean chatShown() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void sendMessage(Component msg) {
|
|
event.setResult(ResultedEvent.ComponentResult.denied(msg));
|
|
}
|
|
};
|
|
}
|
|
|
|
abstract class PlayerlessChatter implements Chatter {
|
|
@Override
|
|
public Locale getLocale() {
|
|
return user().getLocale();
|
|
}
|
|
|
|
@Override
|
|
public Player getPlayer() {
|
|
return VelocityCore.getProxy().getPlayer(user().getUUID()).orElse(null);
|
|
}
|
|
}
|
|
}
|