18 Commits
Author SHA1 Message Date
XiaoMoMi 26b593950d bump version 3.0.15.2 2024-12-10 16:24:46 +08:00
XiaoMoMi 63896acda6 use snapshot adventure 2024-12-10 16:24:06 +08:00
XiaoMoMi 6eb5dee611 Update custom-placeholders.yml 2024-12-10 16:23:48 +08:00
XiaoMoMi 69869d1cb1 update pack format 2024-12-10 16:02:48 +08:00
XiaoMoMi 2e702d8945 Fix thread safety issue 2024-12-09 03:29:06 +08:00
XiaoMoMi 56c77bd294 3.0.15.1 2024-12-04 15:35:12 +08:00
XiaoMoMi 4d195820a0 improve send delay 2024-11-29 17:40:54 +08:00
XiaoMoMi 2874ab7c4e send bossbar immediately 2024-11-29 17:34:40 +08:00
XiaoMoMi cd1a0bffb6 chatty 2024-11-28 18:49:59 +08:00
XiaoMoMi 20d3919c6b Fix regex 2024-11-22 00:57:24 +08:00
XiaoMoMi fccaa059ff Added generate option for bitmaps 2024-11-21 02:14:49 +08:00
XiaoMoMi ed2fb60748 Update settings.gradle.kts 2024-11-19 18:38:26 +08:00
XiaoMoMi 378dc2e3bc Update gradle.properties 2024-11-19 18:37:38 +08:00
XiaoMoMi 6144423110 Update gradle.properties 2024-11-19 18:33:13 +08:00
XiaoMoMi d21fa8a3f7 work 2024-11-19 18:33:04 +08:00
XiaoMoMi 7e68a6cda7 move packages 2024-11-19 16:52:02 +08:00
XiaoMoMi 3df6d66efb better support 2024-11-19 16:46:01 +08:00
XiaoMoMi 001ecd28ed remove debug 2024-11-18 15:14:05 +08:00
132 changed files with 841 additions and 148 deletions

No files matched your search

+3
View File
@@ -5,6 +5,9 @@ target/
!**/src/main/**/build/
!**/src/test/**/build/
### Unfinished ###
platforms/sponge/
### IntelliJ IDEA ###
.idea
*.iws
+1 -1
View File
@@ -6,7 +6,7 @@ plugins {
repositories {
maven("https://jitpack.io/")
maven("https://papermc.io/repo/repository/maven-public/")
maven("https://oss.sonatype.org/content/repositories/snapshots")
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}
dependencies {
@@ -18,7 +18,6 @@
package net.momirealms.customnameplates.api;
import io.netty.channel.Channel;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.momirealms.customnameplates.api.feature.Feature;
@@ -37,6 +36,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public abstract class AbstractCNPlayer implements CNPlayer {
@@ -45,27 +46,27 @@ public abstract class AbstractCNPlayer implements CNPlayer {
protected Object player;
private boolean isLoaded = false;
private boolean tempPreviewing = false;
private boolean toggleablePreviewing = false;
private volatile boolean isLoaded = false;
private volatile boolean tempPreviewing = false;
private volatile boolean toggleablePreviewing = false;
private String equippedNameplate;
private String equippedBubble;
private final TeamView teamView = new TeamView();
// these maps might be visited by other threads through PlaceholderAPI
private final Map<Integer, TimeStampData<String>> cachedValues = new ConcurrentHashMap<>(128);
private final Map<Integer, WeakHashMap<CNPlayer, TimeStampData<String>>> cachedRelationalValues = new ConcurrentHashMap<>(128);
private final Map<Integer, TimeStampData<Boolean>> cachedRequirements = new Int2ObjectOpenHashMap<>(32);
private final Map<Integer, WeakHashMap<CNPlayer, TimeStampData<Boolean>>> cachedRelationalRequirements = new Int2ObjectOpenHashMap<>(32);
private final Map<Integer, TimeStampData<Boolean>> cachedRequirements = new ConcurrentHashMap<>(32);
private final Map<Integer, WeakHashMap<CNPlayer, TimeStampData<Boolean>>> cachedRelationalRequirements = new ConcurrentHashMap<>(32);
private final Set<Feature> activeFeatures = new CopyOnWriteArraySet<>();
private final Map<Placeholder, Set<Feature>> placeholder2Features = new ConcurrentHashMap<>();
private final Map<Feature, Set<Placeholder>> feature2Placeholders = new ConcurrentHashMap<>();
private final Map<CNPlayer, Tracker> trackers = Collections.synchronizedMap(new WeakHashMap<>());
private final Map<CNPlayer, Tracker> trackers = new WeakHashMap<>();
private final ReadWriteLock trackerLock = new ReentrantReadWriteLock();
protected AbstractCNPlayer(CustomNameplates plugin, Channel channel) {
this.plugin = plugin;
@@ -437,58 +438,90 @@ public abstract class AbstractCNPlayer implements CNPlayer {
@Override
public Tracker addPlayerToTracker(CNPlayer another) {
Tracker tracker = trackers.get(another);
if (tracker != null) {
trackerLock.writeLock().lock();
try {
Tracker tracker = trackers.get(another);
if (tracker != null) {
return tracker;
}
tracker = new Tracker(another);
trackers.put(another, tracker);
return tracker;
} finally {
trackerLock.writeLock().unlock();
}
tracker = new Tracker(another);
trackers.put(another, tracker);
// for (Placeholder placeholder : activePlaceholders()) {
// if (placeholder instanceof RelationalPlaceholder relationalPlaceholder) {
// String value = relationalPlaceholder.request(this, another);
// setRelationalValue(relationalPlaceholder, another, value);
// }
// }
return tracker;
}
@Override
public void removePlayerFromTracker(CNPlayer another) {
trackers.remove(another);
trackerLock.writeLock().lock();
try {
trackers.remove(another);
} finally {
trackerLock.writeLock().unlock();
}
}
@Override
public Collection<CNPlayer> nearbyPlayers() {
return new ObjectArrayList<>(trackers.keySet());
trackerLock.readLock().lock();
try {
// Create a snapshot of keys to avoid concurrent modification
return new ObjectArrayList<>(trackers.keySet());
} finally {
trackerLock.readLock().unlock();
}
}
@Override
public void trackPassengers(CNPlayer another, int... passengers) {
Tracker tracker = trackers.get(another);
if (tracker != null) {
for (int passenger : passengers) {
tracker.addPassengerID(passenger);
}
}
trackerLock.writeLock().lock();
try {
Tracker tracker = trackers.get(another);
if (tracker != null) {
for (int passenger : passengers) {
tracker.addPassengerID(passenger);
}
}
} finally {
trackerLock.writeLock().unlock();
}
}
@Override
public void untrackPassengers(CNPlayer another, int... passengers) {
Optional.ofNullable(trackers.get(another)).ifPresent(tracker -> {
for (int passenger : passengers) {
tracker.removePassengerID(passenger);
trackerLock.writeLock().lock();
try {
Tracker tracker = trackers.get(another);
if (tracker != null) {
for (int passenger : passengers) {
tracker.removePassengerID(passenger);
}
}
});
} finally {
trackerLock.writeLock().unlock();
}
}
@Override
public Set<Integer> getTrackedPassengerIds(CNPlayer another) {
return Optional.ofNullable(trackers.get(another)).map(Tracker::getPassengerIDs).orElse(new ObjectOpenHashSet<>());
trackerLock.readLock().lock();
try {
Tracker tracker = trackers.get(another);
return tracker != null ? tracker.getPassengerIDs() : new ObjectOpenHashSet<>();
} finally {
trackerLock.readLock().unlock();
}
}
@Override
public Tracker getTracker(CNPlayer another) {
return trackers.get(another);
trackerLock.readLock().lock();
try {
return trackers.get(another);
} finally {
trackerLock.readLock().unlock();
}
}
@Override
@@ -102,6 +102,7 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
protected boolean packItemsAdder;
protected boolean packItemsAdderLegacy;
protected boolean packOraxen;
protected boolean packNexo;
protected boolean packCreativeCentral;
protected boolean chatUnsafe;
@@ -111,6 +112,8 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
protected boolean chatCarbon;
protected boolean chatAdvanced;
protected boolean chatEss;
protected boolean chatChatControlRed;
protected boolean chatChatty;
protected String configVersion;
@@ -181,6 +184,7 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
if (packItemsAdder) packItemsAdderLegacy = false;
packOraxen = config.getBoolean("integrations.resource-pack.Oraxen", false);
packCreativeCentral = config.getBoolean("integrations.resource-pack.Creative-Central");
packNexo = config.getBoolean("integrations.resource-pack.Nexo");
chatUnsafe = config.getBoolean("other-settings.unsafe-chat-event", false);
chatEss = config.getBoolean("integrations.chat.Essentials", false);
@@ -189,6 +193,8 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
chatAdvanced = config.getBoolean("integrations.chat.AdvancedChat", false);
chatTR = config.getBoolean("integrations.chat.TrChat", false);
chatVenture = config.getBoolean("integrations.chat.VentureChat", false);
chatChatControlRed = config.getBoolean("integrations.chat.ChatControlRed", false);
chatChatty = config.getBoolean("integrations.chat.Chatty", false);
// Packs
generateOnStart = !config.getBoolean("resource-pack.disable-generation-on-start", false);
@@ -305,6 +311,10 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
return instance.packOraxen;
}
public static boolean packNexo() {
return instance.packNexo;
}
public static boolean packCreativeCentral() { return instance.packCreativeCentral; }
public static boolean hideScoreBoardNumber() {
@@ -411,6 +421,14 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
return instance.chatAdvanced;
}
public static boolean chatChatControlRed() {
return instance.chatChatControlRed;
}
public static boolean chatChatty() {
return instance.chatChatty;
}
@Override
public YamlDocument loadConfig(String filePath) {
return loadConfig(filePath, '.');
@@ -29,6 +29,7 @@ import net.momirealms.customnameplates.api.feature.image.ImageManager;
import net.momirealms.customnameplates.api.feature.nameplate.NameplateManager;
import net.momirealms.customnameplates.api.feature.pack.ResourcePackManager;
import net.momirealms.customnameplates.api.feature.tag.UnlimitedTagManager;
import net.momirealms.customnameplates.api.helper.VersionHelper;
import net.momirealms.customnameplates.api.network.PacketSender;
import net.momirealms.customnameplates.api.network.PipelineInjector;
import net.momirealms.customnameplates.api.placeholder.PlaceholderManager;
@@ -81,6 +82,13 @@ public abstract class CustomNameplates implements NameplatesPlugin {
protected ResourcePackManager resourcePackManager;
protected CustomNameplatesAPI api;
private String buildByBit = "%%__BUILTBYBIT__%%";
private String polymart = "%%__POLYMART__%%";
private String time = "%%__TIMESTAMP__%%";
private String user = "%%__USER__%%";
private String username = "%%__USERNAME__%%";
private boolean isLatest = false;
protected CustomNameplates() {
instance = this;
}
@@ -97,6 +105,36 @@ public abstract class CustomNameplates implements NameplatesPlugin {
@Override
public abstract void disable();
@Override
public void enable() {
boolean downloadFromPolymart = polymart.equals("1");
boolean downloadFromBBB = buildByBit.equals("true");
if (ConfigManager.checkUpdate()) {
VersionHelper.UPDATE_CHECKER.apply(this).thenAccept(result -> {
String link;
if (downloadFromPolymart) {
link = "https://polymart.org/resource/2543/";
} else if (downloadFromBBB) {
link = "https://builtbybit.com/resources/36359/";
} else {
link = "https://github.com/Xiao-MoMi/Custom-Nameplates/";
}
if (!result) {
this.getPluginLogger().info("You are using the latest version.");
isLatest = true;
} else {
this.getPluginLogger().warn("Update is available: " + link);
isLatest = false;
}
});
}
}
@Override
public boolean isUpToDate() {
return isLatest;
}
/**
* Logs debug messages through the provided supplier.
*
@@ -34,6 +34,7 @@ public class MainTask implements Runnable {
private int timer;
private final CustomNameplates plugin;
private boolean state;
public MainTask(CustomNameplates plugin) {
this.plugin = plugin;
@@ -53,24 +54,31 @@ public class MainTask implements Runnable {
@Override
public void run() {
RUN_TICKS++;
requestedSharedPlaceholders.clear();
long time1 = System.nanoTime();
plugin.actionBarManager.refreshConditions();
plugin.bossBarManager.onTick();
plugin.unlimitedTagManager.onTick();
long time2 = System.nanoTime();
plugin.placeholderManager.refreshPlaceholders();
long time3 = System.nanoTime();
plugin.actionBarManager.checkHeartBeats();
int diff1 = (int) (time2 - time1);
TIME_1.put(timer, diff1);
int diff2 = (int) (time3 - time2);
TIME_2.put(timer, diff2);
timer++;
if (timer >= 1200) timer = 0;
if (RUN_TICKS < 0) {
CustomNameplates.getInstance().reload();
// we should skip the task if the server is heavily loaded
if (this.state) return;
this.state = true;
try {
RUN_TICKS++;
requestedSharedPlaceholders.clear();
long time1 = System.nanoTime();
plugin.actionBarManager.refreshConditions();
plugin.bossBarManager.onTick();
plugin.unlimitedTagManager.onTick();
long time2 = System.nanoTime();
plugin.placeholderManager.refreshPlaceholders();
long time3 = System.nanoTime();
plugin.actionBarManager.checkHeartBeats();
int diff1 = (int) (time2 - time1);
TIME_1.put(timer, diff1);
int diff2 = (int) (time3 - time2);
TIME_2.put(timer, diff2);
timer++;
if (timer >= 1200) timer = 0;
if (RUN_TICKS < 0) {
CustomNameplates.getInstance().reload();
}
} finally {
this.state = false;
}
}
@@ -61,12 +61,18 @@ public class VersionHelper {
private static float version;
private static boolean mojmap;
private static boolean folia;
private static boolean mohist;
private static boolean paper;
public static void init(String serverVersion) {
String[] split = serverVersion.split("\\.");
version = Float.parseFloat(split[1] + "." + (split.length == 3 ? split[2] : "0"));
checkMojMap();
checkFolia();
checkMohist();
checkPaper();
boolean isModdedServer = mohist;
paper = paper && !isModdedServer;
}
public static float version() {
@@ -90,6 +96,22 @@ public class VersionHelper {
}
}
private static void checkMohist() {
try {
Class.forName("com.mohistmc.api.ServerAPI");
mohist = true;
} catch (ClassNotFoundException ignored) {
}
}
private static void checkPaper() {
try {
Class.forName("com.destroystokyo.paper.Metrics");
paper = true;
} catch (ClassNotFoundException ignored) {
}
}
public static boolean isVersionNewerThan1_21_2() {
return version >= 21.19;
}
@@ -118,6 +140,14 @@ public class VersionHelper {
return folia;
}
public static boolean isMohist() {
return mohist;
}
public static boolean isPaperOrItsForks() {
return paper;
}
public static boolean isMojmap() {
return mojmap;
}
+4
View File
@@ -2,6 +2,10 @@ plugins {
id("io.github.goooler.shadow") version "8.1.8"
}
repositories {
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}
dependencies {
compileOnly(project(":common"))
compileOnly(project(":api"))
@@ -124,14 +124,19 @@ public class ActionBarManagerImpl implements ActionBarManager, JoinQuitListener
@Override
public void onPlayerJoin(CNPlayer player) {
if (!ConfigManager.actionbarModule()) return;
plugin.getScheduler().asyncLater(() -> {
Runnable r = () -> {
if (!player.isOnline()) return;
ActionBarSender sender = new ActionBarSender(this, player);
ActionBarSender previous = senders.put(player.uuid(), sender);
if (previous != null) {
previous.destroy();
}
}, ConfigManager.delaySend() * 50L, TimeUnit.MILLISECONDS);
};
if (ConfigManager.delaySend() < 0) {
r.run();
} else {
plugin.getScheduler().asyncLater(r, ConfigManager.delaySend() * 50L, TimeUnit.MILLISECONDS);
}
}
@Override
@@ -80,7 +80,7 @@ public class ActionBarSender implements Feature {
this.onConditionTimerCheck();
}
public void onConditionTimerCheck() {
public synchronized void onConditionTimerCheck() {
ActionBarConfig[] configs = manager.actionBarConfigs();
outer: {
for (ActionBarConfig config : configs) {
@@ -522,6 +522,8 @@ public class AdvanceManagerImpl implements AdvanceManager {
String codePoints = requireNonNull(section.getString("codepoints", ""), "codepoints should be NonNull");
int height = section.getInt("height", 8);
boolean custom = section.getBoolean("custom", false);
boolean copy = section.getBoolean("generate", false);
String namespace = section.getString("namespace", ConfigManager.namespace());
File bitmapCache = new File(plugin.getDataDirectory().toFile(), "tmp" + File.separator + id + ".tmp");
if (!bitmapCache.exists()) {
@@ -586,9 +588,25 @@ public class AdvanceManagerImpl implements AdvanceManager {
}
registerCharacterFontData(id, bitmapCache, (properties) -> {
int ascent = (int) properties.get("shift_y");
String filePath = custom ? ConfigManager.namespace() + ":font/" + file : "minecraft:font/" + codePoints + ".png";
String filePath = custom ? namespace + ":font/" + file : "minecraft:font/" + codePoints + ".png";
plugin.getConfigManager().saveResource("tmp/" + codePoints + ".json");
StringBuilder jsonContent = new StringBuilder();
if (copy) {
File pngFile = new File(plugin.getDataDirectory().toFile(), "font" + File.separator + file);
File destination = new File(plugin.getDataDirectory().toFile(),
"ResourcePack"
+ File.separator + "assets"
+ File.separator + (custom ? namespace : "minecraft")
+ File.separator + "textures"
+ File.separator + "font"
+ File.separator + (custom ? file : codePoints + ".png")
);
try {
FileUtils.copyFile(pngFile, destination);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
try (BufferedReader reader = new BufferedReader(new FileReader(new File(plugin.getDataDirectory().toFile(), "tmp" + File.separator + codePoints + ".json")))) {
String line;
while ((line = reader.readLine()) != null) {
@@ -84,14 +84,19 @@ public class BossBarManagerImpl implements BossBarManager, JoinQuitListener {
@Override
public void onPlayerJoin(CNPlayer player) {
if (!ConfigManager.bossbarModule()) return;
plugin.getScheduler().asyncLater(() -> {
Runnable r = () -> {
if (!player.isOnline()) return;
BossBarDisplayController sender = new BossBarDisplayController(this, player);
BossBarDisplayController previous = senders.put(player.uuid(), sender);
if (previous != null) {
previous.destroy();
}
}, ConfigManager.delaySend() * 50L, TimeUnit.MILLISECONDS);
};
if (ConfigManager.delaySend() < 0) {
r.run();
} else {
plugin.getScheduler().asyncLater(r, ConfigManager.delaySend() * 50L, TimeUnit.MILLISECONDS);
}
}
@Override
@@ -98,7 +98,7 @@ public class BossBarSender implements Feature, BossBar {
timeLeft = 0;
}
public void tick() {
public synchronized void tick() {
if (timeLeft > 0)
timeLeft--;
@@ -41,6 +41,7 @@ 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 {
@@ -236,6 +237,14 @@ public class ResourcePackManagerImpl implements ResourcePackManager {
plugin.getPluginLogger().warn("Failed to copy files to Oraxen", e);
}
}
if (ConfigManager.packNexo()){
try {
FileUtils.deleteDirectory(new File(pluginsFolder, "Nexo" + File.separator + "pack" + File.separator + "external_packs" + File.separator + "CustomNameplates"));
FileUtils.copyDirectory(resourcePackFolder, new File(pluginsFolder, "Nexo" + File.separator + "pack" + File.separator + "external_packs" + File.separator + "CustomNameplates"));
} catch (IOException e){
plugin.getPluginLogger().warn("Failed to copy files to Nexo", e);
}
}
if(ConfigManager.packCreativeCentral()) {
try {
FileUtils.copyDirectory(new File(resourcePackFolder, "assets"), new File(pluginsFolder, "creative-central" + File.separator + "resources" + File.separator + "assets"));
@@ -25,6 +25,7 @@ import net.momirealms.customnameplates.api.feature.tag.NameTagConfig;
import net.momirealms.customnameplates.api.feature.tag.Tag;
import net.momirealms.customnameplates.api.feature.tag.TagRenderer;
import net.momirealms.customnameplates.api.feature.tag.UnlimitedTagManager;
import net.momirealms.customnameplates.api.helper.VersionHelper;
import net.momirealms.customnameplates.api.network.Tracker;
import java.util.*;
@@ -75,7 +76,7 @@ public class TagRendererImpl implements TagRenderer {
}
@Override
public void onTick() {
public synchronized void onTick() {
if (!isValid()) return;
Set<CNPlayer> playersToUpdatePassengers = new ObjectOpenHashSet<>();
@@ -301,7 +302,13 @@ public class TagRendererImpl implements TagRenderer {
passengers[index++] = passenger;
}
Object packet = CustomNameplates.getInstance().getPlatform().setPassengersPacket(owner.entityID(), passengers);
CustomNameplates.getInstance().getPacketSender().sendPacket(another, packet);
if (VersionHelper.isPaperOrItsForks()) {
CustomNameplates.getInstance().getPacketSender().sendPacket(another, packet);
} else {
CustomNameplates.getInstance().getScheduler().sync().runLater(() -> {
CustomNameplates.getInstance().getPacketSender().sendPacket(another, packet);
}, 0, null);
}
}
public void handleEntityDataChange(CNPlayer another, boolean isCrouching) {
@@ -114,7 +114,15 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
}
private void loadNestNameplatePlaceholders() {
if (!ConfigManager.nameplateModule()) return;
if (!ConfigManager.nameplateModule()) {
this.registerPlayerPlaceholder("%np_tag-image%", (player -> "Please remove %np_tag-image% if you have disabled nameplates module"));
this.registerPlayerPlaceholder("%rel_np_tag-image%", (player -> "Please remove %rel_np_tag-image% if you have disabled nameplates module"));
this.registerPlayerPlaceholder("%np_tag-text%", (player -> "Please remove %np_tag-text% if you have disabled nameplates module"));
this.registerPlayerPlaceholder("%rel_np_tag-text%", (player -> "Please remove %rel_np_tag-text% if you have disabled nameplates module"));
this.registerPlayerPlaceholder("%np_tag%", (player -> "Please remove %np_tag% if you have disabled nameplates module"));
this.registerPlayerPlaceholder("%rel_np_tag%", (player -> "Please remove %rel_np_tag% if you have disabled nameplates module"));
return;
}
PreParsedDynamicText nameTag = new PreParsedDynamicText(plugin.getNameplateManager().playerNameTag());
Placeholder placeholder1 = this.registerPlayerPlaceholder("%np_tag-image%", (player -> {
String equippedNameplate = player.equippedNameplate();
@@ -124,10 +124,17 @@ public abstract class AbstractRequirementManager implements RequirementManager {
this.registerRequirement((args, interval) -> {
Section section = ConfigUtils.safeCast(args, Section.class);
if (section == null) return Requirement.empty();
PreParsedDynamicText dynamicText1 = new PreParsedDynamicText(section.getString("value1", ""), true);
String regex = section.getString("value2", "");
PreParsedDynamicText dynamicText1 = new PreParsedDynamicText(section.getString("papi", ""), true);
String regex = section.getString("regex", "");
return new RegexRequirement(interval, dynamicText1, regex);
}, "regex");
this.registerRequirement((args, interval) -> {
Section section = ConfigUtils.safeCast(args, Section.class);
if (section == null) return Requirement.empty();
PreParsedDynamicText dynamicText1 = new PreParsedDynamicText(section.getString("papi", ""), true);
String regex = section.getString("regex", "");
return new NotRegexRequirement(interval, dynamicText1, regex);
}, "!regex");
this.registerRequirement((args, interval) -> {
Section section = ConfigUtils.safeCast(args, Section.class);
if (section == null) return Requirement.empty();
@@ -0,0 +1,37 @@
/*
* 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.backend.requirement.builtin;
import net.momirealms.customnameplates.api.feature.PreParsedDynamicText;
public class NotRegexRequirement extends PlaceholderRequirement<String> {
public NotRegexRequirement(int refreshInterval, PreParsedDynamicText text, String any) {
super(refreshInterval, text, any);
}
@Override
protected boolean checkArgument(String a1, String a2) {
return !a1.matches(a2);
}
@Override
public String type() {
return "!regex";
}
}
@@ -4,7 +4,7 @@
"description": "CustomNameplates",
"supported_formats": {
"min_inclusive": 13,
"max_inclusive": 43
"max_inclusive": 46
}
},
"overlays": {
@@ -19,7 +19,7 @@
{
"formats": {
"min_inclusive": 42,
"max_inclusive": 43
"max_inclusive": 46
},
"directory": "overlay_1_21_2"
}
@@ -4,7 +4,7 @@
"description": "CustomNameplates",
"supported_formats": {
"min_inclusive": 32,
"max_inclusive": 42
"max_inclusive": 46
}
},
"overlays": {
@@ -19,7 +19,7 @@
{
"formats": {
"min_inclusive": 42,
"max_inclusive": 43
"max_inclusive": 46
},
"directory": "overlay_1_21_2"
}
@@ -4,7 +4,7 @@
"description": "CustomNameplates",
"supported_formats": {
"min_inclusive": 42,
"max_inclusive": 43
"max_inclusive": 46
}
}
}
+13 -7
View File
@@ -23,8 +23,9 @@ modules:
integrations:
resource-pack:
ItemsAdder: false # Integration with ItemsAdder
ItemsAdder-old-method: false # Old method for ItemsAdder
ItemsAdder-old-method: false # Legacy integration with ItemsAdder
Oraxen: false # Integration with Oraxen
Nexo: false # Integration with Nexo
Creative-Central: false # Integration with Creative-Central
chat:
TrChat: false # Integration with TrChat
@@ -33,6 +34,8 @@ integrations:
CarbonChat: false # Integration with CarbonChat
AdvancedChat: false # Integration with AdvancedChat
Essentials: false # Integration with Essentials chat
ChatControlRed: false # Integration with ChatControlRed
Chatty: false # Integration with Chatty
# Resource Pack Generation Settings: Configure resource pack generation behavior.
resource-pack:
@@ -60,18 +63,19 @@ resource-pack:
# Additional Settings: Extra options to control behavior and performance.
other-settings:
legacy-color-code-support: true # Enable support for legacy color codes using &
send-delay: 20 # Set actionbar/bossbar send delay (ticks)
send-delay: 20 # Set actionbar/bossbar send delay (ticks) (0 = send immediately on async threads, -1 = send immediately on main thread)
catch-other-plugin-actionbar: true # Capture actionbars from other plugins
other-actionbar-stay-time: 3000 # How long does other actionsbars stay (ms)
display-system-actionbar: true # Should the plugin display system actionbar and temporarily hide the custom actionbar?
hide-team-names: true # Hide the team name sent by other plugins or vanilla team system
unsafe-chat-event: false # Listen for canceled(unsafe) chat events from unknown plugins
default-condition-refresh-interval: 20 # Set default condition refresh interval
default-placeholder-refresh-interval: 1 # Set default placeholder refresh interval
default-condition-refresh-interval: 10 # Set default condition refresh interval in ticks
default-placeholder-refresh-interval: 1 # Set default placeholder refresh interval in ticks
placeholder-refresh-interval: # Custom placeholder refresh intervals for performance optimization
"%player_name%": 100
"%vault_prefix%": 20
# Font Templates: Define different fonts and their settings.
# Requires a restart to apply because it can be laggy to read thousands of character
font-templates:
space:
space:
@@ -80,7 +84,7 @@ other-settings:
unihex:
unifont:
file: unifont.zip # Load font from unifont.zip
generate: false # Don't include font in the generated resource pack
generate: false # Should this unihex file be included in the generated pack
size_overrides: # Override size for specific Unicode ranges
- from: "\\u3001"
to: "\\u30FF"
@@ -120,7 +124,7 @@ other-settings:
right: 15
unifont_jp:
file: unifont_jp.zip # Load Japanese unifont
generate: false # Don't generate in the resource pack
generate: false # Should this unihex file be included in the generated pack
filter:
"jp": true # Apply to Japanese characters only
size_overrides:
@@ -137,7 +141,9 @@ other-settings:
codepoints: ascii # Define ASCII bitmap font
file: ascii.png # Use ascii.png file for the font
height: 8 # Font height is 8 units
custom: false # Not a custom font (default Minecraft)
custom: false # Does this png path point to a non-default font path??
generate: false # Should this png file be included in the generated pack
# namespace: custom # Optional namespace if you don't want to use the global namespace set in config.yml
ascii_sga:
codepoints: ascii_sga
file: ascii_sga.png
@@ -169,7 +169,8 @@ switch-text:
'egg': "</gradient>"
'xmas': "</WHITE>"
'angel': "</#8B4513>"
'sign': "</WHITE>"
'sign': "</BLACK>"
'banner': "</WHITE>"
'enter': "</WHITE>"
world:
switch: '%player_world%'
+1 -1
View File
@@ -26,7 +26,7 @@ subprojects {
expand(rootProject.properties)
}
filesMatching(arrayListOf("*.yml", "*/*.yml")) {
filesMatching(arrayListOf("*.yml", "*/*.yml", "META-INF/sponge_plugins.json")) {
expand(
Pair("project_version", rootProject.properties["project_version"]),
Pair("config_version", rootProject.properties["config_version"])
+4
View File
@@ -1,3 +1,7 @@
repositories {
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}
dependencies {
compileOnly("net.kyori:adventure-api:${rootProject.properties["adventure_bundle_version"]}") {
exclude(module = "adventure-bom")
@@ -113,6 +113,14 @@ public enum Dependency {
Relocation.of("cloud", "org{}incendo{}cloud"),
Relocation.of("geantyref", "io{}leangen{}geantyref")
),
CLOUD_SPONGE(
"org{}incendo",
"cloud-sponge7",
"maven",
"cloud-sponge7",
Relocation.of("cloud", "org{}incendo{}cloud"),
Relocation.of("geantyref", "io{}leangen{}geantyref")
),
CLOUD_MINECRAFT_EXTRAS(
"org{}incendo",
"cloud-minecraft-extras",
@@ -226,6 +234,18 @@ public enum Dependency {
return Dependency.BSTATS_BASE.getVersion();
}
},
BSTATS_SPONGE(
"org{}bstats",
"bstats-sponge",
"maven",
"bstats-sponge",
Relocation.of("bstats", "org{}bstats")
) {
@Override
public String getVersion() {
return Dependency.BSTATS_BASE.getVersion();
}
},
GSON(
"com.google.code.gson",
"gson",
+13 -13
View File
@@ -1,7 +1,7 @@
# Project settings
# Rule: [major update].[feature update].[bug fix]
project_version=3.0.12
config_version=32
project_version=3.0.15.2
config_version=34
project_group=net.momirealms
# Supported languages
@@ -10,16 +10,16 @@ lang=en,zh_cn
# Dependency settings
paper_version=1.20.4
jetbrains_annotations_version=24.0.0
slf4j_version=2.0.13
log4j_version=2.23.1
slf4j_version=2.0.16
log4j_version=2.24.1
gson_version=2.11.0
asm_version=9.7.1
asm_commons_version=9.7.1
jar_relocator_version=1.7
h2_driver_version=2.2.224
sqlite_driver_version=3.46.1.0
adventure_bundle_version=4.17.0
adventure_platform_version=4.3.4
h2_driver_version=2.3.232
sqlite_driver_version=3.47.0.0
adventure_bundle_version=4.18.0-SNAPSHOT
adventure_platform_version=4.3.5-SNAPSHOT
cloud_core_version=2.0.0
cloud_services_version=2.0.0
cloud_brigadier_version=2.0.0-beta.10
@@ -27,14 +27,14 @@ cloud_bukkit_version=2.0.0-beta.10
cloud_paper_version=2.0.0-beta.10
cloud_minecraft_extras_version=2.0.0-beta.10
boosted_yaml_version=1.3.7
byte_buddy_version=1.14.18
byte_buddy_version=1.15.10
mojang_brigadier_version=1.0.18
mongodb_driver_version=5.1.4
mariadb_driver_version=3.4.1
mysql_driver_version=9.0.0
mongodb_driver_version=5.2.1
mariadb_driver_version=3.5.0
mysql_driver_version=9.1.0
hikari_version=5.1.0
commons_pool_version=2.12.0
bstats_version=3.0.2
bstats_version=3.1.0
geantyref_version=1.3.16
caffeine_version=3.1.8
jedis_version=5.1.5
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
File renamed without changes.
@@ -7,7 +7,7 @@ repositories {
maven("https://libraries.minecraft.net") // brigadier
maven("https://jitpack.io/")
maven("https://papermc.io/repo/repository/maven-public/") // paper
maven("https://oss.sonatype.org/content/repositories/snapshots")
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") // spigot
}
@@ -17,7 +17,7 @@ dependencies {
}
implementation(project(":common"))
implementation(project(":backend"))
implementation(project(":compatibility"))
implementation(project(":platforms:bukkit:compatibility"))
compileOnly("dev.folia:folia-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT")
compileOnly("me.clip:placeholderapi:${rootProject.properties["placeholder_api_version"]}")
@@ -46,7 +46,7 @@ dependencies {
tasks {
shadowJar {
archiveFileName = "CustomNameplates-${rootProject.properties["project_version"]}.jar"
archiveFileName = "CustomNameplates-Bukkit-${rootProject.properties["project_version"]}.jar"
destinationDirectory.set(file("$rootDir/target"))
relocate("net.kyori", "net.momirealms.customnameplates.libraries")
relocate("org.incendo", "net.momirealms.customnameplates.libraries")
@@ -29,9 +29,12 @@ dependencies {
compileOnly(files("libs/carbonchat-paper-3.0.0-beta.27.jar"))
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("net.william278.huskchat:huskchat-bukkit:3.0.4")
compileOnly("net.essentialsx:EssentialsX:2.20.1")
compileOnly("net.essentialsx:EssentialsXChat:2.20.1")
// compileOnly("com.github.Brikster:Chatty:v2.19.14")
compileOnly(files("libs/Chatty-3.0.0-SNAPSHOT.jar"))
// Emoji
compileOnly("com.github.LoneDev6:api-itemsadder:3.6.3-beta-14")
compileOnly("io.th0rgal:oraxen:1.182.0")
@@ -0,0 +1,85 @@
/*
* Copyright (C) <2022> <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.chat;
import net.momirealms.customnameplates.api.CNPlayer;
import net.momirealms.customnameplates.api.CustomNameplates;
import net.momirealms.customnameplates.api.feature.chat.AbstractChatMessageProvider;
import net.momirealms.customnameplates.api.feature.chat.ChatManager;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.mineacademy.chatcontrol.PlayerCache;
import org.mineacademy.chatcontrol.api.ChatChannelEvent;
import org.mineacademy.chatcontrol.model.Channel;
import java.util.Objects;
public class ChatControlRedProvider extends AbstractChatMessageProvider implements Listener {
public ChatControlRedProvider(CustomNameplates plugin, ChatManager manager) {
super(plugin, manager);
}
@EventHandler(ignoreCancelled = true)
public void onChat(ChatChannelEvent event) {
plugin.debug(() -> "ChatChannelEvent triggered");
final CommandSender sender = event.getSender();
if (!(sender instanceof Player player)) {
return;
}
if (!player.isOnline()) return;
CNPlayer cnPlayer = plugin.getPlayer(player.getUniqueId());
if (cnPlayer == null) return;
plugin.getScheduler().async().execute(() -> {
manager.onChat(cnPlayer, event.getMessage(), event.getChannel().getName());
});
}
@Override
public boolean hasJoinedChannel(CNPlayer player, String channelID) {
Channel channel = Channel.findChannel(channelID);
if (channel == null) return false;
return channel.isInChannel((Player) player.player());
}
@Override
public boolean canJoinChannel(CNPlayer player, String channelID) {
return ((Player) player).hasPermission("chatcontrol.channel.join."+channelID+".read");
}
@Override
public boolean isIgnoring(CNPlayer sender, CNPlayer receiver) {
PlayerCache cache = PlayerCache.from((Player) receiver.player());
if (cache == null) return false;
return cache.isIgnoringPlayer(sender.uuid());
}
@Override
public void register() {
Bukkit.getPluginManager().registerEvents(this, Objects.requireNonNull(Bukkit.getPluginManager().getPlugin("CustomNameplates")));
}
@Override
public void unregister() {
HandlerList.unregisterAll(this);
}
}
@@ -0,0 +1,82 @@
/*
* Copyright (C) <2022> <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.chat;
import net.momirealms.customnameplates.api.CNPlayer;
import net.momirealms.customnameplates.api.CustomNameplates;
import net.momirealms.customnameplates.api.feature.chat.AbstractChatMessageProvider;
import net.momirealms.customnameplates.api.feature.chat.ChatManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import ru.brikster.chatty.api.ChattyApi;
import ru.brikster.chatty.api.chat.Chat;
import ru.brikster.chatty.api.event.ChattyMessageEvent;
import java.util.Objects;
public class ChattyProvider extends AbstractChatMessageProvider implements Listener {
public ChattyProvider(CustomNameplates plugin, ChatManager manager) {
super(plugin, manager);
}
@EventHandler(ignoreCancelled = true)
public void onChat(ChattyMessageEvent event) {
final String message = event.getPlainMessage();
final Player player = event.getSender();
if (!player.isOnline()) return;
CNPlayer cnPlayer = plugin.getPlayer(player.getUniqueId());
if (cnPlayer == null) return;
plugin.getScheduler().async().execute(() -> {
manager.onChat(cnPlayer, message, event.getChat().getId());
});
}
@Override
public boolean hasJoinedChannel(CNPlayer player, String channelID) {
return true;
}
@Override
public boolean canJoinChannel(CNPlayer player, String channelID) {
Chat chat = ChattyApi.instance().getChats().get(channelID);
if (chat == null) {
return false;
}
if (!chat.isPermissionRequired()) return true;
return chat.hasReadPermission((Player) player.player());
}
@Override
public boolean isIgnoring(CNPlayer sender, CNPlayer receiver) {
return false;
}
@Override
public void register() {
Bukkit.getPluginManager().registerEvents(this, Objects.requireNonNull(Bukkit.getPluginManager().getPlugin("CustomNameplates")));
}
@Override
public void unregister() {
HandlerList.unregisterAll(this);
}
}
@@ -18,13 +18,11 @@
package net.momirealms.customnameplates.bukkit;
import net.momirealms.customnameplates.api.CustomNameplates;
import net.momirealms.customnameplates.common.plugin.NameplatesPlugin;
import org.bukkit.plugin.java.JavaPlugin;
public class BukkitBootstrap extends JavaPlugin {
private CustomNameplates nameplates;
private NameplatesPlugin plugin;
private CustomNameplates plugin;
@Override
public void onLoad() {
@@ -80,7 +80,7 @@ public class BukkitCNPlayer extends AbstractCNPlayer {
@Override
public Vector3 position() {
Location location = player().getLocation();
return new Vector3(location.x(), location.y(), location.z());
return new Vector3(location.getX(), location.getY(), location.getZ());
}
@Override
@@ -51,6 +51,12 @@ public class BukkitChatManager extends AbstractChatManager {
} else if (ConfigManager.chatEss() && Bukkit.getPluginManager().isPluginEnabled("EssentialsChat")) {
this.chatProvider = new EssentialsChatProvider(plugin, this);
plugin.getPluginLogger().info("EssentialsChat hooked!");
} else if (ConfigManager.chatChatControlRed() && Bukkit.getPluginManager().isPluginEnabled("ChatControlRed")) {
this.chatProvider = new ChatControlRedProvider(plugin, this);
plugin.getPluginLogger().info("ChatControlRed hooked!");
} else if (ConfigManager.chatChatty() && Bukkit.getPluginManager().isPluginEnabled("Chatty")) {
this.chatProvider = new ChattyProvider(plugin, this);
plugin.getPluginLogger().info("Chatty hooked!");
} else {
this.chatProvider = new AsyncChatProvider(plugin, this);
}
@@ -94,14 +94,6 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
private boolean loaded = false;
private String buildByBit = "%%__BUILTBYBIT__%%";
private String polymart = "%%__POLYMART__%%";
private String time = "%%__TIMESTAMP__%%";
private String user = "%%__USER__%%";
private String username = "%%__USERNAME__%%";
private boolean isLatest = false;
public BukkitCustomNameplates(JavaPlugin bootstrap) {
this.bootstrap = bootstrap;
VersionHelper.init(getServerVersion());
@@ -212,29 +204,6 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
}
}
boolean downloadFromPolymart = polymart.equals("1");
boolean downloadFromBBB = buildByBit.equals("true");
if (ConfigManager.checkUpdate()) {
VersionHelper.UPDATE_CHECKER.apply(this).thenAccept(result -> {
String link;
if (downloadFromPolymart) {
link = "https://polymart.org/resource/2543/";
} else if (downloadFromBBB) {
link = "https://builtbybit.com/resources/36359/";
} else {
link = "https://github.com/Xiao-MoMi/Custom-Nameplates/";
}
if (!result) {
this.getPluginLogger().info("You are using the latest version.");
isLatest = true;
} else {
this.getPluginLogger().warn("Update is available: " + link);
isLatest = false;
}
});
}
if (VersionHelper.isFolia()) {
this.foliaTrackerTask = getScheduler().asyncRepeating(() -> {
for (CNPlayer player : getOnlinePlayers()) {
@@ -264,6 +233,8 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
}
}, 200, 200, TimeUnit.MILLISECONDS);
}
super.enable();
}
@Override
@@ -284,7 +255,11 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
if (nameplateManager != null) this.nameplateManager.disable();
if (imageManager != null) this.imageManager.disable();
if (chatManager != null) this.chatManager.disable();
if (commandManager != null) this.commandManager.unregisterFeatures();
if (commandManager != null) {
if (!Bukkit.getServer().isStopping()) {
this.commandManager.unregisterFeatures();
}
}
this.joinQuitListeners.clear();
this.playerListeners.clear();
this.networkManager.shutdown();
@@ -313,6 +288,7 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
this.requirementManager.reload();
// load basics
this.configManager.reload();
this.debugger = ConfigManager.debug() ? (s) -> getPluginLogger().info("[DEBUG] " + s.get()) : (s) -> {};
this.storageManager.reload();
this.translationManager.reload();
// prepare resources
@@ -334,10 +310,6 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
this.scheduledMainTask = getScheduler().asyncRepeating(mainTask, 50, 50, TimeUnit.MILLISECONDS);
}
@Override
public boolean isUpToDate() {
return isLatest;
}
@Override
public InputStream getResourceStream(String filePath) {
Loaded 100 of 132 files, more files were not shown because too many files have changed in this diff. Show more