mirror of
https://github.com/Xiao-MoMi/Custom-Nameplates.git
synced 2025-12-22 00:23:48 +00:00
Added API to take over actionbars
This commit is contained in:
@@ -67,12 +67,28 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
|||||||
|
|
||||||
private final Map<CNPlayer, Tracker> trackers = new WeakHashMap<>();
|
private final Map<CNPlayer, Tracker> trackers = new WeakHashMap<>();
|
||||||
private final ReadWriteLock trackerLock = new ReentrantReadWriteLock();
|
private final ReadWriteLock trackerLock = new ReentrantReadWriteLock();
|
||||||
|
private final List<String> otherActionBarFeatures = new ArrayList<>();
|
||||||
|
|
||||||
protected AbstractCNPlayer(CustomNameplates plugin, Channel channel) {
|
protected AbstractCNPlayer(CustomNameplates plugin, Channel channel) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void acquireActionBar(String id) {
|
||||||
|
this.otherActionBarFeatures.add(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void releaseActionBar(String id) {
|
||||||
|
this.otherActionBarFeatures.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldCNTakeOverActionBar() {
|
||||||
|
return otherActionBarFeatures.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Placeholder> activePlaceholdersToRefresh() {
|
public List<Placeholder> activePlaceholdersToRefresh() {
|
||||||
Placeholder[] activePlaceholders = activePlaceholders();
|
Placeholder[] activePlaceholders = activePlaceholders();
|
||||||
|
|||||||
@@ -181,6 +181,27 @@ public interface CNPlayer {
|
|||||||
*/
|
*/
|
||||||
Placeholder[] activePlaceholders();
|
Placeholder[] activePlaceholders();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquires the actionbar, preventing CustomNameplates from taking control of it.
|
||||||
|
*
|
||||||
|
* @param id The feature ID requesting the actionbar.
|
||||||
|
*/
|
||||||
|
void acquireActionBar(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases the actionbar, allowing CustomNameplates to take control again if no other features are active.
|
||||||
|
*
|
||||||
|
* @param id The feature ID releasing the actionbar.
|
||||||
|
*/
|
||||||
|
void releaseActionBar(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if CustomNameplates should take control of the actionbar.
|
||||||
|
*
|
||||||
|
* @return True if CustomNameplates should take over the actionbar, false otherwise.
|
||||||
|
*/
|
||||||
|
boolean shouldCNTakeOverActionBar();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the list of placeholders that need to be refreshed based on their refresh intervals.
|
* Retrieves the list of placeholders that need to be refreshed based on their refresh intervals.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -115,6 +115,9 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
|||||||
protected boolean chatChatControlRed;
|
protected boolean chatChatControlRed;
|
||||||
protected boolean chatChatty;
|
protected boolean chatChatty;
|
||||||
|
|
||||||
|
protected boolean twDialogue;
|
||||||
|
protected boolean twCinematic;
|
||||||
|
|
||||||
protected String configVersion;
|
protected String configVersion;
|
||||||
|
|
||||||
public ConfigManager(CustomNameplates plugin) {
|
public ConfigManager(CustomNameplates plugin) {
|
||||||
@@ -196,6 +199,9 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
|||||||
chatChatControlRed = config.getBoolean("integrations.chat.ChatControlRed", false);
|
chatChatControlRed = config.getBoolean("integrations.chat.ChatControlRed", false);
|
||||||
chatChatty = config.getBoolean("integrations.chat.Chatty", false);
|
chatChatty = config.getBoolean("integrations.chat.Chatty", false);
|
||||||
|
|
||||||
|
twDialogue = config.getBoolean("integrations.typewriter.dialogue", true);
|
||||||
|
twCinematic = config.getBoolean("integrations.typewriter.cinematic", true);
|
||||||
|
|
||||||
// Packs
|
// Packs
|
||||||
generateOnStart = !config.getBoolean("resource-pack.disable-generation-on-start", false);
|
generateOnStart = !config.getBoolean("resource-pack.disable-generation-on-start", false);
|
||||||
namespace = config.getString("resource-pack.namespace", "nameplates");
|
namespace = config.getString("resource-pack.namespace", "nameplates");
|
||||||
@@ -365,6 +371,14 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
|||||||
return instance.metrics;
|
return instance.metrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean twDialogue() {
|
||||||
|
return instance.twDialogue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean twCinematic() {
|
||||||
|
return instance.twCinematic;
|
||||||
|
}
|
||||||
|
|
||||||
public static int defaultPlaceholderRefreshInterval() {
|
public static int defaultPlaceholderRefreshInterval() {
|
||||||
return instance.defaultPlaceholderRefreshInterval;
|
return instance.defaultPlaceholderRefreshInterval;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ public class ActionBarSender implements Feature {
|
|||||||
if (isTemporarilyHidden()) return;
|
if (isTemporarilyHidden()) return;
|
||||||
if (latestContent != null) {
|
if (latestContent != null) {
|
||||||
updateLastUpdateTime();
|
updateLastUpdateTime();
|
||||||
|
// do not send if other plugins have taken over the actionbar
|
||||||
|
if (!owner.shouldCNTakeOverActionBar()) return;
|
||||||
Object packet = CustomNameplates.getInstance().getPlatform().setActionBarTextPacket(AdventureHelper.miniMessageToMinecraftComponent(latestContent, "nameplates", "actionbar"));
|
Object packet = CustomNameplates.getInstance().getPlatform().setActionBarTextPacket(AdventureHelper.miniMessageToMinecraftComponent(latestContent, "nameplates", "actionbar"));
|
||||||
CustomNameplates.getInstance().getPacketSender().sendPacket(owner, packet);
|
CustomNameplates.getInstance().getPacketSender().sendPacket(owner, packet);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import javax.imageio.ImageIO;
|
|||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ResourcePackManagerImpl implements ResourcePackManager {
|
public class ResourcePackManagerImpl implements ResourcePackManager {
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ integrations:
|
|||||||
Essentials: false # Integration with Essentials chat
|
Essentials: false # Integration with Essentials chat
|
||||||
ChatControlRed: false # Integration with ChatControlRed
|
ChatControlRed: false # Integration with ChatControlRed
|
||||||
Chatty: false # Integration with Chatty
|
Chatty: false # Integration with Chatty
|
||||||
|
# Let typewriter take over actionbar on certain events
|
||||||
|
typewriter:
|
||||||
|
dialogue: true
|
||||||
|
cinematic: true
|
||||||
|
|
||||||
# Resource Pack Generation Settings: Configure resource pack generation behavior.
|
# Resource Pack Generation Settings: Configure resource pack generation behavior.
|
||||||
resource-pack:
|
resource-pack:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Project settings
|
# Project settings
|
||||||
# Rule: [major update].[feature update].[bug fix]
|
# Rule: [major update].[feature update].[bug fix]
|
||||||
project_version=3.0.15.2
|
project_version=3.0.16
|
||||||
config_version=34
|
config_version=35
|
||||||
project_group=net.momirealms
|
project_group=net.momirealms
|
||||||
|
|
||||||
# Supported languages
|
# Supported languages
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ dependencies {
|
|||||||
compileOnly(files("libs/AdvancedChat-1.3.7.jar"))
|
compileOnly(files("libs/AdvancedChat-1.3.7.jar"))
|
||||||
compileOnly(files("libs/CMIAPI-9.7.4.1.jar"))
|
compileOnly(files("libs/CMIAPI-9.7.4.1.jar"))
|
||||||
compileOnly(files("libs/ChatControl-Red-10.28.3.jar"))
|
compileOnly(files("libs/ChatControl-Red-10.28.3.jar"))
|
||||||
|
compileOnly(files("libs/Typewriter.jar"))
|
||||||
compileOnly("net.william278.huskchat:huskchat-bukkit:3.0.4")
|
compileOnly("net.william278.huskchat:huskchat-bukkit:3.0.4")
|
||||||
compileOnly("net.essentialsx:EssentialsX:2.20.1")
|
compileOnly("net.essentialsx:EssentialsX:2.20.1")
|
||||||
compileOnly("net.essentialsx:EssentialsXChat:2.20.1")
|
compileOnly("net.essentialsx:EssentialsXChat:2.20.1")
|
||||||
|
|||||||
BIN
platforms/bukkit/compatibility/libs/Typewriter.jar
Normal file
BIN
platforms/bukkit/compatibility/libs/Typewriter.jar
Normal file
Binary file not shown.
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) <2024> <XiaoMoMi>
|
||||||
|
*
|
||||||
|
* This program 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
|
||||||
|
* 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.momirealms.customnameplates.bukkit.compatibility.quest;
|
||||||
|
|
||||||
|
import com.typewritermc.engine.paper.events.AsyncCinematicEndEvent;
|
||||||
|
import com.typewritermc.engine.paper.events.AsyncCinematicStartEvent;
|
||||||
|
import com.typewritermc.engine.paper.events.AsyncDialogueEndEvent;
|
||||||
|
import com.typewritermc.engine.paper.events.AsyncDialogueStartEvent;
|
||||||
|
import net.momirealms.customnameplates.api.AbstractCNPlayer;
|
||||||
|
import net.momirealms.customnameplates.api.ConfigManager;
|
||||||
|
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class TypeWriterListener implements Listener {
|
||||||
|
|
||||||
|
private final CustomNameplates plugin;
|
||||||
|
|
||||||
|
public TypeWriterListener(CustomNameplates plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onDialogueStart(AsyncDialogueStartEvent event) {
|
||||||
|
if (!ConfigManager.twDialogue()) return;
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
AbstractCNPlayer cnPlayer = (AbstractCNPlayer) plugin.getPlayer(player.getUniqueId());
|
||||||
|
cnPlayer.acquireActionBar("TWDialogue");
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onDialogueEnd(AsyncDialogueEndEvent event) {
|
||||||
|
if (!ConfigManager.twDialogue()) return;
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
AbstractCNPlayer cnPlayer = (AbstractCNPlayer) plugin.getPlayer(player.getUniqueId());
|
||||||
|
cnPlayer.releaseActionBar("TWDialogue");
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onCinematicStart(AsyncCinematicStartEvent event) {
|
||||||
|
if (!ConfigManager.twCinematic()) return;
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
AbstractCNPlayer cnPlayer = (AbstractCNPlayer) plugin.getPlayer(player.getUniqueId());
|
||||||
|
cnPlayer.acquireActionBar("TWCinematic");
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onCinematicEnd(AsyncCinematicEndEvent event) {
|
||||||
|
if (!ConfigManager.twCinematic()) return;
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
AbstractCNPlayer cnPlayer = (AbstractCNPlayer) plugin.getPlayer(player.getUniqueId());
|
||||||
|
cnPlayer.releaseActionBar("TWCinematic");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ import net.momirealms.customnameplates.bukkit.command.BukkitCommandManager;
|
|||||||
import net.momirealms.customnameplates.bukkit.compatibility.NameplatesExpansion;
|
import net.momirealms.customnameplates.bukkit.compatibility.NameplatesExpansion;
|
||||||
import net.momirealms.customnameplates.bukkit.compatibility.NameplatesExtraExpansion;
|
import net.momirealms.customnameplates.bukkit.compatibility.NameplatesExtraExpansion;
|
||||||
import net.momirealms.customnameplates.bukkit.compatibility.cosmetic.MagicCosmeticsHook;
|
import net.momirealms.customnameplates.bukkit.compatibility.cosmetic.MagicCosmeticsHook;
|
||||||
|
import net.momirealms.customnameplates.bukkit.compatibility.quest.TypeWriterListener;
|
||||||
import net.momirealms.customnameplates.bukkit.compatibility.region.WorldGuardRegion;
|
import net.momirealms.customnameplates.bukkit.compatibility.region.WorldGuardRegion;
|
||||||
import net.momirealms.customnameplates.bukkit.requirement.BukkitRequirementManager;
|
import net.momirealms.customnameplates.bukkit.requirement.BukkitRequirementManager;
|
||||||
import net.momirealms.customnameplates.bukkit.scheduler.BukkitSchedulerAdapter;
|
import net.momirealms.customnameplates.bukkit.scheduler.BukkitSchedulerAdapter;
|
||||||
@@ -203,6 +204,10 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
|
|||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (Bukkit.getPluginManager().isPluginEnabled("Typewriter")) {
|
||||||
|
TypeWriterListener listener = new TypeWriterListener(this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(listener, this.getBootstrap());
|
||||||
|
}
|
||||||
|
|
||||||
if (VersionHelper.isFolia()) {
|
if (VersionHelper.isFolia()) {
|
||||||
this.foliaTrackerTask = getScheduler().asyncRepeating(() -> {
|
this.foliaTrackerTask = getScheduler().asyncRepeating(() -> {
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ public class BukkitPlatform implements Platform {
|
|||||||
registerPacketConsumer((player, event, packet) -> {
|
registerPacketConsumer((player, event, packet) -> {
|
||||||
if (!ConfigManager.actionbarModule()) return;
|
if (!ConfigManager.actionbarModule()) return;
|
||||||
if (!ConfigManager.catchOtherActionBar()) return;
|
if (!ConfigManager.catchOtherActionBar()) return;
|
||||||
|
if (!player.shouldCNTakeOverActionBar()) return;
|
||||||
try {
|
try {
|
||||||
// some plugins would send null to clear the actionbar, what a bad solution
|
// some plugins would send null to clear the actionbar, what a bad solution
|
||||||
Object component = Optional.ofNullable(Reflections.field$ClientboundSetActionBarTextPacket$text.get(packet)).orElse(Reflections.instance$Component$empty);
|
Object component = Optional.ofNullable(Reflections.field$ClientboundSetActionBarTextPacket$text.get(packet)).orElse(Reflections.instance$Component$empty);
|
||||||
@@ -119,6 +120,7 @@ public class BukkitPlatform implements Platform {
|
|||||||
registerPacketConsumer((player, event, packet) -> {
|
registerPacketConsumer((player, event, packet) -> {
|
||||||
if (!ConfigManager.actionbarModule()) return;
|
if (!ConfigManager.actionbarModule()) return;
|
||||||
if (!ConfigManager.catchOtherActionBar()) return;
|
if (!ConfigManager.catchOtherActionBar()) return;
|
||||||
|
if (!player.shouldCNTakeOverActionBar()) return;
|
||||||
try {
|
try {
|
||||||
boolean actionBar = (boolean) Reflections.field$ClientboundSystemChatPacket$overlay.get(packet);
|
boolean actionBar = (boolean) Reflections.field$ClientboundSystemChatPacket$overlay.get(packet);
|
||||||
if (actionBar) {
|
if (actionBar) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ softdepend:
|
|||||||
- EssentialsChat
|
- EssentialsChat
|
||||||
- ChatControlRed
|
- ChatControlRed
|
||||||
- WorldGuard
|
- WorldGuard
|
||||||
|
- Typewriter
|
||||||
permissions:
|
permissions:
|
||||||
nameplates.command.equip:
|
nameplates.command.equip:
|
||||||
default: true
|
default: true
|
||||||
|
|||||||
Reference in New Issue
Block a user