9
0
mirror of https://github.com/Xiao-MoMi/Custom-Nameplates.git synced 2025-12-19 15:09:23 +00:00

Added API to take over actionbars

This commit is contained in:
XiaoMoMi
2024-12-26 18:14:06 +08:00
parent 23bde6ab9d
commit 0270830517
13 changed files with 138 additions and 3 deletions

View File

@@ -67,12 +67,28 @@ public abstract class AbstractCNPlayer implements CNPlayer {
private final Map<CNPlayer, Tracker> trackers = new WeakHashMap<>();
private final ReadWriteLock trackerLock = new ReentrantReadWriteLock();
private final List<String> otherActionBarFeatures = new ArrayList<>();
protected AbstractCNPlayer(CustomNameplates plugin, Channel channel) {
this.plugin = plugin;
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
public List<Placeholder> activePlaceholdersToRefresh() {
Placeholder[] activePlaceholders = activePlaceholders();

View File

@@ -181,6 +181,27 @@ public interface CNPlayer {
*/
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.
*

View File

@@ -115,6 +115,9 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
protected boolean chatChatControlRed;
protected boolean chatChatty;
protected boolean twDialogue;
protected boolean twCinematic;
protected String configVersion;
public ConfigManager(CustomNameplates plugin) {
@@ -196,6 +199,9 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
chatChatControlRed = config.getBoolean("integrations.chat.ChatControlRed", false);
chatChatty = config.getBoolean("integrations.chat.Chatty", false);
twDialogue = config.getBoolean("integrations.typewriter.dialogue", true);
twCinematic = config.getBoolean("integrations.typewriter.cinematic", true);
// Packs
generateOnStart = !config.getBoolean("resource-pack.disable-generation-on-start", false);
namespace = config.getString("resource-pack.namespace", "nameplates");
@@ -365,6 +371,14 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
return instance.metrics;
}
public static boolean twDialogue() {
return instance.twDialogue;
}
public static boolean twCinematic() {
return instance.twCinematic;
}
public static int defaultPlaceholderRefreshInterval() {
return instance.defaultPlaceholderRefreshInterval;
}

View File

@@ -160,6 +160,8 @@ public class ActionBarSender implements Feature {
if (isTemporarilyHidden()) return;
if (latestContent != null) {
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"));
CustomNameplates.getInstance().getPacketSender().sendPacket(owner, packet);
}

View File

@@ -41,7 +41,6 @@ import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.*;
public class ResourcePackManagerImpl implements ResourcePackManager {

View File

@@ -36,6 +36,10 @@ integrations:
Essentials: false # Integration with Essentials chat
ChatControlRed: false # Integration with ChatControlRed
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:

View File

@@ -1,7 +1,7 @@
# Project settings
# Rule: [major update].[feature update].[bug fix]
project_version=3.0.15.2
config_version=34
project_version=3.0.16
config_version=35
project_group=net.momirealms
# Supported languages

View File

@@ -30,6 +30,7 @@ dependencies {
compileOnly(files("libs/AdvancedChat-1.3.7.jar"))
compileOnly(files("libs/CMIAPI-9.7.4.1.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.essentialsx:EssentialsX:2.20.1")
compileOnly("net.essentialsx:EssentialsXChat:2.20.1")

Binary file not shown.

View File

@@ -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");
}
}

View File

@@ -40,6 +40,7 @@ import net.momirealms.customnameplates.bukkit.command.BukkitCommandManager;
import net.momirealms.customnameplates.bukkit.compatibility.NameplatesExpansion;
import net.momirealms.customnameplates.bukkit.compatibility.NameplatesExtraExpansion;
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.requirement.BukkitRequirementManager;
import net.momirealms.customnameplates.bukkit.scheduler.BukkitSchedulerAdapter;
@@ -203,6 +204,10 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
} catch (Exception ignore) {
}
}
if (Bukkit.getPluginManager().isPluginEnabled("Typewriter")) {
TypeWriterListener listener = new TypeWriterListener(this);
Bukkit.getPluginManager().registerEvents(listener, this.getBootstrap());
}
if (VersionHelper.isFolia()) {
this.foliaTrackerTask = getScheduler().asyncRepeating(() -> {

View File

@@ -98,6 +98,7 @@ public class BukkitPlatform implements Platform {
registerPacketConsumer((player, event, packet) -> {
if (!ConfigManager.actionbarModule()) return;
if (!ConfigManager.catchOtherActionBar()) return;
if (!player.shouldCNTakeOverActionBar()) return;
try {
// 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);
@@ -119,6 +120,7 @@ public class BukkitPlatform implements Platform {
registerPacketConsumer((player, event, packet) -> {
if (!ConfigManager.actionbarModule()) return;
if (!ConfigManager.catchOtherActionBar()) return;
if (!player.shouldCNTakeOverActionBar()) return;
try {
boolean actionBar = (boolean) Reflections.field$ClientboundSystemChatPacket$overlay.get(packet);
if (actionBar) {

View File

@@ -17,6 +17,7 @@ softdepend:
- EssentialsChat
- ChatControlRed
- WorldGuard
- Typewriter
permissions:
nameplates.command.equip:
default: true