chat settings are synced with velocity again (join/leave, mentions)
This commit is contained in:
1 parent
ca0e364d85
commit
4a87bb3fad
6 files changed
+154
-4
No files matched your search
+49
@@ -0,0 +1,49 @@
|
|||||||
|
package eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.networkChat;
|
||||||
|
|
||||||
|
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.CategorizedSetting;
|
||||||
|
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.SettingCategory;
|
||||||
|
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings;
|
||||||
|
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.datatypes.MultiBoolSetting;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
|
||||||
|
public class ChatMentionSetting extends MultiBoolSetting<ChatMentionSetting.ChatMentionConfig> implements CategorizedSetting {
|
||||||
|
@Override
|
||||||
|
public SettingCategory category() {
|
||||||
|
return SettingCategory.Visuals;
|
||||||
|
}
|
||||||
|
|
||||||
|
public record ChatMentionConfig(
|
||||||
|
@DisplayName("Spielernamen hervorheben") boolean applyMentions,
|
||||||
|
@DisplayName("Benachrichtigungston") boolean notifyOnMention
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatMentionSetting() {
|
||||||
|
super(Settings.Key.ChatMentions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String title() {
|
||||||
|
return "Erwähnungen im Chat";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String description() {
|
||||||
|
return "Wirst du im Chat erwähnt, wird dein Name hervorgehoben und du hörst einen Signalton";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material icon() {
|
||||||
|
return Material.FEATHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ChatMentionConfig defaultValue() {
|
||||||
|
return new ChatMentionConfig(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> dataType() {
|
||||||
|
return ChatMentionConfig.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
+46
-4
@@ -1,7 +1,9 @@
|
|||||||
package eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.networkChat;
|
package eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.networkChat;
|
||||||
|
|
||||||
|
import com.google.common.io.ByteArrayDataInput;
|
||||||
import com.google.common.io.ByteArrayDataOutput;
|
import com.google.common.io.ByteArrayDataOutput;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
|
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings;
|
||||||
import eu.mhsl.craftattack.spawn.core.Main;
|
import eu.mhsl.craftattack.spawn.core.Main;
|
||||||
import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
|
import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
@@ -19,8 +21,17 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Chat läuft über Velocity (Plugin chat-bridge): Der öffentliche Chat, /msg, /r, /adminchat, /mute und
|
* Chat läuft über Velocity (Plugin chat-bridge): Der öffentliche Chat, /msg, /r, /adminchat, /mute und
|
||||||
* Join/Leave-Meldungen gelten im ganzen Netzwerk. Hier wird der Chat nur verworfen und Velocity
|
* Join/Leave-Meldungen gelten im ganzen Netzwerk. Hier wird der Chat nur verworfen, Velocity bekommt
|
||||||
* bekommt die Rang-Prefixe für den Namen.
|
* die Rang-Prefixe für den Namen, und die Chat-Einstellungen werden mit Velocity abgeglichen.
|
||||||
|
* <p>
|
||||||
|
* Kanal {@value #channel}, Nachrichten (UTF-Typ, dann Daten):
|
||||||
|
* <ul>
|
||||||
|
* <li>→ Proxy {@code prefix}: Adventure-JSON oder leer</li>
|
||||||
|
* <li>→ Proxy {@code settings-hello} beim Join, {@code settings-set} nach einer Änderung: Join/Leave,
|
||||||
|
* Erwähnungen hervorheben, Erwähnungston (je boolean). Velocity speichert sie; kennt es schon
|
||||||
|
* Werte, antwortet es auf das Hello mit {@code settings}.</li>
|
||||||
|
* <li>← Proxy {@code settings}: gespeicherte Werte, werden hier übernommen</li>
|
||||||
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public class NetworkChat extends Appliance {
|
public class NetworkChat extends Appliance {
|
||||||
public static final String channel = "craftattack:chat";
|
public static final String channel = "craftattack:chat";
|
||||||
@@ -30,6 +41,12 @@ public class NetworkChat extends Appliance {
|
|||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
Bukkit.getMessenger().registerOutgoingPluginChannel(Main.instance(), channel);
|
Bukkit.getMessenger().registerOutgoingPluginChannel(Main.instance(), channel);
|
||||||
|
Bukkit.getMessenger().registerIncomingPluginChannel(Main.instance(), channel, (channel, player, message) -> this.receive(player, message));
|
||||||
|
|
||||||
|
Settings.instance().declareSetting(ShowJoinAndLeaveMessagesSetting.class);
|
||||||
|
Settings.instance().declareSetting(ChatMentionSetting.class);
|
||||||
|
Settings.instance().addChangeListener(ShowJoinAndLeaveMessagesSetting.class, player -> this.sendSettings(player, "settings-set"));
|
||||||
|
Settings.instance().addChangeListener(ChatMentionSetting.class, player -> this.sendSettings(player, "settings-set"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrefix(Player player, @Nullable Component prefix) {
|
public void setPrefix(Player player, @Nullable Component prefix) {
|
||||||
@@ -39,12 +56,37 @@ public class NetworkChat extends Appliance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendPrefix(Player player) {
|
void sendPrefix(Player player) {
|
||||||
// Velocity meldet den Kanal erst kurz nach dem Join an, dann folgt PlayerRegisterChannelEvent
|
|
||||||
if(!player.getListeningPluginChannels().contains(channel)) return;
|
|
||||||
Component prefix = this.prefixes.get(player.getUniqueId());
|
Component prefix = this.prefixes.get(player.getUniqueId());
|
||||||
ByteArrayDataOutput output = ByteStreams.newDataOutput();
|
ByteArrayDataOutput output = ByteStreams.newDataOutput();
|
||||||
output.writeUTF("prefix");
|
output.writeUTF("prefix");
|
||||||
output.writeUTF(prefix == null ? "" : GsonComponentSerializer.gson().serialize(prefix));
|
output.writeUTF(prefix == null ? "" : GsonComponentSerializer.gson().serialize(prefix));
|
||||||
|
this.send(player, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendSettings(Player player, String type) {
|
||||||
|
ChatMentionSetting.ChatMentionConfig mentions = Settings.instance()
|
||||||
|
.getSetting(player, Settings.Key.ChatMentions, ChatMentionSetting.ChatMentionConfig.class);
|
||||||
|
ByteArrayDataOutput output = ByteStreams.newDataOutput();
|
||||||
|
output.writeUTF(type);
|
||||||
|
output.writeBoolean(Settings.instance().getSetting(player, Settings.Key.ShowJoinAndLeaveMessages, Boolean.class));
|
||||||
|
output.writeBoolean(mentions.applyMentions());
|
||||||
|
output.writeBoolean(mentions.notifyOnMention());
|
||||||
|
this.send(player, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void receive(Player player, byte[] message) {
|
||||||
|
ByteArrayDataInput input = ByteStreams.newDataInput(message);
|
||||||
|
if(!input.readUTF().equals("settings")) return;
|
||||||
|
boolean joinAndLeave = input.readBoolean();
|
||||||
|
boolean applyMentions = input.readBoolean();
|
||||||
|
boolean notifyOnMention = input.readBoolean();
|
||||||
|
Settings.instance().setSetting(player, Settings.Key.ShowJoinAndLeaveMessages, joinAndLeave);
|
||||||
|
Settings.instance().setSetting(player, Settings.Key.ChatMentions, new ChatMentionSetting.ChatMentionConfig(applyMentions, notifyOnMention));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void send(Player player, ByteArrayDataOutput output) {
|
||||||
|
// Velocity meldet den Kanal erst kurz nach dem Join an, dann folgt PlayerRegisterChannelEvent
|
||||||
|
if(!player.getListeningPluginChannels().contains(channel)) return;
|
||||||
player.sendPluginMessage(Main.instance(), channel, output.toByteArray());
|
player.sendPluginMessage(Main.instance(), channel, output.toByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
@@ -43,6 +43,7 @@ class NetworkChatListener extends ApplianceListener<NetworkChat> {
|
|||||||
public void onRegisterChannel(PlayerRegisterChannelEvent event) {
|
public void onRegisterChannel(PlayerRegisterChannelEvent event) {
|
||||||
if(!event.getChannel().equals(NetworkChat.channel)) return;
|
if(!event.getChannel().equals(NetworkChat.channel)) return;
|
||||||
this.getAppliance().sendPrefix(event.getPlayer());
|
this.getAppliance().sendPrefix(event.getPlayer());
|
||||||
|
this.getAppliance().sendSettings(event.getPlayer(), "settings-hello");
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.networkChat;
|
||||||
|
|
||||||
|
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.CategorizedSetting;
|
||||||
|
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.SettingCategory;
|
||||||
|
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings;
|
||||||
|
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.datatypes.BoolSetting;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
|
||||||
|
public class ShowJoinAndLeaveMessagesSetting extends BoolSetting implements CategorizedSetting {
|
||||||
|
public ShowJoinAndLeaveMessagesSetting() {
|
||||||
|
super(Settings.Key.ShowJoinAndLeaveMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String title() {
|
||||||
|
return "Join & Leave Nachrichten anzeigen";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String description() {
|
||||||
|
return "Zeige allgemeine Beitritts und Verlassensmeldungen im Chat";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Material icon() {
|
||||||
|
return Material.PLAYER_HEAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean defaultValue() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingCategory category() {
|
||||||
|
return SettingCategory.Visuals;
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -26,11 +26,13 @@ public class Settings extends Appliance {
|
|||||||
|
|
||||||
public enum Key {
|
public enum Key {
|
||||||
TechnicalTab,
|
TechnicalTab,
|
||||||
|
ShowJoinAndLeaveMessages,
|
||||||
EnablePortableCrafting,
|
EnablePortableCrafting,
|
||||||
EnableSettingsShortcut,
|
EnableSettingsShortcut,
|
||||||
AutoShulker,
|
AutoShulker,
|
||||||
SignEdit,
|
SignEdit,
|
||||||
HotbarReplacer,
|
HotbarReplacer,
|
||||||
|
ChatMentions,
|
||||||
DoubleDoors,
|
DoubleDoors,
|
||||||
KnockDoors,
|
KnockDoors,
|
||||||
BorderWarning,
|
BorderWarning,
|
||||||
@@ -110,6 +112,18 @@ public class Settings extends Appliance {
|
|||||||
return clazz.cast(setting.state());
|
return clazz.cast(setting.state());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Setzt einen Wert von außen (z. B. vom Proxy), ohne die Change-Listener auszulösen. */
|
||||||
|
public <T> void setSetting(Player player, Key key, T value) {
|
||||||
|
Setting<?> setting = this.getSettings(player).stream()
|
||||||
|
.filter(s -> Objects.equals(s.getKey(), key))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
|
if(!setting.dataType().isInstance(value))
|
||||||
|
throw new IllegalStateException("Tried to set Setting with Datatype " + value.getClass().getSimpleName() + " but expected " + setting.dataType().getSimpleName());
|
||||||
|
setting.restore(player, value);
|
||||||
|
}
|
||||||
|
|
||||||
public void openSettings(Player player) {
|
public void openSettings(Player player) {
|
||||||
List<Setting<?>> settings = this.getSettings(player);
|
List<Setting<?>> settings = this.getSettings(player);
|
||||||
Inventory inventory = Bukkit.createInventory(null, this.calculateInvSize(settings), Component.text("Einstellungen"));
|
Inventory inventory = Bukkit.createInventory(null, this.calculateInvSize(settings), Component.text("Einstellungen"));
|
||||||
|
|||||||
+6
@@ -62,6 +62,12 @@ public abstract class Setting<TDataType> {
|
|||||||
Settings.instance().invokeChangeListener(p, this.getClass());
|
Settings.instance().invokeChangeListener(p, this.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void restore(Player p, Object value) {
|
||||||
|
this.state = (TDataType) value;
|
||||||
|
this.toStorage(p.getPersistentDataContainer(), this.state);
|
||||||
|
}
|
||||||
|
|
||||||
public ItemStack buildItem() {
|
public ItemStack buildItem() {
|
||||||
ItemStack stack = new ItemStack(this.icon(), 1);
|
ItemStack stack = new ItemStack(this.icon(), 1);
|
||||||
stack.setItemMeta(this.buildMeta(stack.getItemMeta()));
|
stack.setItemMeta(this.buildMeta(stack.getItemMeta()));
|
||||||
|
|||||||
Reference in new issue
Block a user