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:
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
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.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(() -> {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -17,6 +17,7 @@ softdepend:
|
||||
- EssentialsChat
|
||||
- ChatControlRed
|
||||
- WorldGuard
|
||||
- Typewriter
|
||||
permissions:
|
||||
nameplates.command.equip:
|
||||
default: true
|
||||
|
||||
Reference in New Issue
Block a user