mirror of
https://github.com/Xiao-MoMi/Custom-Nameplates.git
synced 2026-11-05 17:02:39 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0387b30149 | ||
|
|
797b77c529 | ||
|
|
2e689cabb1 | ||
|
|
52f244ddf3 | ||
|
|
6c0a8d2788 | ||
|
|
0d75def1b6 | ||
|
|
f3c297f6d4 | ||
|
|
ec6ff01e24 | ||
|
|
45f8f4fcd4 | ||
|
|
2f6beff060 | ||
|
|
cef568b0b0 | ||
|
|
49fa5d167b | ||
|
|
d6bd4a1574 | ||
|
|
67a97411b8 | ||
|
|
4a4d1fe979 | ||
|
|
d106c96280 | ||
|
|
52331421be | ||
|
|
6c38fc03cc | ||
|
|
aaf4beead4 | ||
|
|
8fb63a90be | ||
|
|
bc83aa46c5 | ||
|
|
fcc6d2bdc5 | ||
|
|
83f6a0139f | ||
|
|
9b74a7bb59 | ||
|
|
22c5c61144 | ||
|
|
741e043b17 | ||
|
|
a4e730890a | ||
|
|
19e30bc29b | ||
|
|
1e5e3bea2c | ||
|
|
8e1ba461a6 | ||
|
|
d573c9063b | ||
|
|
e2a5a5564f | ||
|
|
1a2a689c4c | ||
|
|
4be6e27bc1 | ||
|
|
efae3f62d6 | ||
|
|
0f4af0938b | ||
|
|
72b1dc8513 | ||
|
|
c695226515 | ||
|
|
084f7d1edf | ||
|
|
dafe373f81 | ||
|
|
e405d1c4f1 | ||
|
|
d9ee1bbb21 | ||
|
|
8a4b0e1c23 | ||
|
|
d9d129cd97 | ||
|
|
12060e9b59 | ||
|
|
491ad32466 | ||
|
|
7932423628 | ||
|
|
2036b13524 | ||
|
|
99a9afb1c7 | ||
|
|
486b96d232 | ||
|
|
f505d0da34 | ||
|
|
9c77cf6878 | ||
|
|
df5a1faa19 | ||
|
|
2ebb781721 | ||
|
|
3cbf4698ed | ||
|
|
e01dec757e | ||
|
|
857e5bedc9 | ||
|
|
4ac11deb07 | ||
|
|
9f657166ff | ||
|
|
687908defc | ||
|
|
5520dc3c4e | ||
|
|
3b6542858c | ||
|
|
75982b67a1 | ||
|
|
f1adb436d0 | ||
|
|
c25e222187 | ||
|
|
8f23416ed6 | ||
|
|
85a399eda0 | ||
|
|
01463d554c | ||
|
|
29de340676 | ||
|
|
ebca2deef5 | ||
|
|
f5bc4fda2d | ||
|
|
0328c534c4 | ||
|
|
4d0fab7b68 | ||
|
|
a2f0591e29 | ||
|
|
5a3c320995 | ||
|
|
fd19b99e77 | ||
|
|
4e5dcad309 | ||
|
|
fd2c810d21 | ||
|
|
4bf9a00b32 | ||
|
|
8c0272acc7 | ||
|
|
f8a8ce0f43 | ||
|
|
1147deaa73 | ||
|
|
1bc4ab6258 | ||
|
|
a95ea99a55 | ||
|
|
6dbc6bf596 | ||
|
|
63ec5e8a92 | ||
|
|
8c1a858e2a | ||
|
|
88e4af721b | ||
|
|
b41e1bd2ab | ||
|
|
28ccd9130c | ||
|
|
16976e6347 | ||
|
|
c8f8c38cc8 | ||
|
|
ddbe549900 | ||
|
|
b4608394f7 | ||
|
|
7b7fe63364 | ||
|
|
906390aa78 | ||
|
|
c491a99b1e | ||
|
|
5733338584 | ||
|
|
2fb0e311c9 | ||
|
|
44656962ac | ||
|
|
87703736c3 | ||
|
|
1053b36f75 | ||
|
|
9b26ce4e19 | ||
|
|
0270830517 | ||
|
|
23bde6ab9d | ||
|
|
6f0e61ae48 | ||
|
|
26b593950d | ||
|
|
63896acda6 | ||
|
|
6eb5dee611 | ||
|
|
69869d1cb1 | ||
|
|
2e702d8945 | ||
|
|
56c77bd294 | ||
|
|
4d195820a0 | ||
|
|
2874ab7c4e | ||
|
|
cd1a0bffb6 | ||
|
|
20d3919c6b | ||
|
|
fccaa059ff | ||
|
|
ed2fb60748 | ||
|
|
378dc2e3bc | ||
|
|
6144423110 | ||
|
|
d21fa8a3f7 | ||
|
|
7e68a6cda7 | ||
|
|
3df6d66efb | ||
|
|
001ecd28ed | ||
|
|
6fe8625722 | ||
|
|
43e006f49d | ||
|
|
8d63ad9c74 | ||
|
|
5c2411e420 | ||
|
|
a57cfb0842 | ||
|
|
e4d7fb4346 | ||
|
|
9a9865c424 | ||
|
|
f6b8ce253f | ||
|
|
144b358768 | ||
|
|
0fd7ac1a79 | ||
|
|
67f0e60327 | ||
|
|
d10eb6de67 | ||
|
|
8cfd098be9 | ||
|
|
e3d81e7c0c | ||
|
|
018dc18eee | ||
|
|
366cda6bef | ||
|
|
ca70dfb2b4 | ||
|
|
d59ac96f48 |
No files matched your search
@@ -5,6 +5,9 @@ target/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### Unfinished ###
|
||||
platforms/sponge/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# Custom-Nameplates
|
||||
|
||||

|
||||
[](https://jitpack.io/#Xiao-MoMi/Custom-Nameplates)
|
||||
<a href="https://mo-mi.gitbook.io/xiaomomi-plugins/plugin-wiki/customnameplates" alt="GitBook">
|
||||
<img src="https://img.shields.io/badge/docs-gitbook-brightgreen" alt="Gitbook"/>
|
||||
</a>
|
||||
@@ -11,7 +10,7 @@
|
||||

|
||||

|
||||
|
||||
## How to build
|
||||
## How to Build
|
||||
|
||||
#### Command Line
|
||||
Install JDK 17 & 21. \
|
||||
@@ -22,54 +21,27 @@ Execute ".\gradlew build" and get the artifact under /target folder
|
||||
Import the project and execute gradle build action. \
|
||||
Get the artifact under /target folder
|
||||
|
||||
## Support the developer
|
||||
## How to Contribute
|
||||
|
||||
Polymart: https://polymart.org/resource/customnameplates.2543 \
|
||||
Afdian: https://afdian.com/@xiaomomi
|
||||
#### Translations
|
||||
Clone this project and create a new language file in the /backend/src/main/resources/translations directory. \
|
||||
Once your changes are ready, open a pull request for review. We appreciate your works!
|
||||
|
||||
## Support the Developer
|
||||
|
||||
Polymart: https://polymart.org/resource/customnameplates.2543/ \
|
||||
BuiltByBit: https://builtbybit.com/resources/customnameplates.36359/ \
|
||||
Afdian: https://afdian.com/@xiaomomi/
|
||||
|
||||
## CustomNameplates API
|
||||
|
||||
### Maven
|
||||
|
||||
```html
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack</id>
|
||||
<url>https://jitpack.io/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
```
|
||||
```html
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.Xiao-MoMi</groupId>
|
||||
<artifactId>Custom-Nameplates</artifactId>
|
||||
<version>{VERSION}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
### Gradle (Groovy)
|
||||
|
||||
```groovy
|
||||
repositories {
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
```
|
||||
```groovy
|
||||
dependencies {
|
||||
compileOnly 'com.github.Xiao-MoMi:Custom-Nameplates:{VERSION}'
|
||||
}
|
||||
```
|
||||
### Gradle (Kotlin)
|
||||
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://jitpack.io/")
|
||||
maven("https://repo.momirealms.net/releases/")
|
||||
}
|
||||
```
|
||||
```kotlin
|
||||
dependencies {
|
||||
compileOnly("com.github.Xiao-MoMi:Custom-Nameplates:{VERSION}")
|
||||
compileOnly("net.momirealms:custom-nameplates:3.0.19")
|
||||
}
|
||||
```
|
||||
+49
-14
@@ -1,60 +1,95 @@
|
||||
plugins {
|
||||
id("io.github.goooler.shadow") version "8.1.8"
|
||||
id("maven-publish")
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven("https://jitpack.io/")
|
||||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":common"))
|
||||
// Adventure
|
||||
implementation("net.kyori:adventure-api:${rootProject.properties["adventure_bundle_version"]}")
|
||||
compileOnly("net.kyori:adventure-text-minimessage:${rootProject.properties["adventure_bundle_version"]}")
|
||||
compileOnly("net.kyori:adventure-text-serializer-gson:${rootProject.properties["adventure_bundle_version"]}")
|
||||
compileOnly("net.kyori:adventure-text-minimessage:${rootProject.properties["adventure_bundle_version"]}")
|
||||
compileOnly("net.kyori:adventure-text-serializer-gson:${rootProject.properties["adventure_bundle_version"]}")
|
||||
compileOnly("net.kyori:adventure-text-serializer-json-legacy-impl:${rootProject.properties["adventure_bundle_version"]}")
|
||||
// YAML
|
||||
implementation(files("libs/boosted-yaml-${rootProject.properties["boosted_yaml_version"]}.jar"))
|
||||
// Cache
|
||||
compileOnly("com.github.ben-manes.caffeine:caffeine:${rootProject.properties["caffeine_version"]}")
|
||||
// Netty
|
||||
compileOnly("io.netty:netty-all:4.1.113.Final")
|
||||
compileOnly("io.netty:netty-all:4.1.117.Final")
|
||||
// GSON
|
||||
compileOnly("com.google.code.gson:gson:${rootProject.properties["gson_version"]}")
|
||||
// Fast util
|
||||
compileOnly("it.unimi.dsi:fastutil:${rootProject.properties["fastutil_version"]}")
|
||||
// Command
|
||||
compileOnly("org.incendo:cloud-core:${rootProject.properties["cloud_core_version"]}")
|
||||
compileOnly("org.incendo:cloud-minecraft-extras:${rootProject.properties["cloud_minecraft_extras_version"]}")
|
||||
// Logger
|
||||
compileOnly("org.slf4j:slf4j-api:${rootProject.properties["slf4j_version"]}")
|
||||
compileOnly("org.apache.logging.log4j:log4j-core:${rootProject.properties["log4j_version"]}")
|
||||
// Expression
|
||||
compileOnly("net.objecthunter:exp4j:${rootProject.properties["exp4j_version"]}")
|
||||
// code generator
|
||||
compileOnly("net.bytebuddy:byte-buddy:${rootProject.properties["byte_buddy_version"]}")
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(17)
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
options.release.set(17)
|
||||
options.release.set(21)
|
||||
dependsOn(tasks.clean)
|
||||
}
|
||||
|
||||
tasks {
|
||||
shadowJar {
|
||||
archiveClassifier = ""
|
||||
archiveFileName = "CustomNameplates-${rootProject.properties["project_version"]}.jar"
|
||||
archiveClassifier.set("")
|
||||
archiveFileName = "custom-nameplates-${rootProject.properties["project_version"]}.jar"
|
||||
relocate ("net.kyori", "net.momirealms.customnameplates.libraries")
|
||||
relocate("dev.dejvokep", "net.momirealms.customnameplates.libraries")
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
url = uri("https://repo.momirealms.net/releases")
|
||||
credentials(PasswordCredentials::class) {
|
||||
username = System.getenv("REPO_USERNAME")
|
||||
password = System.getenv("REPO_PASSWORD")
|
||||
}
|
||||
}
|
||||
}
|
||||
publications {
|
||||
create<MavenPublication>("mavenJava") {
|
||||
groupId = "net.momirealms"
|
||||
artifactId = "CustomNameplates"
|
||||
version = rootProject.version.toString()
|
||||
artifact(tasks.shadowJar)
|
||||
artifactId = "custom-nameplates"
|
||||
version = rootProject.properties["project_version"].toString()
|
||||
artifact(tasks["sourcesJar"])
|
||||
from(components["shadow"])
|
||||
pom {
|
||||
name = "CustomNameplates API"
|
||||
url = "https://github.com/Xiao-MoMi/Custom-Nameplates"
|
||||
licenses {
|
||||
license {
|
||||
name = "GNU General Public License v3.0"
|
||||
url = "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||
distribution = "repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,8 @@
|
||||
package net.momirealms.customnameplates.api;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.feature.Feature;
|
||||
import net.momirealms.customnameplates.api.feature.TimeStampData;
|
||||
import net.momirealms.customnameplates.api.feature.tag.TeamView;
|
||||
@@ -29,113 +31,174 @@ import net.momirealms.customnameplates.api.placeholder.SharedPlaceholder;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
import net.momirealms.customnameplates.api.storage.data.PlayerData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
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 {
|
||||
|
||||
/**
|
||||
* Player instance adapted by CustomNameplates
|
||||
*/
|
||||
public abstract class AbstractCNPlayer<P> implements CNPlayer {
|
||||
/**
|
||||
* The CustomNameplates plugin
|
||||
*/
|
||||
protected final CustomNameplates plugin;
|
||||
/**
|
||||
* Player netty channel
|
||||
*/
|
||||
protected final Channel channel;
|
||||
/**
|
||||
* Platform player instance
|
||||
*/
|
||||
protected P player;
|
||||
protected UUID uuid;
|
||||
protected int entityId;
|
||||
protected String name;
|
||||
|
||||
protected Object player;
|
||||
private volatile boolean isLoaded = false;
|
||||
private volatile boolean tempPreviewing = false;
|
||||
private volatile boolean toggleablePreviewing = false;
|
||||
|
||||
private boolean isLoaded = false;
|
||||
|
||||
private boolean tempPreviewing = false;
|
||||
private boolean toggleablePreviewing = false;
|
||||
|
||||
private String equippedNameplate;
|
||||
private String equippedBubble;
|
||||
private String currentNameplate;
|
||||
private String nameplateData;
|
||||
private String currentBubble;
|
||||
private String bubbleData;
|
||||
|
||||
private final TeamView teamView = new TeamView();
|
||||
|
||||
private final Map<Integer, TimeStampData<String>> cachedValues = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, WeakHashMap<CNPlayer, TimeStampData<String>>> cachedRelationalValues = new ConcurrentHashMap<>();
|
||||
|
||||
private final Map<Requirement, TimeStampData<Boolean>> cachedRequirements = new ConcurrentHashMap<>();
|
||||
private final Map<Requirement, WeakHashMap<CNPlayer, TimeStampData<Boolean>>> cachedRelationalRequirements = new ConcurrentHashMap<>();
|
||||
// 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 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();
|
||||
private final Vector<String> otherActionBarFeatures = new Vector<>();
|
||||
|
||||
/**
|
||||
* Creates a player instance
|
||||
*
|
||||
* @param plugin CustomNameplates plugin
|
||||
* @param channel netty channel
|
||||
*/
|
||||
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();
|
||||
List<Placeholder> placeholderWithChildren = new ArrayList<>();
|
||||
List<Placeholder> placeholderWithChildren = new ObjectArrayList<>();
|
||||
for (Placeholder placeholder : activePlaceholders) {
|
||||
childrenFirstList(placeholder, placeholderWithChildren);
|
||||
}
|
||||
return placeholderWithChildren.stream().distinct().toList();
|
||||
}
|
||||
|
||||
private String updatePlayerPlaceholder(PlayerPlaceholder placeholder) {
|
||||
TimeStampData<String> value = getRawPlayerValue(placeholder);
|
||||
if (value == null) {
|
||||
value = new TimeStampData<>(placeholder.request(this), MainTask.getTicks(), true);
|
||||
setPlayerValue(placeholder, value);
|
||||
return value.data();
|
||||
}
|
||||
if (value.ticks() != MainTask.getTicks()) {
|
||||
String newValue = placeholder.request(this);
|
||||
value.updateTicks(!value.data().equals(newValue));
|
||||
value.data(newValue);
|
||||
}
|
||||
return value.data();
|
||||
}
|
||||
|
||||
private void updateRelationalPlaceholder(RelationalPlaceholder placeholder, Collection<CNPlayer> others) {
|
||||
for (CNPlayer another : others) {
|
||||
updateRelationalPlaceholder(placeholder, another);
|
||||
}
|
||||
}
|
||||
|
||||
private String updateRelationalPlaceholder(RelationalPlaceholder placeholder, CNPlayer another) {
|
||||
TimeStampData<String> value = getRawRelationalValue(placeholder, another);
|
||||
if (value == null) {
|
||||
value = new TimeStampData<>(placeholder.request(this, another), MainTask.getTicks(), true);
|
||||
setRelationalValue(placeholder, another, value);
|
||||
return value.data();
|
||||
}
|
||||
if (value.ticks() != MainTask.getTicks()) {
|
||||
String newValue = placeholder.request(this, another);
|
||||
value.updateTicks(!value.data().equals(newValue));
|
||||
value.data(newValue);
|
||||
}
|
||||
return value.data();
|
||||
}
|
||||
|
||||
private String updateSharedPlaceholder(SharedPlaceholder placeholder) {
|
||||
TimeStampData<String> value = getRawSharedValue(placeholder);
|
||||
if (value == null) {
|
||||
String latest;
|
||||
if (MainTask.hasRequested(placeholder.countId())) {
|
||||
latest = placeholder.getLatestValue();
|
||||
} else {
|
||||
latest = placeholder.request();
|
||||
}
|
||||
value = new TimeStampData<>(latest, MainTask.getTicks(), true);
|
||||
setSharedValue(placeholder, value);
|
||||
return value.data();
|
||||
}
|
||||
if (value.ticks() != MainTask.getTicks()) {
|
||||
String latest;
|
||||
if (MainTask.hasRequested(placeholder.countId())) {
|
||||
latest = placeholder.getLatestValue();
|
||||
} else {
|
||||
latest = placeholder.request();
|
||||
}
|
||||
value.updateTicks(!value.data().equals(latest));
|
||||
value.data(latest);
|
||||
}
|
||||
return value.data();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forceUpdatePlaceholders(Set<Placeholder> placeholders, Set<CNPlayer> others) {
|
||||
public void forceUpdatePlaceholders(Set<Placeholder> placeholders, Collection<CNPlayer> others) {
|
||||
if (placeholders.isEmpty()) return;
|
||||
List<Placeholder> placeholderWithChildren = new ArrayList<>();
|
||||
List<Placeholder> placeholderWithChildren = new ObjectArrayList<>();
|
||||
for (Placeholder placeholder : placeholders) {
|
||||
childrenFirstList(placeholder, placeholderWithChildren);
|
||||
}
|
||||
placeholderWithChildren = placeholderWithChildren.stream().distinct().toList();
|
||||
for (Placeholder placeholder : placeholderWithChildren) {
|
||||
if (placeholder instanceof PlayerPlaceholder playerPlaceholder) {
|
||||
TimeStampData<String> value = getValue(placeholder);
|
||||
if (value == null) {
|
||||
value = new TimeStampData<>(playerPlaceholder.request(this), MainTask.getTicks(), true);
|
||||
setValue(placeholder, value);
|
||||
continue;
|
||||
}
|
||||
if (value.ticks() != MainTask.getTicks()) {
|
||||
String newValue = playerPlaceholder.request(this);
|
||||
value.updateTicks(!value.data().equals(newValue));
|
||||
value.data(newValue);
|
||||
}
|
||||
} else if (placeholder instanceof RelationalPlaceholder relational) {
|
||||
for (CNPlayer player : others) {
|
||||
TimeStampData<String> value = getRelationalValue(placeholder, player);
|
||||
if (value == null) {
|
||||
value = new TimeStampData<>(relational.request(this, player), MainTask.getTicks(), true);
|
||||
setRelationalValue(placeholder, player, value);
|
||||
continue;
|
||||
}
|
||||
if (value.ticks() != MainTask.getTicks()) {
|
||||
String newValue = relational.request(this, player);
|
||||
value.updateTicks(!value.data().equals(newValue));
|
||||
value.data(newValue);
|
||||
}
|
||||
}
|
||||
updatePlayerPlaceholder(playerPlaceholder);
|
||||
} else if (placeholder instanceof RelationalPlaceholder relationalPlaceholder) {
|
||||
updateRelationalPlaceholder(relationalPlaceholder, others);
|
||||
} else if (placeholder instanceof SharedPlaceholder sharedPlaceholder) {
|
||||
TimeStampData<String> value = getValue(placeholder);
|
||||
if (value == null) {
|
||||
String latest;
|
||||
if (MainTask.hasRequested(sharedPlaceholder.countId())) {
|
||||
latest = sharedPlaceholder.getLatestValue();
|
||||
} else {
|
||||
latest = sharedPlaceholder.request();
|
||||
}
|
||||
value = new TimeStampData<>(latest, MainTask.getTicks(), true);
|
||||
setValue(placeholder, value);
|
||||
continue;
|
||||
}
|
||||
if (value.ticks() != MainTask.getTicks()) {
|
||||
String latest;
|
||||
if (MainTask.hasRequested(sharedPlaceholder.countId())) {
|
||||
latest = sharedPlaceholder.getLatestValue();
|
||||
} else {
|
||||
latest = sharedPlaceholder.request();
|
||||
}
|
||||
value.updateTicks(!value.data().equals(latest));
|
||||
value.data(latest);
|
||||
}
|
||||
updateSharedPlaceholder(sharedPlaceholder);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +225,9 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the player instance, clear caches
|
||||
*/
|
||||
public void reload() {
|
||||
cachedValues.clear();
|
||||
cachedRelationalValues.clear();
|
||||
@@ -172,7 +238,12 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
feature2Placeholders.clear();
|
||||
}
|
||||
|
||||
public void setPlayer(Object player) {
|
||||
/**
|
||||
* Sets the platform player instance on join
|
||||
*
|
||||
* @param player player
|
||||
*/
|
||||
public void setPlayer(P player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@@ -191,10 +262,20 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the player data is loaded
|
||||
*
|
||||
* @param loaded loaded or not
|
||||
*/
|
||||
public void setLoaded(boolean loaded) {
|
||||
isLoaded = loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the player is temporarily previewing the nameplate
|
||||
*
|
||||
* @param previewing is previewing or not
|
||||
*/
|
||||
public void setTempPreviewing(boolean previewing) {
|
||||
this.tempPreviewing = previewing;
|
||||
}
|
||||
@@ -204,6 +285,11 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
return tempPreviewing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the player is using toggle command to preview his nameplate
|
||||
*
|
||||
* @param previewing is previewing or not
|
||||
*/
|
||||
public void setToggleablePreviewing(boolean previewing) {
|
||||
this.toggleablePreviewing = previewing;
|
||||
}
|
||||
@@ -224,7 +310,7 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
Set<Placeholder> allPlaceholders = feature.allPlaceholders();
|
||||
feature2Placeholders.put(feature, allPlaceholders);
|
||||
for (Placeholder placeholder : allPlaceholders) {
|
||||
Set<Feature> featureSet = placeholder2Features.computeIfAbsent(placeholder, k -> new HashSet<>());
|
||||
Set<Feature> featureSet = placeholder2Features.computeIfAbsent(placeholder, k -> new ObjectOpenHashSet<>());
|
||||
featureSet.add(feature);
|
||||
}
|
||||
}
|
||||
@@ -243,84 +329,98 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Placeholder placeholder, TimeStampData<String> value) {
|
||||
public void setPlayerValue(PlayerPlaceholder placeholder, TimeStampData<String> value) {
|
||||
cachedValues.put(placeholder.countId(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setValue(Placeholder placeholder, String value) {
|
||||
TimeStampData<String> previous = cachedValues.get(placeholder.countId());
|
||||
int currentTicks = MainTask.getTicks();
|
||||
boolean changed = false;
|
||||
if (previous != null) {
|
||||
if (previous.ticks() == currentTicks) {
|
||||
return false;
|
||||
}
|
||||
String data = previous.data();
|
||||
if (!data.equals(value)) {
|
||||
changed = true;
|
||||
previous.data(value);
|
||||
previous.updateTicks(true);
|
||||
}
|
||||
} else {
|
||||
changed= true;
|
||||
previous = new TimeStampData<>(value, currentTicks, true);
|
||||
cachedValues.put(placeholder.countId(), previous);
|
||||
}
|
||||
return changed;
|
||||
public void setSharedValue(SharedPlaceholder placeholder, TimeStampData<String> value) {
|
||||
cachedValues.put(placeholder.countId(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRelationalValue(Placeholder placeholder, CNPlayer another, TimeStampData<String> value) {
|
||||
public void setRelationalValue(RelationalPlaceholder placeholder, CNPlayer another, TimeStampData<String> value) {
|
||||
WeakHashMap<CNPlayer, TimeStampData<String>> map = cachedRelationalValues.computeIfAbsent(placeholder.countId(), k -> new WeakHashMap<>());
|
||||
map.put(another, value);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean setPlayerValue(PlayerPlaceholder placeholder, String value) {
|
||||
// TimeStampData<String> previous = cachedValues.get(placeholder.countId());
|
||||
// int currentTicks = MainTask.getTicks();
|
||||
// boolean changed = false;
|
||||
// if (previous != null) {
|
||||
// if (previous.ticks() == currentTicks) {
|
||||
// return false;
|
||||
// }
|
||||
// String data = previous.data();
|
||||
// if (!data.equals(value)) {
|
||||
// changed = true;
|
||||
// previous.data(value);
|
||||
// previous.updateTicks(true);
|
||||
// }
|
||||
// } else {
|
||||
// changed= true;
|
||||
// previous = new TimeStampData<>(value, currentTicks, true);
|
||||
// cachedValues.put(placeholder.countId(), previous);
|
||||
// }
|
||||
// return changed;
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public boolean setRelationalValue(RelationalPlaceholder placeholder, CNPlayer another, String value) {
|
||||
// WeakHashMap<CNPlayer, TimeStampData<String>> map = cachedRelationalValues.computeIfAbsent(placeholder.countId(), k -> new WeakHashMap<>());
|
||||
// TimeStampData<String> previous = map.get(another);
|
||||
// int currentTicks = MainTask.getTicks();
|
||||
// boolean changed = false;
|
||||
// if (previous != null) {
|
||||
// if (previous.ticks() == currentTicks) {
|
||||
// return false;
|
||||
// }
|
||||
// String data = previous.data();
|
||||
// if (!data.equals(value)) {
|
||||
// changed = true;
|
||||
// previous.data(value);
|
||||
// previous.updateTicks(true);
|
||||
// }
|
||||
// } else {
|
||||
// changed= true;
|
||||
// previous = new TimeStampData<>(value, currentTicks, true);
|
||||
// map.put(another, previous);
|
||||
// }
|
||||
// return changed;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean setRelationalValue(Placeholder placeholder, CNPlayer another, String value) {
|
||||
WeakHashMap<CNPlayer, TimeStampData<String>> map = cachedRelationalValues.computeIfAbsent(placeholder.countId(), k -> new WeakHashMap<>());
|
||||
TimeStampData<String> previous = map.get(another);
|
||||
int currentTicks = MainTask.getTicks();
|
||||
boolean changed = false;
|
||||
if (previous != null) {
|
||||
if (previous.ticks() == currentTicks) {
|
||||
return false;
|
||||
}
|
||||
String data = previous.data();
|
||||
if (!data.equals(value)) {
|
||||
changed = true;
|
||||
previous.data(value);
|
||||
previous.updateTicks(true);
|
||||
}
|
||||
} else {
|
||||
changed= true;
|
||||
previous = new TimeStampData<>(value, currentTicks, true);
|
||||
map.put(another, previous);
|
||||
}
|
||||
return changed;
|
||||
public @NotNull String getCachedSharedValue(SharedPlaceholder placeholder) {
|
||||
return updateSharedPlaceholder(placeholder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getData(Placeholder placeholder) {
|
||||
return Optional.ofNullable(cachedValues.get(placeholder.countId())).map(TimeStampData::data).orElse(placeholder.id());
|
||||
public @NotNull String getCachedPlayerValue(PlayerPlaceholder placeholder) {
|
||||
return updatePlayerPlaceholder(placeholder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeStampData<String> getValue(Placeholder placeholder) {
|
||||
public @NotNull String getCachedRelationalValue(RelationalPlaceholder placeholder, CNPlayer another) {
|
||||
return updateRelationalPlaceholder(placeholder, another);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TimeStampData<String> getRawPlayerValue(PlayerPlaceholder placeholder) {
|
||||
return cachedValues.get(placeholder.countId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public @NotNull String getRelationalData(Placeholder placeholder, CNPlayer another) {
|
||||
WeakHashMap<CNPlayer, TimeStampData<String>> map = cachedRelationalValues.get(placeholder.countId());
|
||||
if (map == null) {
|
||||
return placeholder.id();
|
||||
}
|
||||
return Optional.ofNullable(map.get(another)).map(TimeStampData::data).orElse(placeholder.id());
|
||||
public TimeStampData<String> getRawSharedValue(SharedPlaceholder placeholder) {
|
||||
return cachedValues.get(placeholder.countId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TimeStampData<String> getRelationalValue(Placeholder placeholder, CNPlayer another) {
|
||||
public TimeStampData<String> getRawRelationalValue(RelationalPlaceholder placeholder, CNPlayer another) {
|
||||
WeakHashMap<CNPlayer, TimeStampData<String>> map = cachedRelationalValues.get(placeholder.countId());
|
||||
if (map == null) {
|
||||
return null;
|
||||
@@ -330,7 +430,7 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
|
||||
@Override
|
||||
public Placeholder[] activePlaceholders() {
|
||||
HashSet<Placeholder> placeholders = new HashSet<>();
|
||||
Set<Placeholder> placeholders = new ObjectOpenHashSet<>();
|
||||
for (Feature feature : activeFeatures) {
|
||||
placeholders.addAll(feature.activePlaceholders());
|
||||
}
|
||||
@@ -341,14 +441,19 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
public boolean isMet(Requirement[] requirements) {
|
||||
int currentTicks = MainTask.getTicks();
|
||||
for (Requirement requirement : requirements) {
|
||||
TimeStampData<Boolean> data = cachedRequirements.get(requirement);
|
||||
TimeStampData<Boolean> data = cachedRequirements.get(requirement.countId());
|
||||
if (data != null) {
|
||||
if (data.ticks() + requirement.refreshInterval() > currentTicks) {
|
||||
if (!data.data()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
boolean satisfied = requirement.isSatisfied(this, this);
|
||||
boolean satisfied;
|
||||
try {
|
||||
satisfied = requirement.isSatisfied(this, this);
|
||||
} catch (Exception e) {
|
||||
satisfied = false;
|
||||
}
|
||||
data.updateTicks(false);
|
||||
data.data(satisfied);
|
||||
if (!satisfied) {
|
||||
@@ -356,9 +461,14 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolean satisfied = requirement.isSatisfied(this, this);
|
||||
boolean satisfied;
|
||||
try {
|
||||
satisfied = requirement.isSatisfied(this, this);
|
||||
} catch (Exception e) {
|
||||
satisfied = false;
|
||||
}
|
||||
data = new TimeStampData<>(satisfied, currentTicks, true);
|
||||
cachedRequirements.put(requirement, data);
|
||||
cachedRequirements.put(requirement.countId(), data);
|
||||
if (!satisfied) {
|
||||
return false;
|
||||
}
|
||||
@@ -371,7 +481,7 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
public boolean isMet(CNPlayer another, Requirement[] requirements) {
|
||||
int currentTicks = MainTask.getTicks();
|
||||
for (Requirement requirement : requirements) {
|
||||
WeakHashMap<CNPlayer, TimeStampData<Boolean>> innerMap = cachedRelationalRequirements.computeIfAbsent(requirement, k -> new WeakHashMap<>());
|
||||
WeakHashMap<CNPlayer, TimeStampData<Boolean>> innerMap = cachedRelationalRequirements.computeIfAbsent(requirement.countId(), k -> new WeakHashMap<>());
|
||||
TimeStampData<Boolean> data = innerMap.get(another);
|
||||
if (data != null) {
|
||||
if (data.ticks() + requirement.refreshInterval() > currentTicks) {
|
||||
@@ -379,7 +489,12 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
boolean satisfied = requirement.isSatisfied(this, another);
|
||||
boolean satisfied;
|
||||
try {
|
||||
satisfied = requirement.isSatisfied(this, another);
|
||||
} catch (Exception e) {
|
||||
satisfied = false;
|
||||
}
|
||||
data.updateTicks(false);
|
||||
data.data(satisfied);
|
||||
if (!satisfied) {
|
||||
@@ -387,7 +502,12 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolean satisfied = requirement.isSatisfied(this, another);
|
||||
boolean satisfied;
|
||||
try {
|
||||
satisfied = requirement.isSatisfied(this, another);
|
||||
} catch (Exception e) {
|
||||
satisfied = false;
|
||||
}
|
||||
data = new TimeStampData<>(satisfied, currentTicks, true);
|
||||
innerMap.put(another, data);
|
||||
if (!satisfied) {
|
||||
@@ -400,98 +520,158 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
|
||||
@Override
|
||||
public Tracker addPlayerToTracker(CNPlayer another) {
|
||||
Tracker tracker = trackers.get(another);
|
||||
if (tracker != null) {
|
||||
return tracker;
|
||||
}
|
||||
tracker = new Tracker(another);
|
||||
trackers.put(another, tracker);
|
||||
for (Placeholder placeholder : activePlaceholders()) {
|
||||
if (placeholder instanceof RelationalPlaceholder relationalPlaceholder) {
|
||||
String value = relationalPlaceholder.request(this, another);
|
||||
setRelationalValue(placeholder, another, value);
|
||||
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();
|
||||
}
|
||||
return tracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePlayerFromTracker(CNPlayer another) {
|
||||
trackers.remove(another);
|
||||
trackerLock.writeLock().lock();
|
||||
try {
|
||||
trackers.remove(another);
|
||||
} finally {
|
||||
trackerLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CNPlayer> nearbyPlayers() {
|
||||
return new HashSet<>(trackers.keySet());
|
||||
public Collection<CNPlayer> nearbyPlayers() {
|
||||
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 HashSet<>());
|
||||
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
|
||||
public String equippedBubble() {
|
||||
if (equippedNameplate == null) return "none";
|
||||
return equippedBubble;
|
||||
public String currentBubble() {
|
||||
if (currentNameplate == null) return "none";
|
||||
return currentBubble;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equippedBubble(String equippedBubble) {
|
||||
public boolean setCurrentBubble(String bubble) {
|
||||
if (!isLoaded()) return false;
|
||||
if (!equippedBubble.equals(this.equippedBubble)) {
|
||||
this.equippedBubble = equippedBubble;
|
||||
this.currentBubble = bubble;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String bubbleData() {
|
||||
if (bubbleData == null) return "none";
|
||||
return bubbleData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBubbleData(String bubble) {
|
||||
if (!isLoaded()) return false;
|
||||
this.currentBubble = bubble;
|
||||
this.bubbleData = bubble;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String currentNameplate() {
|
||||
if (currentNameplate == null) return "none";
|
||||
return currentNameplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setCurrentNameplate(String nameplate) {
|
||||
if (!isLoaded()) return false;
|
||||
if (!nameplate.equals(this.currentNameplate)) {
|
||||
this.currentNameplate = nameplate;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String equippedNameplate() {
|
||||
if (equippedNameplate == null) return "none";
|
||||
return equippedNameplate;
|
||||
public String nameplateData() {
|
||||
return nameplateData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equippedNameplate(String equippedNameplate) {
|
||||
public boolean setNameplateData(String nameplate) {
|
||||
if (!isLoaded()) return false;
|
||||
if (!equippedNameplate.equals(this.equippedNameplate)) {
|
||||
this.equippedNameplate = equippedNameplate;
|
||||
}
|
||||
this.nameplateData = nameplate;
|
||||
this.currentNameplate = nameplate;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
plugin.getStorageManager().dataSource().updatePlayerData(PlayerData.builder()
|
||||
this.plugin.getStorageManager().dataSource().updatePlayerData(
|
||||
PlayerData.builder()
|
||||
.uuid(uuid())
|
||||
.nameplate(equippedNameplate())
|
||||
.bubble(equippedBubble())
|
||||
.nameplate(nameplateData())
|
||||
.bubble(bubbleData())
|
||||
.previewTags(isToggleablePreviewing())
|
||||
.build(), plugin.getScheduler().async());
|
||||
.build(),
|
||||
this.plugin.getScheduler().async()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -511,4 +691,19 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
public int hashCode() {
|
||||
return entityID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return Optional.ofNullable(this.name).orElse("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID uuid() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int entityID() {
|
||||
return this.entityId;
|
||||
}
|
||||
}
|
||||
@@ -23,15 +23,22 @@ import net.momirealms.customnameplates.api.feature.TimeStampData;
|
||||
import net.momirealms.customnameplates.api.feature.tag.TeamView;
|
||||
import net.momirealms.customnameplates.api.network.Tracker;
|
||||
import net.momirealms.customnameplates.api.placeholder.Placeholder;
|
||||
import net.momirealms.customnameplates.api.placeholder.PlayerPlaceholder;
|
||||
import net.momirealms.customnameplates.api.placeholder.RelationalPlaceholder;
|
||||
import net.momirealms.customnameplates.api.placeholder.SharedPlaceholder;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* CustomNameplates Player
|
||||
*/
|
||||
public interface CNPlayer {
|
||||
|
||||
/**
|
||||
@@ -177,6 +184,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.
|
||||
*
|
||||
@@ -190,7 +218,7 @@ public interface CNPlayer {
|
||||
* @param placeholders the placeholders to update
|
||||
* @param another the players related to the placeholders
|
||||
*/
|
||||
void forceUpdatePlaceholders(Set<Placeholder> placeholders, Set<CNPlayer> another);
|
||||
void forceUpdatePlaceholders(Set<Placeholder> placeholders, Collection<CNPlayer> another);
|
||||
|
||||
/**
|
||||
* Retrieves the cached data for a given placeholder.
|
||||
@@ -199,16 +227,16 @@ public interface CNPlayer {
|
||||
* @return the cached data as a string
|
||||
*/
|
||||
@NotNull
|
||||
String getData(Placeholder placeholder);
|
||||
String getCachedSharedValue(SharedPlaceholder placeholder);
|
||||
|
||||
/**
|
||||
* Retrieves the cached {@link TimeStampData} for a given placeholder.
|
||||
* Retrieves the cached data for a given placeholder.
|
||||
*
|
||||
* @param placeholder the placeholder to retrieve data for
|
||||
* @return the cached TickStampData, or null if none exists
|
||||
* @return the cached data as a string
|
||||
*/
|
||||
@Nullable
|
||||
TimeStampData<String> getValue(Placeholder placeholder);
|
||||
@NotNull
|
||||
String getCachedPlayerValue(PlayerPlaceholder placeholder);
|
||||
|
||||
/**
|
||||
* Retrieves the cached relational data between this player and another for a given placeholder.
|
||||
@@ -218,7 +246,25 @@ public interface CNPlayer {
|
||||
* @return the relational data as a string
|
||||
*/
|
||||
@NotNull
|
||||
String getRelationalData(Placeholder placeholder, CNPlayer another);
|
||||
String getCachedRelationalValue(RelationalPlaceholder placeholder, CNPlayer another);
|
||||
|
||||
/**
|
||||
* Retrieves the cached {@link TimeStampData} for a given placeholder.
|
||||
*
|
||||
* @param placeholder the placeholder to retrieve data for
|
||||
* @return the cached TickStampData, or null if none exists
|
||||
*/
|
||||
@Nullable
|
||||
TimeStampData<String> getRawPlayerValue(PlayerPlaceholder placeholder);
|
||||
|
||||
/**
|
||||
* Retrieves the cached {@link TimeStampData} for a given placeholder.
|
||||
*
|
||||
* @param placeholder the placeholder to retrieve data for
|
||||
* @return the cached TickStampData, or null if none exists
|
||||
*/
|
||||
@Nullable
|
||||
TimeStampData<String> getRawSharedValue(SharedPlaceholder placeholder);
|
||||
|
||||
/**
|
||||
* Retrieves the cached relational {@link TimeStampData} for a given placeholder.
|
||||
@@ -228,7 +274,7 @@ public interface CNPlayer {
|
||||
* @return the cached relational TickStampData, or null if none exists
|
||||
*/
|
||||
@Nullable
|
||||
TimeStampData<String> getRelationalValue(Placeholder placeholder, CNPlayer another);
|
||||
TimeStampData<String> getRawRelationalValue(RelationalPlaceholder placeholder, CNPlayer another);
|
||||
|
||||
/**
|
||||
* Caches the specified {@link TimeStampData} for the given placeholder.
|
||||
@@ -236,16 +282,15 @@ public interface CNPlayer {
|
||||
* @param placeholder the placeholder to cache
|
||||
* @param value the value to cache
|
||||
*/
|
||||
void setValue(Placeholder placeholder, TimeStampData<String> value);
|
||||
void setPlayerValue(PlayerPlaceholder placeholder, TimeStampData<String> value);
|
||||
|
||||
/**
|
||||
* Caches the specified value for the given placeholder.
|
||||
* Caches the specified {@link TimeStampData} for the given placeholder.
|
||||
*
|
||||
* @param placeholder the placeholder to cache
|
||||
* @param value the value to cache
|
||||
* @return true if the value was changed, false otherwise
|
||||
*/
|
||||
boolean setValue(Placeholder placeholder, String value);
|
||||
void setSharedValue(SharedPlaceholder placeholder, TimeStampData<String> value);
|
||||
|
||||
/**
|
||||
* Caches the specified relational {@link TimeStampData} for a given placeholder and player.
|
||||
@@ -254,17 +299,26 @@ public interface CNPlayer {
|
||||
* @param another the other player
|
||||
* @param value the value to cache
|
||||
*/
|
||||
void setRelationalValue(Placeholder placeholder, CNPlayer another, TimeStampData<String> value);
|
||||
void setRelationalValue(RelationalPlaceholder placeholder, CNPlayer another, TimeStampData<String> value);
|
||||
|
||||
/**
|
||||
* Caches the specified relational value for a given placeholder and player.
|
||||
*
|
||||
* @param placeholder the relational placeholder
|
||||
* @param another the other player
|
||||
* @param value the value to cache
|
||||
* @return true if the value was changed, false otherwise
|
||||
*/
|
||||
boolean setRelationalValue(Placeholder placeholder, CNPlayer another, String value);
|
||||
// /**
|
||||
// * Caches the specified value for the given placeholder.
|
||||
// *
|
||||
// * @param placeholder the placeholder to cache
|
||||
// * @param value the value to cache
|
||||
// * @return true if the value was changed, false otherwise
|
||||
// */
|
||||
// boolean setPlayerValue(PlayerPlaceholder placeholder, String value);
|
||||
|
||||
// /**
|
||||
// * Caches the specified relational value for a given placeholder and player.
|
||||
// *
|
||||
// * @param placeholder the relational placeholder
|
||||
// * @param another the other player
|
||||
// * @param value the value to cache
|
||||
// * @return true if the value was changed, false otherwise
|
||||
// */
|
||||
// boolean setRelationalValue(RelationalPlaceholder placeholder, CNPlayer another, String value);
|
||||
|
||||
/**
|
||||
* Adds a feature to the player
|
||||
@@ -317,7 +371,7 @@ public interface CNPlayer {
|
||||
*
|
||||
* @return the set of nearby players
|
||||
*/
|
||||
Set<CNPlayer> nearbyPlayers();
|
||||
Collection<CNPlayer> nearbyPlayers();
|
||||
|
||||
/**
|
||||
* Adds passenger entities to the tracker for another player.
|
||||
@@ -359,36 +413,64 @@ public interface CNPlayer {
|
||||
Tracker getTracker(CNPlayer another);
|
||||
|
||||
/**
|
||||
* Returns the ID of the currently equipped bubble for the player.
|
||||
* Gets the bubble currently in use (Includes temp bubble used in preview)
|
||||
*
|
||||
* @return the ID of the equipped bubble
|
||||
* @return bubble
|
||||
*/
|
||||
String equippedBubble();
|
||||
String currentBubble();
|
||||
|
||||
/**
|
||||
* Sets the equipped bubble for the player.
|
||||
* Operation would fail if player is not loaded.
|
||||
* Sets the bubble currently in use, which would not be saved
|
||||
*
|
||||
* @param equippedBubble the new bubble ID to equip
|
||||
* @return success or not
|
||||
* @param bubble id
|
||||
* @return false if data not loaded
|
||||
*/
|
||||
boolean equippedBubble(String equippedBubble);
|
||||
boolean setCurrentBubble(String bubble);
|
||||
|
||||
/**
|
||||
* Returns the ID of the currently equipped nameplate for the player.
|
||||
* Sets the bubble data
|
||||
*
|
||||
* @return the ID of the equipped nameplate
|
||||
* @param bubble id
|
||||
* @return false if data not loaded
|
||||
*/
|
||||
String equippedNameplate();
|
||||
boolean setBubbleData(String bubble);
|
||||
|
||||
/**
|
||||
* Sets the equipped nameplate for the player.
|
||||
* Operation would fail if player is not loaded.
|
||||
* Gets the bubble data
|
||||
*
|
||||
* @param equippedNameplate the new nameplate ID to equip
|
||||
* @return success or not
|
||||
* @return bubble id
|
||||
*/
|
||||
boolean equippedNameplate(String equippedNameplate);
|
||||
String bubbleData();
|
||||
|
||||
/**
|
||||
* Gets the nameplate currently in use (Includes temp nameplate used in preview)
|
||||
*
|
||||
* @return nameplate
|
||||
*/
|
||||
String currentNameplate();
|
||||
|
||||
/**
|
||||
* Sets the nameplate currently in use, which would not be saved
|
||||
*
|
||||
* @param nameplate id
|
||||
* @return false if data not loaded
|
||||
*/
|
||||
boolean setCurrentNameplate(String nameplate);
|
||||
|
||||
/**
|
||||
* Gets the nameplate data
|
||||
*
|
||||
* @return the nameplate id
|
||||
*/
|
||||
String nameplateData();
|
||||
|
||||
/**
|
||||
* Sets the nameplate data
|
||||
*
|
||||
* @param nameplate id
|
||||
* @return false if data not loaded
|
||||
*/
|
||||
boolean setNameplateData(String nameplate);
|
||||
|
||||
/**
|
||||
* Save the player's current nameplate/bubble to database
|
||||
@@ -401,4 +483,11 @@ public interface CNPlayer {
|
||||
* @return team view
|
||||
*/
|
||||
TeamView teamView();
|
||||
|
||||
/**
|
||||
* Check if the player is initialized
|
||||
*
|
||||
* @return initialized or not
|
||||
*/
|
||||
boolean isInitialized();
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import dev.dejvokep.boostedyaml.utils.format.NodeRole;
|
||||
import net.momirealms.customnameplates.api.feature.CharacterArranger;
|
||||
import net.momirealms.customnameplates.api.feature.bossbar.BossBar;
|
||||
import net.momirealms.customnameplates.api.helper.AdventureHelper;
|
||||
import net.momirealms.customnameplates.api.helper.VersionHelper;
|
||||
import net.momirealms.customnameplates.common.locale.TranslationManager;
|
||||
import net.momirealms.customnameplates.common.plugin.CustomNameplatesProperties;
|
||||
import net.momirealms.customnameplates.common.plugin.config.ConfigLoader;
|
||||
@@ -42,10 +43,27 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Manages the loading and handling of configuration files for the Custom Nameplates plugin.
|
||||
*/
|
||||
public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
|
||||
/**
|
||||
* The main configuration document that stores all settings for the plugin.
|
||||
* <p>
|
||||
* This document is loaded during the initialization of the plugin and is used to retrieve various configuration values.
|
||||
* </p>
|
||||
*/
|
||||
private static YamlDocument MAIN_CONFIG;
|
||||
|
||||
/**
|
||||
* Returns the main configuration document.
|
||||
* <p>
|
||||
* If the configuration has not been loaded yet, an {@code IllegalStateException} will be thrown.
|
||||
* </p>
|
||||
*
|
||||
* @return The main configuration document
|
||||
* @throws IllegalStateException If the configuration has not been loaded
|
||||
*/
|
||||
public static YamlDocument getMainConfig() {
|
||||
if (MAIN_CONFIG == null) {
|
||||
throw new IllegalStateException("Main config not loaded");
|
||||
@@ -53,72 +71,300 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
return MAIN_CONFIG;
|
||||
}
|
||||
|
||||
/**
|
||||
* The singleton instance of the {@code ConfigManager}.
|
||||
*/
|
||||
private static ConfigManager instance;
|
||||
|
||||
/**
|
||||
* The {@code CustomNameplates} plugin instance associated with this {@code ConfigManager}.
|
||||
*/
|
||||
protected final CustomNameplates plugin;
|
||||
|
||||
/**
|
||||
* Indicates whether debugging is enabled.
|
||||
*/
|
||||
protected boolean debug;
|
||||
/**
|
||||
* Indicates whether plugin updates are checked automatically.
|
||||
*/
|
||||
protected boolean checkUpdate;
|
||||
/**
|
||||
* Metrics flag to enable or disable the metrics system.
|
||||
*/
|
||||
protected boolean metrics;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable the nametag module.
|
||||
*/
|
||||
protected boolean nametagModule;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable the action bar module.
|
||||
*/
|
||||
protected boolean actionbarModule;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable the image module.
|
||||
*/
|
||||
protected boolean imageModule;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable the boss bar module.
|
||||
*/
|
||||
protected boolean bossBarModule;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable the bubble module.
|
||||
*/
|
||||
protected boolean bubbleModule;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable the nameplate module.
|
||||
*/
|
||||
protected boolean nameplateModule;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable the background module.
|
||||
*/
|
||||
protected boolean backgroundModule;
|
||||
|
||||
/**
|
||||
* Flag to hide or display team names.
|
||||
*/
|
||||
protected boolean hideTeamNames;
|
||||
|
||||
/**
|
||||
* The default placeholder refresh interval (in seconds).
|
||||
*/
|
||||
protected int defaultPlaceholderRefreshInterval;
|
||||
|
||||
/**
|
||||
* The default condition refresh interval (in seconds).
|
||||
*/
|
||||
protected int defaultConditionRefreshInterval;
|
||||
|
||||
/**
|
||||
* The delay (in milliseconds) before sending updates.
|
||||
*/
|
||||
protected int delaySend;
|
||||
|
||||
/**
|
||||
* Flag to catch other action bar events.
|
||||
*/
|
||||
protected boolean catchOtherActionBar;
|
||||
|
||||
/**
|
||||
* Flag to display system chat messages.
|
||||
*/
|
||||
protected boolean displaySystemChat;
|
||||
|
||||
/**
|
||||
* The duration (in seconds) that other action bars will stay visible.
|
||||
*/
|
||||
protected int otherActionBarStayTime;
|
||||
|
||||
/**
|
||||
* The namespace used for resource identification.
|
||||
*/
|
||||
protected String namespace;
|
||||
|
||||
/**
|
||||
* The font used for rendering text.
|
||||
*/
|
||||
protected String font;
|
||||
|
||||
/**
|
||||
* Flag to generate configurations on plugin start.
|
||||
*/
|
||||
protected boolean generateOnStart;
|
||||
|
||||
/**
|
||||
* The initial character used in text or formatting.
|
||||
*/
|
||||
protected char initialChar;
|
||||
|
||||
/**
|
||||
* The path to the image resource.
|
||||
*/
|
||||
protected String imagePath;
|
||||
|
||||
/**
|
||||
* The path to the nameplate resource.
|
||||
*/
|
||||
protected String nameplatePath;
|
||||
|
||||
/**
|
||||
* The path to the bubble resource.
|
||||
*/
|
||||
protected String bubblePath;
|
||||
|
||||
/**
|
||||
* The path used for splitting space resources.
|
||||
*/
|
||||
protected String spaceSplitPath;
|
||||
|
||||
/**
|
||||
* The path to the background resource.
|
||||
*/
|
||||
protected String backgroundPath;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable shader effects.
|
||||
*/
|
||||
protected boolean enableShader;
|
||||
|
||||
/**
|
||||
* Flag to hide or show scoreboard numbers.
|
||||
*/
|
||||
protected boolean hideScoreBoardNumber;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable animated text.
|
||||
*/
|
||||
protected boolean animatedText;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable the ItemsAdder effect.
|
||||
*/
|
||||
protected boolean itemsAdderEffect;
|
||||
|
||||
/**
|
||||
* The color used for the boss bar when removed.
|
||||
*/
|
||||
protected BossBar.Color removedBarColor;
|
||||
|
||||
/**
|
||||
* Flag to enable compatibility for version 1.20.2 of Minecraft.
|
||||
*/
|
||||
protected boolean bossBar1_20_2;
|
||||
|
||||
/**
|
||||
* Flag to enable compatibility for version 1.17 of Minecraft.
|
||||
*/
|
||||
protected boolean bossBar1_17;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable legacy Unicode support.
|
||||
*/
|
||||
protected boolean legacyUnicodes;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable ItemsAdder pack.
|
||||
*/
|
||||
protected boolean packItemsAdder;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable legacy ItemsAdder pack.
|
||||
*/
|
||||
protected boolean packItemsAdderLegacy;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable Oraxen pack.
|
||||
*/
|
||||
protected boolean packOraxen;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable Nexo pack.
|
||||
*/
|
||||
protected boolean packNexo;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable Creative Central pack.
|
||||
*/
|
||||
protected boolean packCreativeCentral;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable CraftEngine pack.
|
||||
*/
|
||||
protected boolean packCraftEngine;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable unsafe chat features.
|
||||
*/
|
||||
protected boolean chatUnsafe;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable chat features for TR (text roleplay).
|
||||
*/
|
||||
protected boolean chatTR;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable chat features for Venture.
|
||||
*/
|
||||
protected boolean chatVenture;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable chat features for Husk.
|
||||
*/
|
||||
protected boolean chatHusk;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable chat features for Carbon.
|
||||
*/
|
||||
protected boolean chatCarbon;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable chat features for Advanced.
|
||||
*/
|
||||
protected boolean chatAdvanced;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable chat features for Essentials.
|
||||
*/
|
||||
protected boolean chatEss;
|
||||
|
||||
protected String configVersion;
|
||||
/**
|
||||
* Flag to enable or disable chat features for ChatControlRed.
|
||||
*/
|
||||
protected boolean chatChatControlRed;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable chat features for Chatty.
|
||||
*/
|
||||
protected boolean chatChatty;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable chat features for Zel.
|
||||
*/
|
||||
protected boolean chatZel;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable dialogue features for TW (text world).
|
||||
*/
|
||||
protected boolean twDialogue;
|
||||
|
||||
/**
|
||||
* Flag to enable or disable cinematic features for TW (text world).
|
||||
*/
|
||||
protected boolean twCinematic;
|
||||
|
||||
/**
|
||||
* The version of the current configuration.
|
||||
*/
|
||||
protected String configVersion;
|
||||
protected int forceUpdatePassengerInterval;
|
||||
protected float minPackVersion;
|
||||
protected boolean stripChatColorTags;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ConfigManager} for the specified {@code CustomNameplates} plugin instance.
|
||||
*
|
||||
* @param plugin The {@code CustomNameplates} plugin instance
|
||||
*/
|
||||
public ConfigManager(CustomNameplates plugin) {
|
||||
this.plugin = plugin;
|
||||
instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration file from the specified path and initializes various settings.
|
||||
* <p>
|
||||
* This method reads the {@code config.yml} file and sets up all configuration options such as modules,
|
||||
* integrations, and resource packs. It also handles versioning and saves the loaded configuration back
|
||||
* to the file system.
|
||||
* </p>
|
||||
*
|
||||
* @throws RuntimeException If an error occurs while loading or saving the configuration
|
||||
*/
|
||||
@Override
|
||||
public void load() {
|
||||
configVersion = CustomNameplatesProperties.getValue("config");
|
||||
@@ -156,6 +402,13 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the settings from the configuration document into various fields.
|
||||
* <p>
|
||||
* This method parses the {@code MAIN_CONFIG} document and assigns values to the class fields.
|
||||
* It also applies settings such as locale and legacy support.
|
||||
* </p>
|
||||
*/
|
||||
private void loadSettings() {
|
||||
YamlDocument config = MAIN_CONFIG;
|
||||
AdventureHelper.legacySupport = config.getBoolean("other-settings.legacy-color-code-support", true);
|
||||
@@ -181,6 +434,8 @@ 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");
|
||||
packCraftEngine = false;
|
||||
|
||||
chatUnsafe = config.getBoolean("other-settings.unsafe-chat-event", false);
|
||||
chatEss = config.getBoolean("integrations.chat.Essentials", false);
|
||||
@@ -189,6 +444,12 @@ 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);
|
||||
chatZel = config.getBoolean("integrations.chat.ZelChat", 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);
|
||||
@@ -214,14 +475,18 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
|
||||
legacyUnicodes = config.getBoolean("resource-pack.legacy-unicodes", true);
|
||||
|
||||
minPackVersion = getVersion(config.getString("resource-pack.supported-version.min", "SERVER_VERSION"));
|
||||
|
||||
// Other settings
|
||||
delaySend = config.getInt("other-settings.send-delay", 0);
|
||||
defaultPlaceholderRefreshInterval = config.getInt("other-settings.default-placeholder-refresh-interval", 1);
|
||||
defaultConditionRefreshInterval = config.getInt("other-settings.ddefault-condition-refresh-interval", 1);
|
||||
defaultConditionRefreshInterval = config.getInt("other-settings.default-condition-refresh-interval", 20);
|
||||
catchOtherActionBar = config.getBoolean("other-settings.catch-other-plugin-actionbar", true);
|
||||
otherActionBarStayTime = config.getInt("other-settings.other-actionbar-stay-time", 3000);
|
||||
displaySystemChat = config.getBoolean("other-settings.display-system-actionbar", true);
|
||||
hideTeamNames = config.getBoolean("other-settings.hide-team-names", true);
|
||||
stripChatColorTags = config.getBoolean("other-settings.strip-chat-color-tags", false);
|
||||
forceUpdatePassengerInterval = config.getInt("other-settings.force-update-passenger-interval", -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -229,193 +494,471 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
Reloadable.super.unload();
|
||||
}
|
||||
|
||||
private static float getVersion(String version) {
|
||||
if (version.equalsIgnoreCase("SERVER_VERSION")) {
|
||||
return VersionHelper.version();
|
||||
}
|
||||
String[] split = version.split("\\.", 2);
|
||||
if (split.length != 2) {
|
||||
throw new IllegalArgumentException("Invalid version: " + version);
|
||||
}
|
||||
return Float.parseFloat(split[1]);
|
||||
}
|
||||
|
||||
public static float minPackVersion() {
|
||||
return instance.minPackVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the delay before sending updates.
|
||||
* @return the delay time (in milliseconds).
|
||||
*/
|
||||
public static int delaySend() {
|
||||
return instance.delaySend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the path used for splitting space resources.
|
||||
* @return the space split path.
|
||||
*/
|
||||
public static String spaceSplitPath() {
|
||||
return instance.spaceSplitPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the path to the bubble resource.
|
||||
* @return the bubble path.
|
||||
*/
|
||||
public static String bubblePath() {
|
||||
return instance.bubblePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the path to the image resource.
|
||||
* @return the image path.
|
||||
*/
|
||||
public static String imagePath() {
|
||||
return instance.imagePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the path to the background resource.
|
||||
* @return the background path.
|
||||
*/
|
||||
public static String backgroundPath() {
|
||||
return instance.backgroundPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the path to the nameplate resource.
|
||||
* @return the nameplate path.
|
||||
*/
|
||||
public static String nameplatePath() {
|
||||
return instance.nameplatePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether configuration generation is enabled on startup.
|
||||
* @return true if configuration generation is enabled on start; false otherwise.
|
||||
*/
|
||||
public static boolean generateOnStart() {
|
||||
return instance.generateOnStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the namespace used for resource identification.
|
||||
* @return the namespace.
|
||||
*/
|
||||
public static String namespace() {
|
||||
return instance.namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the font used for rendering text.
|
||||
* @return the font.
|
||||
*/
|
||||
public static String font() {
|
||||
return instance.font;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the version of the current configuration.
|
||||
* @return the config version.
|
||||
*/
|
||||
public static String configVersion() {
|
||||
return instance.configVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the initial character used for formatting.
|
||||
* @return the initial character.
|
||||
*/
|
||||
public static char initialChar() {
|
||||
return instance.initialChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether team names are hidden.
|
||||
* @return true if team names are hidden; false otherwise.
|
||||
*/
|
||||
public static boolean hideTeamNames() {
|
||||
return instance.hideTeamNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the action bar module is enabled.
|
||||
* @return true if the action bar module is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean actionbarModule() {
|
||||
return instance.actionbarModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the nametag module is enabled.
|
||||
* @return true if the nametag module is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean nametagModule() {
|
||||
return instance.nametagModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether other action bars should be caught.
|
||||
* @return true if other action bars are caught; false otherwise.
|
||||
*/
|
||||
public static boolean catchOtherActionBar() {
|
||||
return instance.catchOtherActionBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether system chat should be displayed.
|
||||
* @return true if system chat is displayed; false otherwise.
|
||||
*/
|
||||
public static boolean displaySystemChat() {
|
||||
return instance.displaySystemChat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the ItemsAdder pack is enabled.
|
||||
* @return true if the ItemsAdder pack is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean packItemsAdder() {
|
||||
return instance.packItemsAdder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the legacy ItemsAdder pack is enabled.
|
||||
* @return true if the legacy ItemsAdder pack is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean packItemsAdderLegacy() {
|
||||
return instance.packItemsAdderLegacy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the Oraxen pack is enabled.
|
||||
* @return true if the Oraxen pack is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean packOraxen() {
|
||||
return instance.packOraxen;
|
||||
}
|
||||
|
||||
public static boolean packCreativeCentral() { return instance.packCreativeCentral; }
|
||||
/**
|
||||
* Retrieves whether the Nexo pack is enabled.
|
||||
* @return true if the Nexo pack is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean packNexo() {
|
||||
return instance.packNexo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the CraftEngine pack is enabled.
|
||||
* @return true if the CraftEngine pack is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean packCraftEngine() {
|
||||
return instance.packCraftEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the Creative Central pack is enabled.
|
||||
* @return true if the Creative Central pack is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean packCreativeCentral() {
|
||||
return instance.packCreativeCentral;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the scoreboard numbers should be hidden.
|
||||
* @return true if scoreboard numbers are hidden; false otherwise.
|
||||
*/
|
||||
public static boolean hideScoreBoardNumber() {
|
||||
return instance.hideScoreBoardNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether animated text is enabled.
|
||||
* @return true if animated text is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean animatedText() {
|
||||
return instance.animatedText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the ItemsAdder effect is enabled.
|
||||
* @return true if the ItemsAdder effect is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean itemsAdderEffect() {
|
||||
return instance.itemsAdderEffect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the color to be used for a removed boss bar.
|
||||
* @return the color for the removed bar.
|
||||
*/
|
||||
public static BossBar.Color removedBarColor() {
|
||||
return instance.removedBarColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the image module is enabled.
|
||||
* @return true if the image module is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean imageModule() {
|
||||
return instance.imageModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the boss bar module is enabled.
|
||||
* @return true if the boss bar module is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean bossbarModule() {
|
||||
return instance.bossBarModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the bubble module is enabled.
|
||||
* @return true if the bubble module is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean bubbleModule() {
|
||||
return instance.bubbleModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the background module is enabled.
|
||||
* @return true if the background module is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean backgroundModule() {
|
||||
return instance.backgroundModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the nameplate module is enabled.
|
||||
* @return true if the nameplate module is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean nameplateModule() {
|
||||
return instance.nameplateModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether debugging is enabled.
|
||||
* @return true if debugging is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean debug() {
|
||||
return instance.debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the plugin checks for updates.
|
||||
* @return true if update checks are enabled; false otherwise.
|
||||
*/
|
||||
public static boolean checkUpdate() {
|
||||
return instance.checkUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether the metrics system is enabled.
|
||||
* @return true if the metrics system is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean metrics() {
|
||||
return instance.metrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether dialogue features for text world (TW) are enabled.
|
||||
* @return true if TW dialogue is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean twDialogue() {
|
||||
return instance.twDialogue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether cinematic features for text world (TW) are enabled.
|
||||
* @return true if TW cinematic is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean twCinematic() {
|
||||
return instance.twCinematic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default placeholder refresh interval (in seconds).
|
||||
* @return the default placeholder refresh interval.
|
||||
*/
|
||||
public static int defaultPlaceholderRefreshInterval() {
|
||||
return instance.defaultPlaceholderRefreshInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default condition refresh interval (in seconds).
|
||||
* @return the default condition refresh interval.
|
||||
*/
|
||||
public static int defaultConditionRefreshInterval() {
|
||||
return instance.defaultConditionRefreshInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the duration (in seconds) that other action bars will stay visible.
|
||||
* @return the duration for other action bars to stay visible.
|
||||
*/
|
||||
public static int otherActionBarStayTime() {
|
||||
return instance.otherActionBarStayTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether shader effects are enabled.
|
||||
* @return true if shader effects are enabled; false otherwise.
|
||||
*/
|
||||
public static boolean enableShader() {
|
||||
return instance.enableShader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether legacy Unicode support is enabled.
|
||||
* @return true if legacy Unicode support is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean legacyUnicodes() {
|
||||
return instance.legacyUnicodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether compatibility with Minecraft 1.20.2 is enabled for the boss bar.
|
||||
* @return true if the boss bar is compatible with Minecraft 1.20.2; false otherwise.
|
||||
*/
|
||||
public static boolean bossBar1_20_2() {
|
||||
return instance.bossBar1_20_2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether compatibility with Minecraft 1.17 is enabled for the boss bar.
|
||||
* @return true if the boss bar is compatible with Minecraft 1.17; false otherwise.
|
||||
*/
|
||||
public static boolean bossBar1_17() {
|
||||
return instance.bossBar1_17;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether unsafe chat features are enabled.
|
||||
* @return true if unsafe chat is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean chatUnsafe() {
|
||||
return instance.chatUnsafe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether TrChat features are enabled.
|
||||
* @return true if TR chat is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean chatTrChat() {
|
||||
return instance.chatTR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether VentureChat features are enabled.
|
||||
* @return true if Venture chat is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean chatVenture() {
|
||||
return instance.chatVenture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether HuskChat features are enabled.
|
||||
* @return true if Husk chat is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean chatHusk() {
|
||||
return instance.chatHusk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether Essentials chat features are enabled.
|
||||
* @return true if Essentials chat is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean chatEss() {
|
||||
return instance.chatEss;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether CarbonChat features are enabled.
|
||||
* @return true if Carbon chat is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean chatCarbon() {
|
||||
return instance.chatCarbon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether AdvancedChat features are enabled.
|
||||
* @return true if Advanced chat is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean chatAdvanced() {
|
||||
return instance.chatAdvanced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether RedChatControl is enabled.
|
||||
* @return true if Red chat control is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean chatChatControlRed() {
|
||||
return instance.chatChatControlRed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether Chatty chat features are enabled.
|
||||
* @return true if Chatty chat is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean chatChatty() {
|
||||
return instance.chatChatty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether ZelChat chat features are enabled.
|
||||
* @return true if ZelChat chat is enabled; false otherwise.
|
||||
*/
|
||||
public static boolean chatZel() {
|
||||
return instance.chatZel;
|
||||
}
|
||||
|
||||
public static boolean stripChatColorTags() {
|
||||
return instance.stripChatColorTags;
|
||||
}
|
||||
|
||||
public static int forceUpdatePassengerInterval() {
|
||||
return instance.forceUpdatePassengerInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration file at the specified path with a custom route separator.
|
||||
*
|
||||
* @param filePath The path to the configuration file
|
||||
* @return The {@code YamlDocument} representing the loaded configuration
|
||||
*/
|
||||
@Override
|
||||
public YamlDocument loadConfig(String filePath) {
|
||||
return loadConfig(filePath, '.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration file at the specified path with a custom route separator.
|
||||
*
|
||||
* @param filePath The path to the configuration file
|
||||
* @param routeSeparator The character used to separate route segments in the YAML file
|
||||
* @return The {@code YamlDocument} representing the loaded configuration
|
||||
*/
|
||||
@Override
|
||||
public YamlDocument loadConfig(String filePath, char routeSeparator) {
|
||||
try (InputStream inputStream = new FileInputStream(resolveConfig(filePath).toFile())) {
|
||||
@@ -447,6 +990,17 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration file from the specified file path.
|
||||
*
|
||||
* @param filePath the relative or absolute path to the configuration file.
|
||||
* @param generalSettings settings for general YAML loading behavior.
|
||||
* @param loaderSettings settings for YAML loader behavior.
|
||||
* @param dumperSettings settings for YAML dumping behavior.
|
||||
* @param updaterSettings settings for YAML updating behavior.
|
||||
* @return a {@link YamlDocument} containing the loaded YAML content.
|
||||
* @throws RuntimeException if the configuration file could not be loaded or an error occurs.
|
||||
*/
|
||||
@Override
|
||||
public YamlDocument loadConfig(String filePath, GeneralSettings generalSettings, LoaderSettings loaderSettings, DumperSettings dumperSettings, UpdaterSettings updaterSettings) {
|
||||
try (InputStream inputStream = new FileInputStream(resolveConfig(filePath).toFile())) {
|
||||
@@ -464,6 +1018,13 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the YAML data from the specified file.
|
||||
*
|
||||
* @param file the file containing the YAML data.
|
||||
* @return a {@link YamlDocument} containing the loaded YAML data.
|
||||
* @throws RuntimeException if the data file could not be loaded or an error occurs.
|
||||
*/
|
||||
@Override
|
||||
public YamlDocument loadData(File file) {
|
||||
try (InputStream inputStream = new FileInputStream(file)) {
|
||||
@@ -474,6 +1035,15 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the configuration file path and ensures the file exists.
|
||||
* If the configuration file does not exist, it is created from an embedded resource.
|
||||
*
|
||||
* @param filePath the relative or absolute path to the configuration file.
|
||||
* @return the resolved {@link Path} to the configuration file.
|
||||
* @throws IllegalArgumentException if the filePath is null or empty, or if the embedded resource cannot be found.
|
||||
* @throws RuntimeException if an error occurs during file creation or copying.
|
||||
*/
|
||||
public Path resolveConfig(String filePath) {
|
||||
if (filePath == null || filePath.isEmpty()) {
|
||||
throw new IllegalArgumentException("ResourcePath cannot be null or empty");
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package net.momirealms.customnameplates.api;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.momirealms.customnameplates.api.feature.actionbar.ActionBarManager;
|
||||
import net.momirealms.customnameplates.api.feature.advance.AdvanceManager;
|
||||
import net.momirealms.customnameplates.api.feature.background.BackgroundManager;
|
||||
@@ -27,6 +28,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;
|
||||
@@ -37,10 +39,11 @@ import net.momirealms.customnameplates.common.event.EventManager;
|
||||
import net.momirealms.customnameplates.common.locale.TranslationManager;
|
||||
import net.momirealms.customnameplates.common.plugin.NameplatesPlugin;
|
||||
import net.momirealms.customnameplates.common.plugin.scheduler.SchedulerTask;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
@@ -51,36 +54,149 @@ import java.util.function.Supplier;
|
||||
* Provides access to managers for various features.
|
||||
*/
|
||||
public abstract class CustomNameplates implements NameplatesPlugin {
|
||||
|
||||
private static CustomNameplates instance;
|
||||
|
||||
/**
|
||||
* Manages the dependencies required by the plugin or system.
|
||||
*/
|
||||
protected DependencyManager dependencyManager;
|
||||
|
||||
/**
|
||||
* Handles translations for the plugin, ensuring text is localized based on the player's language.
|
||||
*/
|
||||
protected TranslationManager translationManager;
|
||||
|
||||
/**
|
||||
* A debugger function that logs debug information with a "[DEBUG]" prefix.
|
||||
* It consumes a supplier of strings and logs the result.
|
||||
*/
|
||||
protected Consumer<Supplier<String>> debugger = (s) -> getPluginLogger().info("[DEBUG] " + s.get());
|
||||
|
||||
/**
|
||||
* Manages configuration settings, loading and accessing configuration data for the plugin.
|
||||
*/
|
||||
protected ConfigManager configManager;
|
||||
|
||||
/**
|
||||
* Responsible for sending packets to clients or other network entities.
|
||||
*/
|
||||
protected PacketSender packetSender;
|
||||
|
||||
/**
|
||||
* Injects custom pipelines into the system to modify or handle data processing flows.
|
||||
*/
|
||||
protected PipelineInjector pipelineInjector;
|
||||
|
||||
/**
|
||||
* Manages placeholders used for dynamic text replacements in the plugin's output.
|
||||
*/
|
||||
protected PlaceholderManager placeholderManager;
|
||||
|
||||
/**
|
||||
* Manages requirements or conditions that must be met for certain actions or events to occur.
|
||||
*/
|
||||
protected RequirementManager requirementManager;
|
||||
|
||||
/**
|
||||
* Manages the action bar, responsible for displaying dynamic text to players in the action bar.
|
||||
*/
|
||||
protected ActionBarManager actionBarManager;
|
||||
|
||||
/**
|
||||
* Manages the boss bar, which displays a customizable progress bar and messages to players.
|
||||
*/
|
||||
protected BossBarManager bossBarManager;
|
||||
|
||||
/**
|
||||
* Manages unlimited tags that can be applied to players, items, or other entities.
|
||||
*/
|
||||
protected UnlimitedTagManager unlimitedTagManager;
|
||||
|
||||
/**
|
||||
* Represents the platform on which the plugin or system is running (e.g., Spigot, Bukkit, etc.).
|
||||
*/
|
||||
protected Platform platform;
|
||||
|
||||
/**
|
||||
* The main task or process that the plugin or system executes.
|
||||
*/
|
||||
protected MainTask mainTask;
|
||||
|
||||
/**
|
||||
* A scheduled task that runs alongside the main task, typically used for periodic or delayed actions.
|
||||
*/
|
||||
protected SchedulerTask scheduledMainTask;
|
||||
protected ConcurrentHashMap<UUID, CNPlayer> onlinePlayerMap = new ConcurrentHashMap<>();
|
||||
protected HashMap<Integer, CNPlayer> entityIDFastLookup = new HashMap<>();
|
||||
|
||||
/**
|
||||
* A map that tracks online players by their unique UUID, allowing quick access to player data.
|
||||
*/
|
||||
protected Map<UUID, CNPlayer> onlinePlayerMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* A fast lookup map that associates entity IDs to player data (CNPlayer) for quick access.
|
||||
*/
|
||||
protected Map<Integer, CNPlayer> entityIDFastLookup = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Manages advances or progressions for players, such as achievements or level ups.
|
||||
*/
|
||||
protected AdvanceManager advanceManager;
|
||||
|
||||
/**
|
||||
* Manages background tasks, likely for asynchronous processing or UI updates.
|
||||
*/
|
||||
protected BackgroundManager backgroundManager;
|
||||
|
||||
/**
|
||||
* Manages events and event handling within the plugin or system.
|
||||
*/
|
||||
protected EventManager eventManager;
|
||||
|
||||
/**
|
||||
* Manages the plugin's data storage system, including saving and retrieving player data.
|
||||
*/
|
||||
protected StorageManager storageManager;
|
||||
|
||||
/**
|
||||
* Manages bubble effects, likely for UI or visual effects displayed to players.
|
||||
*/
|
||||
protected BubbleManager bubbleManager;
|
||||
|
||||
/**
|
||||
* Manages chat functionality, including message formatting, commands, and interactions.
|
||||
*/
|
||||
protected ChatManager chatManager;
|
||||
|
||||
/**
|
||||
* Manages images, such as textures or images for resource packs or player displays.
|
||||
*/
|
||||
protected ImageManager imageManager;
|
||||
|
||||
/**
|
||||
* Manages nameplates displayed above players or entities.
|
||||
*/
|
||||
protected NameplateManager nameplateManager;
|
||||
|
||||
/**
|
||||
* Manages resource packs, allowing the plugin to send custom content to players.
|
||||
*/
|
||||
protected ResourcePackManager resourcePackManager;
|
||||
|
||||
/**
|
||||
* Provides an API for external access to the plugin's functionality and data.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* Creates the CustomNameplates instance
|
||||
*/
|
||||
protected CustomNameplates() {
|
||||
instance = this;
|
||||
}
|
||||
@@ -97,6 +213,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.
|
||||
*
|
||||
@@ -288,7 +434,7 @@ public abstract class CustomNameplates implements NameplatesPlugin {
|
||||
* @return a collection of {@link CNPlayer} instances
|
||||
*/
|
||||
public Collection<CNPlayer> getOnlinePlayers() {
|
||||
return new HashSet<>(onlinePlayerMap.values());
|
||||
return new ObjectArrayList<>(onlinePlayerMap.values());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,4 +465,16 @@ public abstract class CustomNameplates implements NameplatesPlugin {
|
||||
public static CustomNameplates getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public void addPlayerUnsafe(int entityId, CNPlayer player) {
|
||||
if (this.entityIDFastLookup.containsKey(entityId)) return;
|
||||
this.entityIDFastLookup.put(entityId, player);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ApiStatus.Experimental
|
||||
public CNPlayer removePlayerUnsafe(int entityId) {
|
||||
return this.entityIDFastLookup.remove(entityId);
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* CustomNameplatesAPI
|
||||
*/
|
||||
public record CustomNameplatesAPI(CustomNameplates plugin) {
|
||||
|
||||
private static CustomNameplatesAPI instance;
|
||||
|
||||
public CustomNameplatesAPI(CustomNameplates plugin) {
|
||||
@@ -108,7 +110,7 @@ public record CustomNameplatesAPI(CustomNameplates plugin) {
|
||||
text = AdventureHelper.legacyToMiniMessage(text);
|
||||
}
|
||||
float advance = plugin.getAdvanceManager().getLineAdvance(text);
|
||||
return adaptiveImage.createImagePrefix(advance, leftMargin, rightMargin) + text + adaptiveImage.createImageSuffix(advance, leftMargin, rightMargin);
|
||||
return AdventureHelper.surroundWithNameplatesFont(adaptiveImage.createImagePrefix(advance, leftMargin, rightMargin)) + text + AdventureHelper.surroundWithNameplatesFont(adaptiveImage.createImageSuffix(advance, leftMargin, rightMargin));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
package net.momirealms.customnameplates.api;
|
||||
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DummyPlayer extends AbstractCNPlayer<Object> {
|
||||
private final CNPlayer target;
|
||||
private final int megEntityId;
|
||||
private final Vector3 position;
|
||||
|
||||
public DummyPlayer(CustomNameplates plugin, CNPlayer delegate, int entityId, Vector3 location) {
|
||||
super(plugin, delegate.channel());
|
||||
this.target = delegate;
|
||||
this.megEntityId = entityId;
|
||||
this.position = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int entityID() {
|
||||
return this.megEntityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
return this.target.hasPermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3 position() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String world() {
|
||||
return this.target.world();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnline() {
|
||||
return this.target.isOnline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpectator() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double scale() {
|
||||
return this.target.scale();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCrouching() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long playerTime() {
|
||||
return this.target.playerTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlying() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remainingAir() {
|
||||
return this.target.remainingAir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> passengers() {
|
||||
return Set.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return this.target.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID uuid() {
|
||||
return this.target.uuid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object player() {
|
||||
return this.target.player();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String currentNameplate() {
|
||||
return this.target.currentNameplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String currentBubble() {
|
||||
return this.target.currentBubble();
|
||||
}
|
||||
}
|
||||
@@ -17,62 +17,97 @@
|
||||
|
||||
package net.momirealms.customnameplates.api;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* MainTask is a periodic task that handles various operations related to the plugin, such as refreshing conditions,
|
||||
* managing placeholders, and monitoring performance. It runs periodically and executes different plugin managers
|
||||
* in each cycle to maintain the smooth operation of the system.
|
||||
*/
|
||||
public class MainTask implements Runnable {
|
||||
|
||||
private static int RUN_TICKS = 0;
|
||||
|
||||
private static final Map<Integer, Integer> TIME_1 = new ConcurrentHashMap<>(2048);
|
||||
private static final Map<Integer, Integer> TIME_2 = new ConcurrentHashMap<>(2048);
|
||||
private static final Set<Integer> requestedSharedPlaceholders = Collections.synchronizedSet(new HashSet<>());
|
||||
private static final Set<Integer> requestedSharedPlaceholders = Collections.synchronizedSet(new ObjectOpenHashSet<>());
|
||||
private int timer;
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
private boolean state;
|
||||
|
||||
/**
|
||||
* Constructs a new MainTask instance.
|
||||
*
|
||||
* @param plugin the plugin instance associated with this task
|
||||
*/
|
||||
public MainTask(CustomNameplates plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of ticks the task has executed.
|
||||
*
|
||||
* @return the number of ticks
|
||||
*/
|
||||
public static int getTicks() {
|
||||
return RUN_TICKS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a shared placeholder request for the specified count ID has already been made.
|
||||
*
|
||||
* @param countId the ID to check
|
||||
* @return true if the request has been made, false otherwise
|
||||
*/
|
||||
public static boolean hasRequested(int countId) {
|
||||
return !requestedSharedPlaceholders.add(countId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the tick counter to 0.
|
||||
*/
|
||||
public static void reset() {
|
||||
RUN_TICKS = 0;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the performance profile of the task based on the execution time and load.
|
||||
*
|
||||
* @return a HealthyProfile object containing the performance statistics
|
||||
*/
|
||||
public static HealthyProfile getHealthyProfile() {
|
||||
long total1 = TIME_1.values().stream().mapToLong(Integer::longValue).sum();
|
||||
long total2 = TIME_2.values().stream().mapToLong(Integer::longValue).sum();
|
||||
@@ -90,14 +125,23 @@ public class MainTask implements Runnable {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the health profile of the task, including performance metrics such as load and execution times.
|
||||
*/
|
||||
public static class HealthyProfile {
|
||||
|
||||
private final double load;
|
||||
private final long totalTimeNS;
|
||||
|
||||
private final int actionBarConditionNS;
|
||||
private final int refreshPlaceholderNS;
|
||||
|
||||
/**
|
||||
* Constructs a new HealthyProfile instance with the provided metrics.
|
||||
*
|
||||
* @param load the load factor based on execution time
|
||||
* @param totalTimeNS the total time spent on the task, in nanoseconds
|
||||
* @param actionBarConditionNS the average time spent on action bar conditions, in nanoseconds
|
||||
* @param refreshPlaceholderNS the average time spent refreshing placeholders, in nanoseconds
|
||||
*/
|
||||
public HealthyProfile(
|
||||
double load,
|
||||
long totalTimeNS,
|
||||
@@ -110,18 +154,38 @@ public class MainTask implements Runnable {
|
||||
this.totalTimeNS = totalTimeNS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the average time spent on action bar condition checks, in nanoseconds.
|
||||
*
|
||||
* @return the action bar condition time in nanoseconds
|
||||
*/
|
||||
public int getActionBarConditionNS() {
|
||||
return actionBarConditionNS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the average time spent refreshing placeholders, in nanoseconds.
|
||||
*
|
||||
* @return the placeholder refresh time in nanoseconds
|
||||
*/
|
||||
public int getRefreshPlaceholderNS() {
|
||||
return refreshPlaceholderNS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the load factor based on the task's execution time.
|
||||
*
|
||||
* @return the load factor
|
||||
*/
|
||||
public double getLoad() {
|
||||
return load;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total time spent on the task, in nanoseconds.
|
||||
*
|
||||
* @return the total execution time in nanoseconds
|
||||
*/
|
||||
public long getTotalTimeNS() {
|
||||
return totalTimeNS;
|
||||
}
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
package net.momirealms.customnameplates.api;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.bossbar.BossBar;
|
||||
import net.momirealms.customnameplates.api.feature.tag.NameTagConfig;
|
||||
import net.momirealms.customnameplates.api.network.PacketEvent;
|
||||
import net.momirealms.customnameplates.api.placeholder.Placeholder;
|
||||
import net.momirealms.customnameplates.api.util.Alignment;
|
||||
import net.momirealms.customnameplates.api.util.Billboard;
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
|
||||
import java.util.List;
|
||||
@@ -114,29 +116,30 @@ public interface Platform {
|
||||
/**
|
||||
* Creates packets to display text on a custom text display entity.
|
||||
*
|
||||
* @param entityID the entity ID
|
||||
* @param uuid the entity UUID
|
||||
* @param position the position of the text
|
||||
* @param pitch the pitch of the entity
|
||||
* @param yaw the yaw of the entity
|
||||
* @param headYaw the head yaw of the entity
|
||||
* @param interpolationDelay the interpolation delay
|
||||
* @param transformationInterpolationDuration the transformation interpolation duration
|
||||
* @param entityID the entity ID
|
||||
* @param uuid the entity UUID
|
||||
* @param position the position of the text
|
||||
* @param pitch the pitch of the entity
|
||||
* @param yaw the yaw of the entity
|
||||
* @param headYaw the head yaw of the entity
|
||||
* @param interpolationDelay the interpolation delay
|
||||
* @param transformationInterpolationDuration the transformation interpolation duration
|
||||
* @param positionRotationInterpolationDuration the position and rotation interpolation duration
|
||||
* @param component the component containing the text
|
||||
* @param backgroundColor the background color
|
||||
* @param opacity the opacity of the text
|
||||
* @param hasShadow whether the text has a shadow
|
||||
* @param isSeeThrough whether the text is see-through
|
||||
* @param useDefaultBackgroundColor whether the default background color is used
|
||||
* @param alignment the alignment of the text
|
||||
* @param viewRange the view range of the text
|
||||
* @param shadowRadius the shadow radius
|
||||
* @param shadowStrength the shadow strength
|
||||
* @param scale the scale of the text
|
||||
* @param translation the translation of the text
|
||||
* @param lineWidth the width of the text line
|
||||
* @param isCrouching whether the entity is crouching
|
||||
* @param component the component containing the text
|
||||
* @param backgroundColor the background color
|
||||
* @param opacity the opacity of the text
|
||||
* @param hasShadow whether the text has a shadow
|
||||
* @param isSeeThrough whether the text is see-through
|
||||
* @param useDefaultBackgroundColor whether the default background color is used
|
||||
* @param alignment the alignment of the text
|
||||
* @param billboard
|
||||
* @param viewRange the view range of the text
|
||||
* @param shadowRadius the shadow radius
|
||||
* @param shadowStrength the shadow strength
|
||||
* @param scale the scale of the text
|
||||
* @param translation the translation of the text
|
||||
* @param lineWidth the width of the text line
|
||||
* @param isCrouching whether the entity is crouching
|
||||
* @return a list of packets for creating the text display
|
||||
*/
|
||||
List<Object> createTextDisplayPacket(
|
||||
@@ -145,9 +148,8 @@ public interface Platform {
|
||||
int interpolationDelay, int transformationInterpolationDuration, int positionRotationInterpolationDuration,
|
||||
Object component, int backgroundColor, byte opacity,
|
||||
boolean hasShadow, boolean isSeeThrough, boolean useDefaultBackgroundColor, Alignment alignment,
|
||||
float viewRange, float shadowRadius, float shadowStrength,
|
||||
Vector3 scale, Vector3 translation, int lineWidth, boolean isCrouching
|
||||
);
|
||||
Billboard billboard, float viewRange, float shadowRadius, float shadowStrength,
|
||||
Vector3 scale, Vector3 translation, int lineWidth, boolean isCrouching);
|
||||
|
||||
/**
|
||||
* Creates a modifier for interpolation delay.
|
||||
@@ -189,13 +191,7 @@ public interface Platform {
|
||||
*/
|
||||
Consumer<List<Object>> createTranslationModifier(Vector3 translation);
|
||||
|
||||
/**
|
||||
* Creates a modifier to change the opacity of a text display.
|
||||
*
|
||||
* @param opacity the new opacity
|
||||
* @return a consumer that applies the modifier to a list of packets
|
||||
*/
|
||||
Consumer<List<Object>> createOpacityModifier(byte opacity);
|
||||
Consumer<List<Object>> createSneakModifier(boolean isSneaking, boolean seeThrough, NameTagConfig config);
|
||||
|
||||
/**
|
||||
* Updates an existing text display entity with modifiers.
|
||||
|
||||
@@ -17,6 +17,15 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.feature;
|
||||
|
||||
/**
|
||||
* Interface representing an adaptive image with methods for generating image
|
||||
* prefixes, suffixes, and the full image string based on specified parameters.
|
||||
* <p>
|
||||
* The implementation of this interface should define how the image is adapted
|
||||
* based on the given margins and advance, which are used for layout and
|
||||
* positioning purposes.
|
||||
* </p>
|
||||
*/
|
||||
public interface AdaptiveImage {
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ public class ConfiguredCharacter {
|
||||
}
|
||||
advance = (float) Math.round((i + 1) * scale) + 1f;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new RuntimeException("Failed to load " + imageFile.toPath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,64 +17,241 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.feature;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Enum representing different font offsets used for handling character spacing and height.
|
||||
* The offsets are categorized into positive and negative values, each corresponding to
|
||||
* a specific advance (horizontal movement) and height (vertical movement).
|
||||
*/
|
||||
public enum OffsetFont {
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf800', horizontal advance of -1, and vertical height of -3.
|
||||
*/
|
||||
NEG_1('\uf800', -1, -3),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf801', horizontal advance of -2, and vertical height of -4.
|
||||
*/
|
||||
NEG_2('\uf801', -2, -4),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf802', horizontal advance of -3, and vertical height of -5.
|
||||
*/
|
||||
NEG_3('\uf802', -3, -5),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf803', horizontal advance of -4, and vertical height of -6.
|
||||
*/
|
||||
NEG_4('\uf803', -4, -6),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf804', horizontal advance of -5, and vertical height of -7.
|
||||
*/
|
||||
NEG_5('\uf804', -5, -7),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf805', horizontal advance of -6, and vertical height of -8.
|
||||
*/
|
||||
NEG_6('\uf805', -6, -8),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf806', horizontal advance of -7, and vertical height of -9.
|
||||
*/
|
||||
NEG_7('\uf806', -7, -9),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf807', horizontal advance of -8, and vertical height of -10.
|
||||
*/
|
||||
NEG_8('\uf807', -8, -10),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf808', horizontal advance of -9, and vertical height of -11.
|
||||
*/
|
||||
NEG_9('\uf808', -9, -11),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf809', horizontal advance of -10, and vertical height of -12.
|
||||
*/
|
||||
NEG_10('\uf809', -10, -12),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf80a', horizontal advance of -11, and vertical height of -13.
|
||||
*/
|
||||
NEG_11('\uf80a', -11, -13),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf80b', horizontal advance of -12, and vertical height of -14.
|
||||
*/
|
||||
NEG_12('\uf80b', -12, -14),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf80c', horizontal advance of -13, and vertical height of -15.
|
||||
*/
|
||||
NEG_13('\uf80c', -13, -15),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf80d', horizontal advance of -14, and vertical height of -16.
|
||||
*/
|
||||
NEG_14('\uf80d', -14, -16),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf80e', horizontal advance of -15, and vertical height of -17.
|
||||
*/
|
||||
NEG_15('\uf80e', -15, -17),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf80f', horizontal advance of -16, and vertical height of -18.
|
||||
*/
|
||||
NEG_16('\uf80f', -16, -18),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf810', horizontal advance of -24, and vertical height of -26.
|
||||
*/
|
||||
NEG_24('\uf810', -24, -26),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf811', horizontal advance of -32, and vertical height of -34.
|
||||
*/
|
||||
NEG_32('\uf811', -32, -34),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf812', horizontal advance of -48, and vertical height of -50.
|
||||
*/
|
||||
NEG_48('\uf812', -48, -50),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf813', horizontal advance of -64, and vertical height of -66.
|
||||
*/
|
||||
NEG_64('\uf813', -64, -66),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf814', horizontal advance of -128, and vertical height of -130.
|
||||
*/
|
||||
NEG_128('\uf814', -128, -130),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf815', horizontal advance of -256, and vertical height of -258.
|
||||
*/
|
||||
NEG_256('\uf815', -256, -258),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf830', horizontal advance of 1, and vertical height of -1.
|
||||
*/
|
||||
POS_1('\uf830', 1, -1),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf831', horizontal advance of 2, and vertical height of 1.
|
||||
*/
|
||||
POS_2('\uf831', 2, 1),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf832', horizontal advance of 3, and vertical height of 2.
|
||||
*/
|
||||
POS_3('\uf832', 3, 2),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf833', horizontal advance of 4, and vertical height of 3.
|
||||
*/
|
||||
POS_4('\uf833', 4, 3),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf834', horizontal advance of 5, and vertical height of 4.
|
||||
*/
|
||||
POS_5('\uf834', 5, 4),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf835', horizontal advance of 6, and vertical height of 5.
|
||||
*/
|
||||
POS_6('\uf835', 6, 5),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf836', horizontal advance of 7, and vertical height of 6.
|
||||
*/
|
||||
POS_7('\uf836', 7, 6),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf837', horizontal advance of 8, and vertical height of 7.
|
||||
*/
|
||||
POS_8('\uf837', 8, 7),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf838', horizontal advance of 9, and vertical height of 8.
|
||||
*/
|
||||
POS_9('\uf838', 9, 8),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf839', horizontal advance of 10, and vertical height of 9.
|
||||
*/
|
||||
POS_10('\uf839', 10, 9),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf83a', horizontal advance of 11, and vertical height of 10.
|
||||
*/
|
||||
POS_11('\uf83a', 11, 10),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf83b', horizontal advance of 12, and vertical height of 11.
|
||||
*/
|
||||
POS_12('\uf83b', 12, 11),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf83c', horizontal advance of 13, and vertical height of 12.
|
||||
*/
|
||||
POS_13('\uf83c', 13, 12),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf83d', horizontal advance of 14, and vertical height of 13.
|
||||
*/
|
||||
POS_14('\uf83d', 14, 13),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf83e', horizontal advance of 15, and vertical height of 14.
|
||||
*/
|
||||
POS_15('\uf83e', 15, 14),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf83f', horizontal advance of 16, and vertical height of 15.
|
||||
*/
|
||||
POS_16('\uf83f', 16, 15),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf840', horizontal advance of 24, and vertical height of 23.
|
||||
*/
|
||||
POS_24('\uf840', 24, 23),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf841', horizontal advance of 32, and vertical height of 31.
|
||||
*/
|
||||
POS_32('\uf841', 32, 31),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf842', horizontal advance of 48, and vertical height of 47.
|
||||
*/
|
||||
POS_48('\uf842', 48, 47),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf843', horizontal advance of 64, and vertical height of 63.
|
||||
*/
|
||||
POS_64('\uf843', 64, 63),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf844', horizontal advance of 128, and vertical height of 127.
|
||||
*/
|
||||
POS_128('\uf844', 128, 127),
|
||||
|
||||
/**
|
||||
* Represents a font with a character value of '\uf845', horizontal advance of 256, and vertical height of 255.
|
||||
*/
|
||||
POS_256('\uf845', 256, 255);
|
||||
|
||||
private static final HashMap<Integer, OffsetFont> negFastLookup = new HashMap<>();
|
||||
private static final HashMap<Integer, OffsetFont> posFastLookup = new HashMap<>();
|
||||
private static final OffsetFont[] negFastLookup = new OffsetFont[17];
|
||||
private static final OffsetFont[] posFastLookup = new OffsetFont[17];
|
||||
|
||||
static {
|
||||
for (OffsetFont f : OffsetFont.values()) {
|
||||
if (f.advance > 0) {
|
||||
posFastLookup.put(f.advance, f);
|
||||
} else {
|
||||
negFastLookup.put(-f.advance, f);
|
||||
if (f.advance > 0 && f.advance <= 16) {
|
||||
posFastLookup[f.advance] = f;
|
||||
} else if (f.advance < 0 && f.advance >= -16) {
|
||||
negFastLookup[-f.advance] = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,24 +260,53 @@ public enum OffsetFont {
|
||||
private final int advance;
|
||||
private final int height;
|
||||
|
||||
/**
|
||||
* Constructor to initialize the OffsetFont with a specific character, advance, and height.
|
||||
*
|
||||
* @param character the character associated with the offset
|
||||
* @param advance the horizontal movement (positive or negative)
|
||||
* @param height the vertical movement (positive or negative)
|
||||
*/
|
||||
OffsetFont(char character, int advance, int height) {
|
||||
this.character = character;
|
||||
this.advance = advance;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the character associated with this offset font.
|
||||
*
|
||||
* @return the character of this offset font
|
||||
*/
|
||||
public char character() {
|
||||
return this.character;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the advance value for this offset font.
|
||||
*
|
||||
* @return the advance (horizontal movement) for this offset font
|
||||
*/
|
||||
public float advance() {
|
||||
return this.advance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height value for this offset font.
|
||||
*
|
||||
* @return the height (vertical movement) for this offset font
|
||||
*/
|
||||
public int height() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string of offset characters based on the given offset value.
|
||||
* The result depends on whether the offset is positive or negative.
|
||||
*
|
||||
* @param offset the offset value
|
||||
* @return a string of offset characters
|
||||
*/
|
||||
public static String createOffsets(float offset) {
|
||||
if (offset >= 0) {
|
||||
return shortestPosChars(offset);
|
||||
@@ -109,6 +315,13 @@ public enum OffsetFont {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string of the shortest possible negative offset characters
|
||||
* that sum up to the given advance value.
|
||||
*
|
||||
* @param advance the negative advance value
|
||||
* @return the shortest string of negative offset characters
|
||||
*/
|
||||
public static String shortestNegChars(float advance) {
|
||||
int n = (int) Math.ceil(advance);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
@@ -141,10 +354,17 @@ public enum OffsetFont {
|
||||
n -= 16;
|
||||
}
|
||||
if (n == 0) return stringBuilder.toString();
|
||||
stringBuilder.append(negFastLookup.get(n).character());
|
||||
stringBuilder.append(negFastLookup[n].character());
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string of the shortest possible positive offset characters
|
||||
* that sum up to the given advance value.
|
||||
*
|
||||
* @param advance the positive advance value
|
||||
* @return the shortest string of positive offset characters
|
||||
*/
|
||||
public static String shortestPosChars(float advance) {
|
||||
int n = (int) Math.ceil(advance);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
@@ -177,7 +397,7 @@ public enum OffsetFont {
|
||||
n -= 16;
|
||||
}
|
||||
if (n == 0) return stringBuilder.toString();
|
||||
stringBuilder.append(posFastLookup.get(n).character());
|
||||
stringBuilder.append(posFastLookup[n].character());
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
+56
-11
@@ -17,29 +17,56 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.feature;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.placeholder.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Represents a dynamically parsed text that can contain placeholders.
|
||||
* The text is parsed at initialization and placeholders are replaced with corresponding values.
|
||||
* This class provides functionality to manage placeholders and generate dynamic text for players.
|
||||
*/
|
||||
public class PreParsedDynamicText {
|
||||
|
||||
private final String text;
|
||||
private final List<Function<CNPlayer, Function<CNPlayer, String>>> textFunctions = new ArrayList<>();
|
||||
private final Set<Placeholder> set = new HashSet<>();
|
||||
private final List<Function<CNPlayer, Function<CNPlayer, String>>> textFunctions = new ObjectArrayList<>();
|
||||
private final Set<Placeholder> set = new ObjectOpenHashSet<>();
|
||||
private boolean init = false;
|
||||
|
||||
/**
|
||||
* Constructs a PreParsedDynamicText with the given text.
|
||||
*
|
||||
* @param text the original text containing placeholders to be parsed
|
||||
* @throws NullPointerException if the provided text is null
|
||||
*/
|
||||
public PreParsedDynamicText(String text) {
|
||||
this.text = Objects.requireNonNull(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PreParsedDynamicText with the given text and initializes it (parses placeholders).
|
||||
*
|
||||
* @param text the original text containing placeholders to be parsed
|
||||
* @param init flag indicating whether to initialize the text immediately
|
||||
* @throws NullPointerException if the provided text is null
|
||||
*/
|
||||
public PreParsedDynamicText(String text, boolean init) {
|
||||
this.text = Objects.requireNonNull(text);
|
||||
if (init) init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the PreParsedDynamicText by parsing the text for placeholders and creating
|
||||
* corresponding functions for replacing the placeholders with values.
|
||||
* This method is called automatically if the constructor is provided with `true` for the init flag.
|
||||
*/
|
||||
public void init() {
|
||||
if (init) return;
|
||||
init = true;
|
||||
@@ -50,18 +77,24 @@ public class PreParsedDynamicText {
|
||||
for (String id : detectedPlaceholders) {
|
||||
Placeholder placeholder = manager.getPlaceholder(id);
|
||||
placeholders.add(placeholder);
|
||||
if (placeholder instanceof RelationalPlaceholder) {
|
||||
convertor.add((owner) -> (viewer) -> owner.getRelationalData(placeholder, viewer));
|
||||
if (placeholder instanceof RelationalPlaceholder relationalPlaceholder) {
|
||||
convertor.add((owner) -> (viewer) -> owner.getCachedRelationalValue(relationalPlaceholder, viewer));
|
||||
} else if (placeholder instanceof PlayerPlaceholder playerPlaceholder) {
|
||||
convertor.add((owner) -> (viewer) -> {
|
||||
if (owner != null) {
|
||||
return owner.getData(placeholder);
|
||||
return owner.getCachedPlayerValue(playerPlaceholder);
|
||||
} else {
|
||||
return playerPlaceholder.request(null);
|
||||
}
|
||||
});
|
||||
} else if (placeholder instanceof SharedPlaceholder sharedPlaceholder) {
|
||||
convertor.add((owner) -> (viewer) -> sharedPlaceholder.getLatestValue());
|
||||
convertor.add((owner) -> (viewer) -> {
|
||||
if (owner != null) {
|
||||
return owner.getCachedSharedValue(sharedPlaceholder);
|
||||
} else {
|
||||
return sharedPlaceholder.request();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
convertor.add((owner) -> (viewer) -> id);
|
||||
}
|
||||
@@ -86,18 +119,30 @@ public class PreParsedDynamicText {
|
||||
String remaining = original0.substring(lastIndex);
|
||||
textFunctions.add((owner) -> (viewer) -> remaining);
|
||||
}
|
||||
// To optimize the tree height, call new HashSet twice here
|
||||
set.addAll(new HashSet<>(placeholders));
|
||||
// To optimize the tree height
|
||||
set.addAll(new ObjectArrayList<>(placeholders));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a dynamic text based on the current pre-parsed text, tailored to the given player.
|
||||
* This method uses the player's data to generate the final text.
|
||||
*
|
||||
* @param player the player for whom the dynamic text is being generated
|
||||
* @return a DynamicText object containing the final text for the player
|
||||
*/
|
||||
public DynamicText fastCreate(CNPlayer player) {
|
||||
List<Function<CNPlayer, String>> functions = new ArrayList<>();
|
||||
List<Function<CNPlayer, String>> functions = new ObjectArrayList<>();
|
||||
for (Function<CNPlayer, Function<CNPlayer, String>> textFunction : textFunctions) {
|
||||
functions.add(textFunction.apply(player));
|
||||
}
|
||||
return new DynamicText(text, functions, set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of placeholders detected in the text.
|
||||
*
|
||||
* @return a set of placeholders used in the text
|
||||
*/
|
||||
public Set<Placeholder> placeholders() {
|
||||
return set;
|
||||
}
|
||||
|
||||
+3
@@ -20,6 +20,9 @@ package net.momirealms.customnameplates.api.feature.actionbar;
|
||||
import net.momirealms.customnameplates.api.feature.CarouselText;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
|
||||
/**
|
||||
* ActionBar Config
|
||||
*/
|
||||
public interface ActionBarConfig {
|
||||
|
||||
/**
|
||||
|
||||
+7
-3
@@ -22,13 +22,15 @@ import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Implementation of ActionBarConfig
|
||||
*/
|
||||
public class ActionBarConfigImpl implements ActionBarConfig {
|
||||
|
||||
private final String id;
|
||||
private final Requirement[] requirements;
|
||||
private final CarouselText[] carouselTexts;
|
||||
|
||||
public ActionBarConfigImpl(String id, Requirement[] requirements, CarouselText[] carouselTexts) {
|
||||
private ActionBarConfigImpl(String id, Requirement[] requirements, CarouselText[] carouselTexts) {
|
||||
this.id = requireNonNull(id);
|
||||
this.requirements = requireNonNull(requirements);
|
||||
this.carouselTexts = requireNonNull(carouselTexts);
|
||||
@@ -49,8 +51,10 @@ public class ActionBarConfigImpl implements ActionBarConfig {
|
||||
return carouselTexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder Implementation
|
||||
*/
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private Requirement[] requirements;
|
||||
private CarouselText[] carouselTexts;
|
||||
|
||||
+3
@@ -21,6 +21,9 @@ import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Interface representing a manager for handling ActionBars.
|
||||
*/
|
||||
public interface ActionBarManager extends Reloadable {
|
||||
|
||||
/**
|
||||
|
||||
+3
@@ -25,6 +25,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface that defines methods for managing and calculating text advance data,
|
||||
*/
|
||||
public interface AdvanceManager extends Reloadable {
|
||||
|
||||
/**
|
||||
|
||||
+3
@@ -23,6 +23,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Interface representing character font advance data.
|
||||
*/
|
||||
public interface CharacterFontAdvanceData {
|
||||
|
||||
/**
|
||||
|
||||
+17
-6
@@ -18,21 +18,30 @@
|
||||
package net.momirealms.customnameplates.api.feature.advance;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Implementation of the CharacterFontAdvanceData interface.
|
||||
*/
|
||||
public class CharacterFontAdvanceDataImpl implements CharacterFontAdvanceData {
|
||||
|
||||
private final HashMap<Integer, Float> data;
|
||||
private final Map<Integer, Float> data;
|
||||
private final String id;
|
||||
private final Function<Map<String, Object>, List<JsonObject>> fontProviderFunction;
|
||||
|
||||
public CharacterFontAdvanceDataImpl(String id, HashMap<Integer, Float> data, Function<Map<String, Object>, List<JsonObject>> fontProviderFunction) {
|
||||
/**
|
||||
* Constructs a new instance of CharacterFontAdvanceDataImpl.
|
||||
*
|
||||
* @param id the unique identifier for this font advance data
|
||||
* @param data a map of character code points and their corresponding advance values
|
||||
* @param fontProviderFunction a function that generates font provider configurations
|
||||
*/
|
||||
private CharacterFontAdvanceDataImpl(String id, Map<Integer, Float> data, Function<Map<String, Object>, List<JsonObject>> fontProviderFunction) {
|
||||
this.data = data;
|
||||
this.id = requireNonNull(id);
|
||||
this.fontProviderFunction = requireNonNull(fontProviderFunction);
|
||||
@@ -63,9 +72,11 @@ public class CharacterFontAdvanceDataImpl implements CharacterFontAdvanceData {
|
||||
return fontProviderFunction.apply(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* The builder implementation
|
||||
*/
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private final HashMap<Integer, Float> data = new HashMap<>();
|
||||
private final Int2FloatOpenHashMap data = new Int2FloatOpenHashMap();
|
||||
private String id;
|
||||
private Function<Map<String, Object>, List<JsonObject>> fontProviderFunction = (stringObjectMap -> null);
|
||||
|
||||
|
||||
+13
-9
@@ -17,21 +17,23 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.feature.advance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Implementation of ConfigurableFontAdvanceData
|
||||
*/
|
||||
public class ConfigurableFontAdvanceDataImpl implements ConfigurableFontAdvanceData {
|
||||
|
||||
private final float defaultAdvance;
|
||||
private final HashMap<Integer, Float> data = new HashMap<>();
|
||||
private final List<CharacterFontAdvanceData> parents = new ArrayList<>();
|
||||
private final Map<Integer, Float> data = new Int2FloatOpenHashMap();
|
||||
private final List<CharacterFontAdvanceData> parents = new ObjectArrayList<>();
|
||||
private final String id;
|
||||
|
||||
public ConfigurableFontAdvanceDataImpl(String id, float defaultAdvance, HashMap<Integer, Float> customData, List<CharacterFontAdvanceData> parentFonts) {
|
||||
private ConfigurableFontAdvanceDataImpl(String id, float defaultAdvance, HashMap<Integer, Float> customData, List<CharacterFontAdvanceData> parentFonts) {
|
||||
this.id = requireNonNull(id);
|
||||
this.defaultAdvance = defaultAdvance;
|
||||
for (CharacterFontAdvanceData parent : parentFonts) {
|
||||
@@ -71,8 +73,10 @@ public class ConfigurableFontAdvanceDataImpl implements ConfigurableFontAdvanceD
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The builder implementation
|
||||
*/
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private final HashMap<Integer, Float> customData = new HashMap<>();
|
||||
private final List<CharacterFontAdvanceData> parents = new ArrayList<>();
|
||||
private float defaultAdvance = 0;
|
||||
|
||||
+10
-95
@@ -22,101 +22,14 @@ import net.momirealms.customnameplates.api.feature.OffsetFont;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Implements the {@link Background} interface, representing the detailed configuration of a background.
|
||||
*/
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public class BackgroundImpl implements Background {
|
||||
|
||||
private final String id;
|
||||
private final ConfiguredCharacter left;
|
||||
private final ConfiguredCharacter width_1;
|
||||
private final ConfiguredCharacter width_2;
|
||||
private final ConfiguredCharacter width_4;
|
||||
private final ConfiguredCharacter width_8;
|
||||
private final ConfiguredCharacter width_16;
|
||||
private final ConfiguredCharacter width_32;
|
||||
private final ConfiguredCharacter width_64;
|
||||
private final ConfiguredCharacter width_128;
|
||||
private final ConfiguredCharacter right;
|
||||
|
||||
public BackgroundImpl(
|
||||
String id,
|
||||
ConfiguredCharacter left,
|
||||
ConfiguredCharacter width_1,
|
||||
ConfiguredCharacter width_2,
|
||||
ConfiguredCharacter width_4,
|
||||
ConfiguredCharacter width_8,
|
||||
ConfiguredCharacter width_16,
|
||||
ConfiguredCharacter width_32,
|
||||
ConfiguredCharacter width_64,
|
||||
ConfiguredCharacter width_128,
|
||||
ConfiguredCharacter right
|
||||
) {
|
||||
this.id = id;
|
||||
this.left = left;
|
||||
this.width_1 = width_1;
|
||||
this.width_2 = width_2;
|
||||
this.width_4 = width_4;
|
||||
this.width_8 = width_8;
|
||||
this.width_16 = width_16;
|
||||
this.width_32 = width_32;
|
||||
this.width_64 = width_64;
|
||||
this.width_128 = width_128;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter left() {
|
||||
return left;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter width_1() {
|
||||
return width_1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter width_2() {
|
||||
return width_2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter width_4() {
|
||||
return width_4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter width_8() {
|
||||
return width_8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter width_16() {
|
||||
return width_16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter width_32() {
|
||||
return width_32;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter width_64() {
|
||||
return width_64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter width_128() {
|
||||
return width_128;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter right() {
|
||||
return right;
|
||||
}
|
||||
public record BackgroundImpl(String id, ConfiguredCharacter left, ConfiguredCharacter width_1,
|
||||
ConfiguredCharacter width_2, ConfiguredCharacter width_4, ConfiguredCharacter width_8,
|
||||
ConfiguredCharacter width_16, ConfiguredCharacter width_32, ConfiguredCharacter width_64,
|
||||
ConfiguredCharacter width_128, ConfiguredCharacter right) implements Background {
|
||||
|
||||
@Override
|
||||
public String createImagePrefix(float advance, float leftMargin, float rightMargin) {
|
||||
@@ -239,8 +152,10 @@ public class BackgroundImpl implements Background {
|
||||
return Objects.hashCode(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* The builder implementation
|
||||
*/
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private ConfiguredCharacter left;
|
||||
private ConfiguredCharacter width_1;
|
||||
|
||||
+3
@@ -22,6 +22,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Interface representing a manager for background configurations.
|
||||
*/
|
||||
public interface BackgroundManager extends Reloadable {
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.feature.bossbar;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a BossBar
|
||||
*/
|
||||
public interface BossBar {
|
||||
|
||||
/**
|
||||
@@ -50,21 +53,74 @@ public interface BossBar {
|
||||
*/
|
||||
Overlay overlay();
|
||||
|
||||
/**
|
||||
* Enum representing the different overlay styles for the BossBar.
|
||||
* The overlay style determines how the bar is divided, either as a simple progress bar or as notches.
|
||||
*/
|
||||
enum Overlay {
|
||||
/**
|
||||
* The bar is displayed as a simple progress bar.
|
||||
*/
|
||||
PROGRESS,
|
||||
|
||||
/**
|
||||
* The bar is divided into 6 notches.
|
||||
*/
|
||||
NOTCHED_6,
|
||||
|
||||
/**
|
||||
* The bar is divided into 10 notches.
|
||||
*/
|
||||
NOTCHED_10,
|
||||
|
||||
/**
|
||||
* The bar is divided into 12 notches.
|
||||
*/
|
||||
NOTCHED_12,
|
||||
|
||||
/**
|
||||
* The bar is divided into 20 notches.
|
||||
*/
|
||||
NOTCHED_20
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum representing the different colors for the BossBar.
|
||||
*/
|
||||
enum Color {
|
||||
/**
|
||||
* Blue color for the BossBar.
|
||||
*/
|
||||
BLUE,
|
||||
|
||||
/**
|
||||
* Green color for the BossBar.
|
||||
*/
|
||||
GREEN,
|
||||
|
||||
/**
|
||||
* Pink color for the BossBar.
|
||||
*/
|
||||
PINK,
|
||||
|
||||
/**
|
||||
* Purple color for the BossBar.
|
||||
*/
|
||||
PURPLE,
|
||||
|
||||
/**
|
||||
* Red color for the BossBar.
|
||||
*/
|
||||
RED,
|
||||
|
||||
/**
|
||||
* White color for the BossBar.
|
||||
*/
|
||||
WHITE,
|
||||
|
||||
/**
|
||||
* Yellow color for the BossBar.
|
||||
*/
|
||||
YELLOW
|
||||
}
|
||||
}
|
||||
+3
@@ -20,6 +20,9 @@ package net.momirealms.customnameplates.api.feature.bossbar;
|
||||
import net.momirealms.customnameplates.api.feature.CarouselText;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
|
||||
/**
|
||||
* Interface for BossBarConfig
|
||||
*/
|
||||
public interface BossBarConfig {
|
||||
|
||||
/**
|
||||
|
||||
+18
-3
@@ -22,8 +22,10 @@ import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Implementation of BossBar Config
|
||||
*/
|
||||
public class BossBarConfigImpl implements BossBarConfig {
|
||||
|
||||
private final String id;
|
||||
private final Requirement[] requirements;
|
||||
private final CarouselText[] carouselTexts;
|
||||
@@ -31,7 +33,18 @@ public class BossBarConfigImpl implements BossBarConfig {
|
||||
private final BossBar.Color color;
|
||||
private final float progress;
|
||||
|
||||
public BossBarConfigImpl(String id, Requirement[] requirements, CarouselText[] carouselTexts, BossBar.Overlay overlay, BossBar.Color color, float progress) {
|
||||
/**
|
||||
* Constructor for creating a new BossBarConfigImpl.
|
||||
* Ensures that all fields are non-null and properly initialized.
|
||||
*
|
||||
* @param id the unique ID of the BossBar configuration
|
||||
* @param requirements the requirements for the BossBar
|
||||
* @param carouselTexts the carousel texts associated with the BossBar
|
||||
* @param overlay the overlay style of the BossBar
|
||||
* @param color the color of the BossBar
|
||||
* @param progress the progress value of the BossBar (between 0.0 and 1.0)
|
||||
*/
|
||||
private BossBarConfigImpl(String id, Requirement[] requirements, CarouselText[] carouselTexts, BossBar.Overlay overlay, BossBar.Color color, float progress) {
|
||||
this.id = requireNonNull(id);
|
||||
this.requirements = requireNonNull(requirements);
|
||||
this.carouselTexts = requireNonNull(carouselTexts);
|
||||
@@ -70,8 +83,10 @@ public class BossBarConfigImpl implements BossBarConfig {
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder Implementation
|
||||
*/
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private Requirement[] requirements;
|
||||
private CarouselText[] carouselTexts;
|
||||
|
||||
+3
@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.feature.bossbar;
|
||||
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
|
||||
/**
|
||||
* Manager interface for handling BossBar configurations and their updates.
|
||||
*/
|
||||
public interface BossBarManager extends Reloadable {
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,9 @@ package net.momirealms.customnameplates.api.feature.bubble;
|
||||
import net.momirealms.customnameplates.api.feature.AdaptiveImage;
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
|
||||
/**
|
||||
* Bubble
|
||||
*/
|
||||
public interface Bubble extends AdaptiveImage {
|
||||
|
||||
/**
|
||||
|
||||
+54
-2
@@ -17,8 +17,13 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.feature.bubble;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.PreParsedDynamicText;
|
||||
import net.momirealms.customnameplates.api.util.Billboard;
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
|
||||
/**
|
||||
* Bubble configuration
|
||||
*/
|
||||
public interface BubbleConfig {
|
||||
|
||||
/**
|
||||
@@ -28,6 +33,15 @@ public interface BubbleConfig {
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Returns the command suggestion of the Bubble configuration.
|
||||
*
|
||||
* @return the configuration ID
|
||||
*/
|
||||
default String commandSuggestion() {
|
||||
return id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the background color of the Bubble text.
|
||||
*
|
||||
@@ -49,6 +63,20 @@ public interface BubbleConfig {
|
||||
*/
|
||||
int maxLines();
|
||||
|
||||
/**
|
||||
* Returns if the bubble has shadow
|
||||
*
|
||||
* @return has shadow or not
|
||||
*/
|
||||
boolean hasShadow();
|
||||
|
||||
/**
|
||||
* Returns the billboard
|
||||
*
|
||||
* @return billboard
|
||||
*/
|
||||
Billboard billboard();
|
||||
|
||||
/**
|
||||
* Returns the bubbles used in this configuration.
|
||||
*
|
||||
@@ -61,14 +89,14 @@ public interface BubbleConfig {
|
||||
*
|
||||
* @return the text prefix
|
||||
*/
|
||||
String textPrefix();
|
||||
PreParsedDynamicText textPrefix();
|
||||
|
||||
/**
|
||||
* Returns the text suffix to be applied after the Bubble content.
|
||||
*
|
||||
* @return the text suffix
|
||||
*/
|
||||
String textSuffix();
|
||||
PreParsedDynamicText textSuffix();
|
||||
|
||||
/**
|
||||
* Returns the display name of the Bubble.
|
||||
@@ -106,6 +134,14 @@ public interface BubbleConfig {
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets the command suggestion for the BubbleConfig.
|
||||
*
|
||||
* @param suggestion the command suggestion
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder commandSuggestion(String suggestion);
|
||||
|
||||
/**
|
||||
* Sets the display name for the BubbleConfig.
|
||||
*
|
||||
@@ -170,6 +206,22 @@ public interface BubbleConfig {
|
||||
*/
|
||||
Builder scale(Vector3 scale);
|
||||
|
||||
/**
|
||||
* Sets if the text has shadow
|
||||
*
|
||||
* @param hasShadow has shadow
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder hasShadow(boolean hasShadow);
|
||||
|
||||
/**
|
||||
* Sets the billboard
|
||||
*
|
||||
* @param billboard billboard
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder billboard(Billboard billboard);
|
||||
|
||||
/**
|
||||
* Builds and returns the configured BubbleConfig instance.
|
||||
*
|
||||
|
||||
+76
-11
@@ -17,37 +17,69 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.feature.bubble;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.PreParsedDynamicText;
|
||||
import net.momirealms.customnameplates.api.util.Billboard;
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Implementation of the BubbleConfig interface
|
||||
*/
|
||||
public class BubbleConfigImpl implements BubbleConfig {
|
||||
|
||||
private final String id;
|
||||
private final String commandSuggestion;
|
||||
private final int backgroundColor;
|
||||
private final int lineWidth;
|
||||
private final int maxLines;
|
||||
private final Bubble[] bubbles;
|
||||
private final String textPrefix;
|
||||
private final String textSuffix;
|
||||
private final PreParsedDynamicText textPrefix;
|
||||
private final PreParsedDynamicText textSuffix;
|
||||
private final String displayName;
|
||||
private final Vector3 scale;
|
||||
private final boolean hasShadow;
|
||||
private final Billboard billboard;
|
||||
|
||||
public BubbleConfigImpl(String id, String displayName, int backgroundColor, int lineWidth, int maxLines, Bubble[] bubbles, String textPrefix, String textSuffix, Vector3 scale) {
|
||||
/**
|
||||
* Constructs a new BubbleConfigImpl.
|
||||
*
|
||||
* @param id the unique ID for the bubble configuration
|
||||
* @param commandSuggestion the command suggestion for the bubble configuration
|
||||
* @param displayName the name to be displayed for the bubble configuration
|
||||
* @param backgroundColor the background color for the bubble (in integer format)
|
||||
* @param lineWidth the line width for the bubble display
|
||||
* @param maxLines the maximum number of lines that can be displayed in the bubble
|
||||
* @param bubbles an array of Bubble objects representing the actual bubbles
|
||||
* @param textPrefix a prefix that will be added before the text in the bubble
|
||||
* @param textSuffix a suffix that will be added after the text in the bubble
|
||||
* @param scale the scale of the bubble display (as a Vector3)
|
||||
* @param hasShadow has shadow or not
|
||||
*/
|
||||
public BubbleConfigImpl(String id, String commandSuggestion, String displayName, int backgroundColor, int lineWidth, int maxLines, Bubble[] bubbles, String textPrefix, String textSuffix, Vector3 scale, boolean hasShadow, Billboard billboard) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.lineWidth = lineWidth;
|
||||
this.maxLines = maxLines;
|
||||
this.id = id;
|
||||
this.commandSuggestion = commandSuggestion;
|
||||
this.bubbles = requireNonNull(bubbles);
|
||||
this.textPrefix = requireNonNull(textPrefix);
|
||||
this.textSuffix = requireNonNull(textSuffix);
|
||||
this.textPrefix = new PreParsedDynamicText(requireNonNull(textPrefix), true);
|
||||
this.textSuffix = new PreParsedDynamicText(requireNonNull(textSuffix), true);
|
||||
this.displayName = requireNonNull(displayName);
|
||||
this.scale = requireNonNull(scale);
|
||||
this.hasShadow = hasShadow;
|
||||
this.billboard = billboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String commandSuggestion() {
|
||||
return this.commandSuggestion;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,12 +103,12 @@ public class BubbleConfigImpl implements BubbleConfig {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String textPrefix() {
|
||||
public PreParsedDynamicText textPrefix() {
|
||||
return textPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String textSuffix() {
|
||||
public PreParsedDynamicText textSuffix() {
|
||||
return textSuffix;
|
||||
}
|
||||
|
||||
@@ -90,8 +122,20 @@ public class BubbleConfigImpl implements BubbleConfig {
|
||||
return scale;
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
@Override
|
||||
public boolean hasShadow() {
|
||||
return hasShadow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Billboard billboard() {
|
||||
return billboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder implementation for creating BubbleConfigImpl instances.
|
||||
*/
|
||||
public static class BuilderImpl implements Builder {
|
||||
private int backgroundColor;
|
||||
private int lineWidth;
|
||||
private int maxLines;
|
||||
@@ -99,8 +143,11 @@ public class BubbleConfigImpl implements BubbleConfig {
|
||||
private String textPrefix;
|
||||
private String textSuffix;
|
||||
private String id;
|
||||
private String commandSuggestion;
|
||||
private String displayName;
|
||||
private Vector3 scale;
|
||||
private boolean hasShadow;
|
||||
private Billboard billboard;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
@@ -114,6 +161,12 @@ public class BubbleConfigImpl implements BubbleConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder commandSuggestion(String commandSuggestion) {
|
||||
this.commandSuggestion = commandSuggestion;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder backgroundColor(int backgroundColor) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
@@ -156,9 +209,21 @@ public class BubbleConfigImpl implements BubbleConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder hasShadow(boolean hasShadow) {
|
||||
this.hasShadow = hasShadow;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder billboard(Billboard billboard) {
|
||||
this.billboard = billboard;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BubbleConfig build() {
|
||||
return new BubbleConfigImpl(id, displayName, backgroundColor, lineWidth, maxLines, bubbles, textPrefix, textSuffix, scale);
|
||||
return new BubbleConfigImpl(id, Optional.ofNullable(this.commandSuggestion).orElse(id), displayName, backgroundColor, lineWidth, maxLines, bubbles, textPrefix, textSuffix, scale, hasShadow, billboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-2
@@ -22,14 +22,25 @@ import net.momirealms.customnameplates.api.feature.OffsetFont;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Implementation of the Bubble interface
|
||||
*/
|
||||
public class BubbleImpl implements Bubble {
|
||||
|
||||
private final String id;
|
||||
private final ConfiguredCharacter left;
|
||||
private final ConfiguredCharacter right;
|
||||
private final ConfiguredCharacter middle;
|
||||
private final ConfiguredCharacter tail;
|
||||
|
||||
/**
|
||||
* Constructs a new BubbleImpl.
|
||||
*
|
||||
* @param id the unique ID for the bubble
|
||||
* @param left the character representing the left part of the bubble
|
||||
* @param right the character representing the right part of the bubble
|
||||
* @param middle the character representing the middle part of the bubble
|
||||
* @param tail the character representing the tail part of the bubble
|
||||
*/
|
||||
public BubbleImpl(String id, ConfiguredCharacter left, ConfiguredCharacter right, ConfiguredCharacter middle, ConfiguredCharacter tail) {
|
||||
this.id = id;
|
||||
this.left = left;
|
||||
@@ -149,8 +160,10 @@ public class BubbleImpl implements Bubble {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder implementation for creating BubbleImpl instances.
|
||||
*/
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private ConfiguredCharacter left;
|
||||
private ConfiguredCharacter right;
|
||||
|
||||
+12
@@ -25,6 +25,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The BubbleManager interface is responsible for managing the configuration and display of Bubbles,
|
||||
* including retrieving available Bubbles, managing Bubble configurations, and controlling display settings.
|
||||
*/
|
||||
public interface BubbleManager extends Reloadable {
|
||||
|
||||
/**
|
||||
@@ -59,6 +63,14 @@ public interface BubbleManager extends Reloadable {
|
||||
@Nullable
|
||||
BubbleConfig bubbleConfigById(String id);
|
||||
|
||||
/**
|
||||
* Retrieves a Bubble configuration by its command suggestion
|
||||
*
|
||||
* @param suggestion command suggestion
|
||||
* @return the BubbleConfig instance, or null if not found
|
||||
*/
|
||||
@Nullable BubbleConfig bubbleConfigByCommand(String suggestion);
|
||||
|
||||
/**
|
||||
* Checks if a player has access to a specific Bubble by its ID.
|
||||
*
|
||||
|
||||
+14
-2
@@ -17,9 +17,21 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.feature.bubble;
|
||||
|
||||
/**
|
||||
* Enum representing the different modes for Bubble channels.
|
||||
* The mode determines the visibility and access rules for Bubbles in various channels.
|
||||
*/
|
||||
public enum ChannelMode {
|
||||
|
||||
/**
|
||||
* The ALL mode means that Bubbles can be displayed in all channels, regardless of the player's status or permissions.
|
||||
*/
|
||||
ALL,
|
||||
/**
|
||||
* The JOINED mode means that Bubbles can only be displayed in channels where the player is currently a member.
|
||||
*/
|
||||
JOINED,
|
||||
/**
|
||||
* The CAN_JOIN mode means that Bubbles can be displayed in channels that the player can join, even if they are not currently in them.
|
||||
*/
|
||||
CAN_JOIN
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -24,8 +24,13 @@ import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
* for managing the plugin and chat manager.
|
||||
*/
|
||||
public abstract class AbstractChatMessageProvider implements ChatMessageProvider {
|
||||
|
||||
/**
|
||||
* The CustomNameplates plugin
|
||||
*/
|
||||
protected CustomNameplates plugin;
|
||||
/**
|
||||
* The chat manager
|
||||
*/
|
||||
protected ChatManager manager;
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,8 @@ import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
*/
|
||||
public interface ChatManager extends Reloadable {
|
||||
|
||||
String replaceEmojis(CNPlayer player, String text);
|
||||
|
||||
/**
|
||||
* Sets a custom chat message provider.
|
||||
*
|
||||
|
||||
+5
-13
@@ -15,18 +15,10 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.common.event;
|
||||
package net.momirealms.customnameplates.api.feature.image;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
public interface CommandFeedbackEvent<C> extends NameplatesEvent, Cancellable {
|
||||
|
||||
@Param(0)
|
||||
C sender();
|
||||
|
||||
@Param(1)
|
||||
String key();
|
||||
|
||||
@Param(2)
|
||||
Component message();
|
||||
/**
|
||||
* A record representing an animation with a speed and a number of frames.
|
||||
*/
|
||||
public record Animation(int speed, int frames) {
|
||||
}
|
||||
@@ -18,7 +18,11 @@
|
||||
package net.momirealms.customnameplates.api.feature.image;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An interface represents the image
|
||||
*/
|
||||
public interface Image {
|
||||
|
||||
/**
|
||||
@@ -33,15 +37,15 @@ public interface Image {
|
||||
*
|
||||
* @return true if the image has a shadow, false otherwise
|
||||
*/
|
||||
boolean hasShadow();
|
||||
boolean removeShadow();
|
||||
|
||||
/**
|
||||
* Returns the opacity level of the image.
|
||||
* The value should typically range from 0 (fully transparent) to 255 (fully opaque).
|
||||
* Get the animation of the image
|
||||
*
|
||||
* @return the opacity value of the image
|
||||
* @return the animated image
|
||||
*/
|
||||
int opacity();
|
||||
@Nullable
|
||||
Animation animation();
|
||||
|
||||
/**
|
||||
* Returns the configured character associated with this image.
|
||||
@@ -73,20 +77,20 @@ public interface Image {
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets whether the image has a shadow effect.
|
||||
* Sets whether to remove the shadow of the image
|
||||
*
|
||||
* @param has true if the image should have a shadow, false otherwise
|
||||
* @param remove true if to remove the shadow
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder hasShadow(boolean has);
|
||||
Builder removeShadow(boolean remove);
|
||||
|
||||
/**
|
||||
* Sets the opacity level of the image.
|
||||
* Sets the animation of the image
|
||||
*
|
||||
* @param opacity the opacity value, typically from 0 to 255
|
||||
* @param animation animation
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder opacity(int opacity);
|
||||
Builder animation(@Nullable Animation animation);
|
||||
|
||||
/**
|
||||
* Sets the configured character associated with this image.
|
||||
|
||||
+23
-18
@@ -18,21 +18,24 @@
|
||||
package net.momirealms.customnameplates.api.feature.image;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Implementation of Image
|
||||
*/
|
||||
public class ImageImpl implements Image {
|
||||
|
||||
private final String id;
|
||||
private final boolean hasShadow;
|
||||
private final int opacity;
|
||||
private final boolean removeShadow;
|
||||
private final ConfiguredCharacter character;
|
||||
private final Animation animation;
|
||||
|
||||
public ImageImpl(String id, boolean hasShadow, int opacity, ConfiguredCharacter character) {
|
||||
private ImageImpl(String id, boolean removeShadow, Animation animation, ConfiguredCharacter character) {
|
||||
this.id = id;
|
||||
this.hasShadow = hasShadow;
|
||||
this.opacity = opacity;
|
||||
this.removeShadow = removeShadow;
|
||||
this.character = character;
|
||||
this.animation = animation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,13 +44,13 @@ public class ImageImpl implements Image {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasShadow() {
|
||||
return hasShadow;
|
||||
public boolean removeShadow() {
|
||||
return removeShadow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int opacity() {
|
||||
return opacity;
|
||||
public @Nullable Animation animation() {
|
||||
return animation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,12 +71,14 @@ public class ImageImpl implements Image {
|
||||
return Objects.hashCode(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* The builder Implementation
|
||||
*/
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private boolean hasShadow;
|
||||
private int opacity;
|
||||
private boolean removeShadow;
|
||||
private ConfiguredCharacter character;
|
||||
private Animation animation;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
@@ -82,14 +87,14 @@ public class ImageImpl implements Image {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder hasShadow(boolean has) {
|
||||
this.hasShadow = has;
|
||||
public Builder removeShadow(boolean removeShadow) {
|
||||
this.removeShadow = removeShadow;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder opacity(int opacity) {
|
||||
this.opacity = opacity;
|
||||
public Builder animation(@Nullable Animation animation) {
|
||||
this.animation = animation;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -101,7 +106,7 @@ public class ImageImpl implements Image {
|
||||
|
||||
@Override
|
||||
public Image build() {
|
||||
return new ImageImpl(id, hasShadow, opacity, character);
|
||||
return new ImageImpl(id, removeShadow, animation, character);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Manages image configurations
|
||||
*/
|
||||
public interface ImageManager extends Reloadable {
|
||||
|
||||
/**
|
||||
|
||||
+35
@@ -20,6 +20,9 @@ package net.momirealms.customnameplates.api.feature.nameplate;
|
||||
import net.momirealms.customnameplates.api.feature.AdaptiveImage;
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
|
||||
/**
|
||||
* Nameplate
|
||||
*/
|
||||
public interface Nameplate extends AdaptiveImage {
|
||||
|
||||
/**
|
||||
@@ -29,6 +32,15 @@ public interface Nameplate extends AdaptiveImage {
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Returns the command suggestion of the nameplate configuration.
|
||||
*
|
||||
* @return the nameplate ID
|
||||
*/
|
||||
default String commandSuggestion() {
|
||||
return id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display name of the nameplate.
|
||||
*
|
||||
@@ -57,6 +69,13 @@ public interface Nameplate extends AdaptiveImage {
|
||||
*/
|
||||
ConfiguredCharacter right();
|
||||
|
||||
/**
|
||||
* Gets the min width of the nameplate
|
||||
*
|
||||
* @return the min width of the nameplate
|
||||
*/
|
||||
int minWidth();
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing a Nameplate configuration.
|
||||
*
|
||||
@@ -79,6 +98,14 @@ public interface Nameplate extends AdaptiveImage {
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets the command suggestion for the nameplate
|
||||
*
|
||||
* @param commandSuggestion command suggestion
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder commandSuggestion(String commandSuggestion);
|
||||
|
||||
/**
|
||||
* Sets the display name for the nameplate.
|
||||
*
|
||||
@@ -87,6 +114,14 @@ public interface Nameplate extends AdaptiveImage {
|
||||
*/
|
||||
Builder displayName(String displayName);
|
||||
|
||||
/**
|
||||
* Sets the min width for the nameplate
|
||||
*
|
||||
* @param minWidth min width
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder minWidth(int minWidth);
|
||||
|
||||
/**
|
||||
* Sets the configured character for the left side of the nameplate.
|
||||
*
|
||||
|
||||
+40
-4
@@ -21,18 +21,25 @@ import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
import net.momirealms.customnameplates.api.feature.OffsetFont;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Implementation of Nameplate
|
||||
*/
|
||||
public class NameplateImpl implements Nameplate {
|
||||
|
||||
private final String id;
|
||||
private final String commandSuggestion;
|
||||
private final String displayName;
|
||||
private final ConfiguredCharacter left;
|
||||
private final ConfiguredCharacter middle;
|
||||
private final ConfiguredCharacter right;
|
||||
private final int minWidth;
|
||||
|
||||
public NameplateImpl(String id, String displayName, ConfiguredCharacter left, ConfiguredCharacter middle, ConfiguredCharacter right) {
|
||||
private NameplateImpl(String id, String commandSuggestion, String displayName, int minWidth, ConfiguredCharacter left, ConfiguredCharacter middle, ConfiguredCharacter right) {
|
||||
this.id = id;
|
||||
this.commandSuggestion = commandSuggestion;
|
||||
this.displayName = displayName;
|
||||
this.minWidth = minWidth;
|
||||
this.left = left;
|
||||
this.middle = middle;
|
||||
this.right = right;
|
||||
@@ -48,6 +55,11 @@ public class NameplateImpl implements Nameplate {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String commandSuggestion() {
|
||||
return this.commandSuggestion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter left() {
|
||||
return left;
|
||||
@@ -63,6 +75,11 @@ public class NameplateImpl implements Nameplate {
|
||||
return right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int minWidth() {
|
||||
return minWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) return true;
|
||||
@@ -80,6 +97,7 @@ public class NameplateImpl implements Nameplate {
|
||||
@Override
|
||||
public String createImagePrefix(float advance, float leftMargin, float rightMargin) {
|
||||
if (advance <= 0) return "";
|
||||
advance = Math.max(minWidth, advance);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(left.character());
|
||||
sb.append(OffsetFont.NEG_1.character());
|
||||
@@ -99,6 +117,7 @@ public class NameplateImpl implements Nameplate {
|
||||
@Override
|
||||
public String createImageSuffix(float advance, float leftMargin, float rightMargin) {
|
||||
if (advance <= 0) return "";
|
||||
advance = Math.max(minWidth, advance);
|
||||
int mid_amount = (int) Math.ceil((advance + leftMargin + rightMargin) / (middle.advance() - 1));
|
||||
float exceed = mid_amount * (middle.advance() - 1) - advance - leftMargin - rightMargin;
|
||||
return OffsetFont.shortestPosChars((float) Math.ceil(exceed / 2) + rightMargin + right.advance());
|
||||
@@ -108,6 +127,7 @@ public class NameplateImpl implements Nameplate {
|
||||
@Override
|
||||
public String createImage(float advance, float leftMargin, float rightMargin) {
|
||||
if (advance <= 0) return "";
|
||||
advance = Math.max(minWidth, advance);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(left.character());
|
||||
sb.append(OffsetFont.NEG_1.character());
|
||||
@@ -124,13 +144,17 @@ public class NameplateImpl implements Nameplate {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The builder implementation
|
||||
*/
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private String commandSuggestion;
|
||||
private String displayName;
|
||||
private ConfiguredCharacter left;
|
||||
private ConfiguredCharacter middle;
|
||||
private ConfiguredCharacter right;
|
||||
private int minWidth;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
@@ -138,12 +162,24 @@ public class NameplateImpl implements Nameplate {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder commandSuggestion(String commandSuggestion) {
|
||||
this.commandSuggestion = commandSuggestion;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder displayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder minWidth(int minWidth) {
|
||||
this.minWidth = minWidth;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder left(ConfiguredCharacter left) {
|
||||
this.left = left;
|
||||
@@ -164,7 +200,7 @@ public class NameplateImpl implements Nameplate {
|
||||
|
||||
@Override
|
||||
public Nameplate build() {
|
||||
return new NameplateImpl(id, displayName, left, middle, right);
|
||||
return new NameplateImpl(id, Optional.ofNullable(commandSuggestion).orElse(id), displayName, minWidth, left, middle, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -23,6 +23,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Manages the nameplates system, providing functionality to retrieve, check access,
|
||||
* and manipulate nameplates associated with players.
|
||||
*/
|
||||
public interface NameplateManager extends Reloadable {
|
||||
|
||||
/**
|
||||
@@ -34,6 +38,15 @@ public interface NameplateManager extends Reloadable {
|
||||
@Nullable
|
||||
Nameplate nameplateById(String id);
|
||||
|
||||
/**
|
||||
* Retrieves a Nameplate by command suggestion.
|
||||
*
|
||||
* @param suggestion the command suggestion of the nameplate
|
||||
* @return the Nameplate instance, or null if not found
|
||||
*/
|
||||
@Nullable
|
||||
Nameplate nameplateByCommand(String suggestion);
|
||||
|
||||
/**
|
||||
* Returns a collection of all available nameplates.
|
||||
*
|
||||
|
||||
+3
@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.feature.pack;
|
||||
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
|
||||
/**
|
||||
* Interface to manager resource packs
|
||||
*/
|
||||
public interface ResourcePackManager extends Reloadable {
|
||||
|
||||
/**
|
||||
|
||||
+48
-11
@@ -28,23 +28,63 @@ import java.util.UUID;
|
||||
import java.util.Vector;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Represents an abstract tag for a {@link CNPlayer} that can be shown to specific viewers.
|
||||
* This class handles the rendering of the tag, showing and hiding it for specific players,
|
||||
* and managing tag attributes such as opacity and scale.
|
||||
*/
|
||||
public abstract class AbstractTag implements Tag {
|
||||
|
||||
/**
|
||||
* The owner of this tag
|
||||
*/
|
||||
protected CNPlayer owner;
|
||||
/**
|
||||
* The {@link TagRenderer} responsible for rendering this tag.
|
||||
*/
|
||||
protected TagRenderer renderer;
|
||||
/**
|
||||
* The unique UUID assigned to this tag.
|
||||
*/
|
||||
protected final UUID uuid = UUID.randomUUID();
|
||||
/**
|
||||
* The unique entity ID assigned to this tag, used to track visibility and actions.
|
||||
*/
|
||||
protected final int entityID = SelfIncreaseEntityID.getAndIncrease();
|
||||
|
||||
/**
|
||||
* A flag indicating whether the tag is currently visible to viewers.
|
||||
*/
|
||||
protected boolean isShown = false;
|
||||
|
||||
/**
|
||||
* A list of players who are currently viewing this tag.
|
||||
*/
|
||||
protected final Vector<CNPlayer> viewers = new Vector<>();
|
||||
/**
|
||||
* An array representation of the viewers, used for optimization.
|
||||
*/
|
||||
protected CNPlayer[] viewerArray = new CNPlayer[0];
|
||||
|
||||
public AbstractTag(CNPlayer owner, TagRenderer renderer) {
|
||||
/**
|
||||
* Constructs a new {@link AbstractTag} for the given {@link CNPlayer} owner and
|
||||
* {@link TagRenderer}.
|
||||
*
|
||||
* @param owner the {@link CNPlayer} who owns this tag
|
||||
* @param renderer the {@link TagRenderer} used to render this tag
|
||||
*/
|
||||
protected AbstractTag(CNPlayer owner, TagRenderer renderer) {
|
||||
this.owner = owner;
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
public CNPlayer[] viewerArray() {
|
||||
return this.viewerArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns the tag for the given viewer by sending a packet to the viewer.
|
||||
*
|
||||
* @param viewer the {@link CNPlayer} who will see the tag
|
||||
* @return a list of objects representing the spawn packet for the tag
|
||||
*/
|
||||
protected abstract List<Object> spawnPacket(CNPlayer viewer);
|
||||
|
||||
@Override
|
||||
@@ -76,6 +116,7 @@ public abstract class AbstractTag implements Tag {
|
||||
|
||||
@Override
|
||||
public void show(CNPlayer viewer) {
|
||||
if (!renderer.isValid()) return;
|
||||
if (!isShown()) throw new IllegalStateException("This tag is currently hidden");
|
||||
viewers.add(viewer);
|
||||
resetViewerArray();
|
||||
@@ -125,13 +166,6 @@ public abstract class AbstractTag implements Tag {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void darkTag(CNPlayer viewer, boolean dark) {
|
||||
Consumer<List<Object>> modifiers = CustomNameplates.getInstance().getPlatform().createOpacityModifier(dark ? 64 : opacity());
|
||||
Object packet = CustomNameplates.getInstance().getPlatform().updateTextDisplayPacket(entityID, List.of(modifiers));
|
||||
CustomNameplates.getInstance().getPacketSender().sendPacket(viewer, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerScaleUpdate(double scale) {
|
||||
for (CNPlayer viewer : viewerArray) {
|
||||
@@ -187,6 +221,9 @@ public abstract class AbstractTag implements Tag {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the viewer array
|
||||
*/
|
||||
protected void resetViewerArray() {
|
||||
this.viewerArray = viewers.toArray(new CNPlayer[0]);
|
||||
}
|
||||
|
||||
+22
-3
@@ -20,8 +20,13 @@ package net.momirealms.customnameplates.api.feature.tag;
|
||||
import net.momirealms.customnameplates.api.feature.CarouselText;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
import net.momirealms.customnameplates.api.util.Alignment;
|
||||
import net.momirealms.customnameplates.api.util.Billboard;
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
import net.momirealms.customnameplates.common.util.Tristate;
|
||||
|
||||
/**
|
||||
* NameTag Configuration
|
||||
*/
|
||||
public interface NameTagConfig {
|
||||
|
||||
/**
|
||||
@@ -73,12 +78,18 @@ public interface NameTagConfig {
|
||||
*/
|
||||
boolean hasShadow();
|
||||
|
||||
/**
|
||||
* Gets the billboard
|
||||
*
|
||||
* @return billboard
|
||||
*/
|
||||
Billboard billboard();
|
||||
|
||||
/**
|
||||
* Checks if the name tag is see-through.
|
||||
*
|
||||
* @return true if the name tag is see-through, false otherwise
|
||||
*/
|
||||
boolean isSeeThrough();
|
||||
Tristate isSeeThrough();
|
||||
|
||||
/**
|
||||
* Checks if the default background color is used.
|
||||
@@ -241,7 +252,7 @@ public interface NameTagConfig {
|
||||
* @param seeThrough true if the name tag is see-through, false otherwise
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder seeThrough(boolean seeThrough);
|
||||
Builder seeThrough(Tristate seeThrough);
|
||||
|
||||
/**
|
||||
* Sets whether the name tag uses the default background color.
|
||||
@@ -259,6 +270,14 @@ public interface NameTagConfig {
|
||||
*/
|
||||
Builder alignment(Alignment alignment);
|
||||
|
||||
/**
|
||||
* Sets the billboard of the name tag
|
||||
*
|
||||
* @param billboard billboard
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder billboard(Billboard billboard);
|
||||
|
||||
/**
|
||||
* Sets the view range for the name tag.
|
||||
*
|
||||
|
||||
+28
-7
@@ -20,10 +20,14 @@ package net.momirealms.customnameplates.api.feature.tag;
|
||||
import net.momirealms.customnameplates.api.feature.CarouselText;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
import net.momirealms.customnameplates.api.util.Alignment;
|
||||
import net.momirealms.customnameplates.api.util.Billboard;
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
import net.momirealms.customnameplates.common.util.Tristate;
|
||||
|
||||
/**
|
||||
* Implementation of NameTagConfig
|
||||
*/
|
||||
public class NameTagConfigImpl implements NameTagConfig {
|
||||
|
||||
private final String id;
|
||||
private final Requirement[] ownerRequirements;
|
||||
private final Requirement[] viewerRequirements;
|
||||
@@ -32,9 +36,10 @@ public class NameTagConfigImpl implements NameTagConfig {
|
||||
private final byte opacity;
|
||||
private final int backgroundColor;
|
||||
private final boolean hasShadow;
|
||||
private final boolean isSeeThrough;
|
||||
private final Tristate isSeeThrough;
|
||||
private final boolean useDefaultBackgroundColor;
|
||||
private final Alignment alignment;
|
||||
private final Billboard billboard;
|
||||
private final float viewRange;
|
||||
private final float shadowRadius;
|
||||
private final float shadowStrength;
|
||||
@@ -44,7 +49,7 @@ public class NameTagConfigImpl implements NameTagConfig {
|
||||
private final boolean affectedByScale;
|
||||
private final boolean affectedBySpectator;
|
||||
|
||||
public NameTagConfigImpl(String id, Requirement[] ownerRequirements, Requirement[] viewerRequirements, CarouselText[] carouselTexts, int lineWidth, byte opacity, int backgroundColor, boolean hasShadow, boolean isSeeThrough, boolean useDefaultBackgroundColor, Alignment alignment, float viewRange, float shadowRadius, float shadowStrength, Vector3 scale, Vector3 translation, boolean affectedByCrouching, boolean affectedByScale, boolean affectedBySpectator) {
|
||||
private NameTagConfigImpl(String id, Requirement[] ownerRequirements, Requirement[] viewerRequirements, CarouselText[] carouselTexts, int lineWidth, byte opacity, int backgroundColor, boolean hasShadow, Tristate isSeeThrough, boolean useDefaultBackgroundColor, Alignment alignment, Billboard billboard, float viewRange, float shadowRadius, float shadowStrength, Vector3 scale, Vector3 translation, boolean affectedByCrouching, boolean affectedByScale, boolean affectedBySpectator) {
|
||||
this.id = id;
|
||||
this.ownerRequirements = ownerRequirements;
|
||||
this.viewerRequirements = viewerRequirements;
|
||||
@@ -55,6 +60,7 @@ public class NameTagConfigImpl implements NameTagConfig {
|
||||
this.isSeeThrough = isSeeThrough;
|
||||
this.useDefaultBackgroundColor = useDefaultBackgroundColor;
|
||||
this.alignment = alignment;
|
||||
this.billboard = billboard;
|
||||
this.viewRange = viewRange;
|
||||
this.shadowRadius = shadowRadius;
|
||||
this.shadowStrength = shadowStrength;
|
||||
@@ -102,7 +108,12 @@ public class NameTagConfigImpl implements NameTagConfig {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSeeThrough() {
|
||||
public Billboard billboard() {
|
||||
return billboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tristate isSeeThrough() {
|
||||
return isSeeThrough;
|
||||
}
|
||||
|
||||
@@ -161,6 +172,9 @@ public class NameTagConfigImpl implements NameTagConfig {
|
||||
return lineWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* The builder implementation
|
||||
*/
|
||||
public static class BuilderImpl implements Builder {
|
||||
private String id;
|
||||
private Requirement[] ownerRequirements;
|
||||
@@ -170,9 +184,10 @@ public class NameTagConfigImpl implements NameTagConfig {
|
||||
private byte opacity;
|
||||
private int backgroundColor;
|
||||
private boolean hasShadow;
|
||||
private boolean isSeeThrough;
|
||||
private Tristate isSeeThrough;
|
||||
private boolean useDefaultBackgroundColor;
|
||||
private Alignment alignment;
|
||||
private Billboard billboard;
|
||||
private float viewRange;
|
||||
private float shadowRadius;
|
||||
private float shadowStrength;
|
||||
@@ -231,7 +246,7 @@ public class NameTagConfigImpl implements NameTagConfig {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder seeThrough(boolean seeThrough) {
|
||||
public Builder seeThrough(Tristate seeThrough) {
|
||||
this.isSeeThrough = seeThrough;
|
||||
return this;
|
||||
}
|
||||
@@ -248,6 +263,12 @@ public class NameTagConfigImpl implements NameTagConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder billboard(Billboard billboard) {
|
||||
this.billboard = billboard;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder viewRange(float viewRange) {
|
||||
this.viewRange = viewRange;
|
||||
@@ -298,7 +319,7 @@ public class NameTagConfigImpl implements NameTagConfig {
|
||||
|
||||
@Override
|
||||
public NameTagConfig build() {
|
||||
return new NameTagConfigImpl(id, ownerRequirements, viewerRequirements, carouselTexts, lineWidth, opacity, backgroundColor, hasShadow, isSeeThrough, useDefaultBackgroundColor, alignment, viewRange, shadowRadius, shadowStrength, scale, translation, affectedByCrouching, affectedByScale, affectedBySpectator);
|
||||
return new NameTagConfigImpl(id, ownerRequirements, viewerRequirements, carouselTexts, lineWidth, opacity, backgroundColor, hasShadow, isSeeThrough, useDefaultBackgroundColor, alignment, billboard, viewRange, shadowRadius, shadowStrength, scale, translation, affectedByCrouching, affectedByScale, affectedBySpectator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,9 @@ import net.momirealms.customnameplates.api.util.Vector3;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a tag
|
||||
*/
|
||||
public interface Tag {
|
||||
|
||||
/**
|
||||
@@ -59,6 +62,11 @@ public interface Tag {
|
||||
*/
|
||||
boolean affectedByScaling();
|
||||
|
||||
/**
|
||||
* Checks if the tag is affected by spectator mode.
|
||||
*
|
||||
* @return true if affected by spectator mode, false otherwise
|
||||
*/
|
||||
boolean affectedBySpectator();
|
||||
|
||||
/**
|
||||
@@ -189,6 +197,8 @@ public interface Tag {
|
||||
|
||||
/**
|
||||
* Updates the translation of the tag for a certain player
|
||||
*
|
||||
* @param viewer the player to update
|
||||
*/
|
||||
void updateTranslation(CNPlayer viewer);
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.feature.tag;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* An interface to control the rendering of tags
|
||||
*/
|
||||
public interface TagRenderer {
|
||||
|
||||
/**
|
||||
@@ -35,6 +38,13 @@ public interface TagRenderer {
|
||||
*/
|
||||
void hatOffset(double hatOffset);
|
||||
|
||||
/**
|
||||
* Checks if the tag is valid
|
||||
*
|
||||
* @return valid or not
|
||||
*/
|
||||
boolean isValid();
|
||||
|
||||
/**
|
||||
* Called every tick to update the state of the tags managed by this renderer.
|
||||
*/
|
||||
|
||||
@@ -17,26 +17,57 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.feature.tag;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents a view of teams and their associated members.
|
||||
* <p>
|
||||
* This class allows you to manage a collection of teams, with each team having a set of member names.
|
||||
* You can add or remove members from teams, retrieve the list of members for a specific team,
|
||||
* or remove entire teams.
|
||||
* </p>
|
||||
*/
|
||||
public class TeamView {
|
||||
/**
|
||||
* A map that stores the team names as keys and their associated members as values.
|
||||
* The members are stored as a set of strings to avoid duplicates.
|
||||
*/
|
||||
private final Map<String, Set<String>> teamMembers = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
private final HashMap<String, Set<String>> teamMembers = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Retrieves the members of a given team.
|
||||
*
|
||||
* @param team the name of the team
|
||||
* @return a set of member names, or {@code null} if the team does not exist
|
||||
*/
|
||||
@Nullable
|
||||
public Set<String> getTeamMembers(String team) {
|
||||
return teamMembers.get(team);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a collection of members to a team. If the team does not exist, it will be created.
|
||||
*
|
||||
* @param team the name of the team
|
||||
* @param members the collection of members to add
|
||||
*/
|
||||
public void addTeamMembers(String team, Collection<String> members) {
|
||||
teamMembers.computeIfAbsent(team, k -> new HashSet<>(members));
|
||||
teamMembers.computeIfAbsent(team, k -> new ObjectOpenHashSet<>(members));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a collection of members from a team. If the team exists, the members will be removed
|
||||
* from the team's member set.
|
||||
*
|
||||
* @param team the name of the team
|
||||
* @param members the collection of members to remove
|
||||
*/
|
||||
public void removeTeamMembers(String team, Collection<String> members) {
|
||||
Set<String> membersSet = teamMembers.get(team);
|
||||
if (membersSet != null) {
|
||||
@@ -44,6 +75,11 @@ public class TeamView {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an entire team and all its members.
|
||||
*
|
||||
* @param team the name of the team to remove
|
||||
*/
|
||||
public void removeTeam(String team) {
|
||||
this.teamMembers.remove(team);
|
||||
}
|
||||
|
||||
+5
-1
@@ -18,11 +18,15 @@
|
||||
package net.momirealms.customnameplates.api.feature.tag;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.feature.JoinQuitListener;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface UnlimitedTagManager extends Reloadable {
|
||||
/**
|
||||
* An interface manages unlimited tags
|
||||
*/
|
||||
public interface UnlimitedTagManager extends Reloadable, JoinQuitListener {
|
||||
|
||||
/**
|
||||
* Called every tick to update the state of tags.
|
||||
|
||||
@@ -23,6 +23,8 @@ import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.json.JSONOptions;
|
||||
import net.kyori.adventure.text.serializer.json.legacyimpl.NBTLegacyHoverEventSerializer;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
|
||||
@@ -35,10 +37,14 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
public class AdventureHelper {
|
||||
|
||||
/**
|
||||
* Whether to enable legacy color code support
|
||||
*/
|
||||
public static boolean legacySupport = false;
|
||||
|
||||
private final MiniMessage miniMessage;
|
||||
private final MiniMessage miniMessageStrict;
|
||||
private final GsonComponentSerializer gsonComponentSerializer;
|
||||
public static boolean legacySupport = false;
|
||||
|
||||
private final Cache<String, Component> miniMessageToComponentCache;
|
||||
private final Cache<String, Object> miniMessageToMinecraftComponentCache;
|
||||
@@ -48,7 +54,19 @@ public class AdventureHelper {
|
||||
private AdventureHelper() {
|
||||
this.miniMessage = MiniMessage.builder().build();
|
||||
this.miniMessageStrict = MiniMessage.builder().strict(true).build();
|
||||
this.gsonComponentSerializer = GsonComponentSerializer.builder().build();
|
||||
GsonComponentSerializer.Builder builder = GsonComponentSerializer.builder();
|
||||
if (!VersionHelper.isVersionNewerThan1_20_5()) {
|
||||
builder.legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.get());
|
||||
builder.editOptions((b) -> b.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_ID_AS_INT_ARRAY, false));
|
||||
}
|
||||
if (!VersionHelper.isVersionNewerThan1_21_5()) {
|
||||
builder.editOptions((b) -> {
|
||||
b.value(JSONOptions.EMIT_CLICK_EVENT_TYPE, JSONOptions.ClickEventValueMode.CAMEL_CASE);
|
||||
b.value(JSONOptions.EMIT_HOVER_EVENT_TYPE, JSONOptions.HoverEventValueMode.CAMEL_CASE);
|
||||
b.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_KEY_AS_TYPE_AND_UUID_AS_ID, true);
|
||||
});
|
||||
}
|
||||
this.gsonComponentSerializer = builder.build();
|
||||
|
||||
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, r -> {
|
||||
Thread thread = Executors.defaultThreadFactory().newThread(r);
|
||||
@@ -84,6 +102,9 @@ public class AdventureHelper {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache
|
||||
*/
|
||||
public static void clearCache() {
|
||||
AdventureHelper instance = getInstance();
|
||||
instance.miniMessageToMinecraftComponentCache.cleanUp();
|
||||
@@ -217,8 +238,14 @@ public class AdventureHelper {
|
||||
return "<#FFFEFD>" + text + "</#FFFEFD>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes shadow from the provided text using a specific color code.
|
||||
*
|
||||
* @param text the text to modify
|
||||
* @return the text wrapped in a color tag to remove shadows
|
||||
*/
|
||||
public static String removeShadow(String text) {
|
||||
return "<#F0F0F0>" + text + "</#F0F0F0>";
|
||||
return "<shadow:#00000000><#F0F0F0>" + text + "</#F0F0F0></shadow>";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,19 +320,19 @@ public class AdventureHelper {
|
||||
case '7' -> stringBuilder.append("<gray>");
|
||||
case '8' -> stringBuilder.append("<dark_gray>");
|
||||
case '9' -> stringBuilder.append("<blue>");
|
||||
case 'a' -> stringBuilder.append("<green>");
|
||||
case 'b' -> stringBuilder.append("<aqua>");
|
||||
case 'c' -> stringBuilder.append("<red>");
|
||||
case 'd' -> stringBuilder.append("<light_purple>");
|
||||
case 'e' -> stringBuilder.append("<yellow>");
|
||||
case 'f' -> stringBuilder.append("<white>");
|
||||
case 'r' -> stringBuilder.append("<reset>");
|
||||
case 'l' -> stringBuilder.append("<b>");
|
||||
case 'm' -> stringBuilder.append("<st>");
|
||||
case 'o' -> stringBuilder.append("<i>");
|
||||
case 'n' -> stringBuilder.append("<u>");
|
||||
case 'k' -> stringBuilder.append("<obf>");
|
||||
case 'x' -> {
|
||||
case 'a', 'A' -> stringBuilder.append("<green>");
|
||||
case 'b', 'B' -> stringBuilder.append("<aqua>");
|
||||
case 'c', 'C' -> stringBuilder.append("<red>");
|
||||
case 'd', 'D' -> stringBuilder.append("<light_purple>");
|
||||
case 'e', 'E' -> stringBuilder.append("<yellow>");
|
||||
case 'f', 'F' -> stringBuilder.append("<white>");
|
||||
case 'r', 'R' -> stringBuilder.append("<reset>");
|
||||
case 'l', 'L' -> stringBuilder.append("<b>");
|
||||
case 'm', 'M' -> stringBuilder.append("<st>");
|
||||
case 'o', 'O' -> stringBuilder.append("<i>");
|
||||
case 'n', 'N' -> stringBuilder.append("<u>");
|
||||
case 'k', 'K' -> stringBuilder.append("<obf>");
|
||||
case 'x', 'X' -> {
|
||||
if (i + 13 >= chars.length
|
||||
|| !isLegacyColorCode(chars[i+2])
|
||||
|| !isLegacyColorCode(chars[i+4])
|
||||
@@ -327,6 +354,28 @@ public class AdventureHelper {
|
||||
.append(">");
|
||||
i += 12;
|
||||
}
|
||||
case '#' -> {
|
||||
if (i + 7 >= chars.length
|
||||
|| !isHexColorCode(chars[i+2])
|
||||
|| !isHexColorCode(chars[i+3])
|
||||
|| !isHexColorCode(chars[i+4])
|
||||
|| !isHexColorCode(chars[i+5])
|
||||
|| !isHexColorCode(chars[i+6])
|
||||
|| !isHexColorCode(chars[i+7])) {
|
||||
stringBuilder.append(chars[i]);
|
||||
continue;
|
||||
}
|
||||
stringBuilder
|
||||
.append("<#")
|
||||
.append(chars[i+2])
|
||||
.append(chars[i+3])
|
||||
.append(chars[i+4])
|
||||
.append(chars[i+5])
|
||||
.append(chars[i+6])
|
||||
.append(chars[i+7])
|
||||
.append(">");
|
||||
i += 6;
|
||||
}
|
||||
default -> {
|
||||
stringBuilder.append(chars[i]);
|
||||
continue;
|
||||
@@ -336,4 +385,10 @@ public class AdventureHelper {
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private static boolean isHexColorCode(char c) {
|
||||
return c >= '0' && c <= '9' ||
|
||||
c >= 'a' && c <= 'f' ||
|
||||
c >= 'A' && c <= 'F';
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,9 @@ public class GsonHelper {
|
||||
|
||||
private final Gson gson;
|
||||
|
||||
/**
|
||||
* Create the gson
|
||||
*/
|
||||
public GsonHelper() {
|
||||
this.gson = new GsonBuilder()
|
||||
.create();
|
||||
|
||||
@@ -28,11 +28,14 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* This class implements the VersionManager interface and is responsible for managing version-related information.
|
||||
* VersionHelper is a utility class that provides methods for managing and checking version-related information,
|
||||
* including plugin updates and server version details. It implements the VersionManager interface.
|
||||
*/
|
||||
public class VersionHelper {
|
||||
|
||||
// Method to asynchronously check for plugin updates
|
||||
/**
|
||||
* A function to check for plugin updates asynchronously by comparing the plugin's current version with the latest version available.
|
||||
*/
|
||||
public static final Function<NameplatesPlugin, CompletableFuture<Boolean>> UPDATE_CHECKER = (plugin) -> {
|
||||
CompletableFuture<Boolean> updateFuture = new CompletableFuture<>();
|
||||
plugin.getScheduler().async().execute(() -> {
|
||||
@@ -58,23 +61,80 @@ public class VersionHelper {
|
||||
return updateFuture;
|
||||
};
|
||||
|
||||
private static float version;
|
||||
private static int version;
|
||||
private static boolean mojmap;
|
||||
private static boolean folia;
|
||||
private static boolean mohist;
|
||||
private static boolean paper;
|
||||
|
||||
/**
|
||||
* Initializes version-specific settings based on the server version.
|
||||
* This method checks if the server is running Mojmap, Folia, Mohist, or Paper.
|
||||
*
|
||||
* @param serverVersion The server version string.
|
||||
*/
|
||||
public static void init(String serverVersion) {
|
||||
String[] split = serverVersion.split("\\.");
|
||||
version = Float.parseFloat(split[1] + "." + (split.length == 3 ? split[2] : "0"));
|
||||
version = parseVersionToInteger(serverVersion);
|
||||
checkMojMap();
|
||||
checkFolia();
|
||||
checkMohist();
|
||||
checkPaper();
|
||||
boolean isModdedServer = mohist;
|
||||
paper = paper && !isModdedServer;
|
||||
}
|
||||
|
||||
public static int parseVersionToInteger(String versionString) {
|
||||
int v1 = 0;
|
||||
int v2 = 0;
|
||||
int v3 = 0;
|
||||
int currentNumber = 0;
|
||||
int part = 0;
|
||||
|
||||
for(int i = 0; i < versionString.length(); ++i) {
|
||||
char c = versionString.charAt(i);
|
||||
if (c >= '0' && c <= '9') {
|
||||
currentNumber = currentNumber * 10 + (c - 48);
|
||||
} else if (c == '.') {
|
||||
if (part == 0) {
|
||||
v1 = currentNumber;
|
||||
}
|
||||
|
||||
if (part == 1) {
|
||||
v2 = currentNumber;
|
||||
}
|
||||
|
||||
++part;
|
||||
currentNumber = 0;
|
||||
if (part > 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (part == 0) {
|
||||
v1 = currentNumber;
|
||||
} else if (part == 1) {
|
||||
v2 = currentNumber;
|
||||
} else if (part == 2) {
|
||||
v3 = currentNumber;
|
||||
}
|
||||
|
||||
return 10000 * v1 + v2 * 100 + v3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current server version as a float.
|
||||
*
|
||||
* @return The server version as a float.
|
||||
*/
|
||||
public static float version() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server is running Mojmap.
|
||||
*/
|
||||
private static void checkMojMap() {
|
||||
// Check if the server is Mojmap
|
||||
try {
|
||||
Class.forName("net.minecraft.network.protocol.game.ClientboundBossEventPacket");
|
||||
mojmap = true;
|
||||
@@ -82,6 +142,9 @@ public class VersionHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server is running Folia.
|
||||
*/
|
||||
private static void checkFolia() {
|
||||
try {
|
||||
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
|
||||
@@ -90,39 +153,156 @@ public class VersionHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server is running Mohist.
|
||||
*/
|
||||
private static void checkMohist() {
|
||||
try {
|
||||
Class.forName("com.mohistmc.api.ServerAPI");
|
||||
mohist = true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server is running Paper or its forks.
|
||||
*/
|
||||
private static void checkPaper() {
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paper.Metrics");
|
||||
paper = true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isVersionNewerThan26_1() {
|
||||
return version >= 260100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server version is newer than 1.21.9
|
||||
*
|
||||
* @return True if the version is newer than 1.21.9, otherwise false.
|
||||
*/
|
||||
public static boolean isVersionNewerThan1_21_9() {
|
||||
return version >= 12109;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server version is newer than 1.21.5
|
||||
*
|
||||
* @return True if the version is newer than 1.21.5, otherwise false.
|
||||
*/
|
||||
public static boolean isVersionNewerThan1_21_5() {
|
||||
return version >= 12105;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server version is newer than 1.21.4
|
||||
*
|
||||
* @return True if the version is newer than 1.21.4, otherwise false.
|
||||
*/
|
||||
public static boolean isVersionNewerThan1_21_4() {
|
||||
return version >= 12104;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server version is newer than 1.21.2.
|
||||
*
|
||||
* @return True if the version is newer than 1.21.2, otherwise false.
|
||||
*/
|
||||
public static boolean isVersionNewerThan1_21_2() {
|
||||
return version >= 21.19;
|
||||
return version >= 12102;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server version is newer than 1.20.5.
|
||||
*
|
||||
* @return True if the version is newer than 1.20.5, otherwise false.
|
||||
*/
|
||||
public static boolean isVersionNewerThan1_20_5() {
|
||||
return version >= 20.49;
|
||||
return version >= 12005;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server version is newer than 1.20.4.
|
||||
*
|
||||
* @return True if the version is newer than 1.20.4, otherwise false.
|
||||
*/
|
||||
public static boolean isVersionNewerThan1_20_4() {
|
||||
return version >= 20.39;
|
||||
return version >= 12004;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server version is newer than 1.19.4.
|
||||
*
|
||||
* @return True if the version is newer than 1.19.4, otherwise false.
|
||||
*/
|
||||
public static boolean isVersionNewerThan1_19_4() {
|
||||
return version >= 19.39;
|
||||
return version >= 11904;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server version is newer than 1.20.2.
|
||||
*
|
||||
* @return True if the version is newer than 1.20.2, otherwise false.
|
||||
*/
|
||||
public static boolean isVersionNewerThan1_20_2() {
|
||||
return version >= 20.19;
|
||||
return version >= 12002;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server version is newer than 1.20.
|
||||
*
|
||||
* @return True if the version is newer than 1.20, otherwise false.
|
||||
*/
|
||||
public static boolean isVersionNewerThan1_20() {
|
||||
return version >= 20;
|
||||
return version >= 12000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server is running Folia.
|
||||
*
|
||||
* @return True if the server is running Folia, otherwise false.
|
||||
*/
|
||||
public static boolean isFolia() {
|
||||
return folia;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server is running Mohist.
|
||||
*
|
||||
* @return True if the server is running Mohist, otherwise false.
|
||||
*/
|
||||
public static boolean isMohist() {
|
||||
return mohist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server is running Paper or its forks.
|
||||
*
|
||||
* @return True if the server is running Paper or its forks, otherwise false.
|
||||
*/
|
||||
public static boolean isPaperOrItsForks() {
|
||||
return paper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server is using Mojmap.
|
||||
*
|
||||
* @return True if the server is using Mojmap, otherwise false.
|
||||
*/
|
||||
public static boolean isMojmap() {
|
||||
return mojmap;
|
||||
}
|
||||
|
||||
// Method to compare two version strings
|
||||
/**
|
||||
* Compares two version strings to determine if the first version is newer than the second.
|
||||
*
|
||||
* @param newV The new version string.
|
||||
* @param currentV The current version string.
|
||||
* @return True if the new version is newer than the current version, otherwise false.
|
||||
*/
|
||||
private static boolean compareVer(String newV, String currentV) {
|
||||
if (newV == null || currentV == null || newV.isEmpty() || currentV.isEmpty()) {
|
||||
return false;
|
||||
@@ -140,31 +320,11 @@ public class VersionHelper {
|
||||
return true;
|
||||
} else if (newNum < currentNum) {
|
||||
return false;
|
||||
} else if (newPart.length > 1 && currentPart.length > 1) {
|
||||
String[] newHotfix = newPart[1].split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
|
||||
String[] currentHotfix = currentPart[1].split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
|
||||
if (newHotfix.length == 2 && currentHotfix.length == 1) return true;
|
||||
else if (newHotfix.length > 1 && currentHotfix.length > 1) {
|
||||
int newHotfixNum = Integer.parseInt(newHotfix[1]);
|
||||
int currentHotfixNum = Integer.parseInt(currentHotfix[1]);
|
||||
if (newHotfixNum > currentHotfixNum) {
|
||||
return true;
|
||||
} else if (newHotfixNum < currentHotfixNum) {
|
||||
return false;
|
||||
} else {
|
||||
return newHotfix[0].compareTo(currentHotfix[0]) > 0;
|
||||
}
|
||||
}
|
||||
} else if (newPart.length > 1) {
|
||||
return true;
|
||||
} else if (currentPart.length > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException ignored) {
|
||||
return false;
|
||||
} catch (NumberFormatException e) {
|
||||
// handle error
|
||||
}
|
||||
}
|
||||
return newVS.length > currentVS.length;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,18 +19,12 @@ package net.momirealms.customnameplates.api.network;
|
||||
|
||||
import net.momirealms.customnameplates.common.event.Cancellable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents a packet event, which can be cancelled and supports delayed tasks that are executed later.
|
||||
*/
|
||||
public class PacketEvent implements Cancellable {
|
||||
|
||||
private boolean cancelled;
|
||||
private List<Runnable> delayedTasks = null;
|
||||
private final Object packet;
|
||||
|
||||
/**
|
||||
@@ -51,27 +45,6 @@ public class PacketEvent implements Cancellable {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a task to be executed later, after the event has been processed.
|
||||
*
|
||||
* @param task the task to be added
|
||||
*/
|
||||
public void addDelayedTask(Runnable task) {
|
||||
if (delayedTasks == null) {
|
||||
delayedTasks = new ArrayList<>();
|
||||
}
|
||||
delayedTasks.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of delayed tasks to be executed.
|
||||
*
|
||||
* @return a list of tasks, or an empty list if no tasks are added
|
||||
*/
|
||||
public List<Runnable> getDelayedTasks() {
|
||||
return Optional.ofNullable(delayedTasks).orElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the event has been cancelled.
|
||||
*
|
||||
|
||||
@@ -27,15 +27,43 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
*/
|
||||
public interface PipelineInjector {
|
||||
|
||||
/**
|
||||
* Sets the user (player) associated with the given Netty channel.
|
||||
* This is an internal method for managing the mapping between a channel and a player.
|
||||
*
|
||||
* @param channel the Netty channel to associate with the player
|
||||
* @param user the player to associate with the channel
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
void setUser(Channel channel, CNPlayer user);
|
||||
|
||||
/**
|
||||
* Retrieves the player associated with the given Netty channel.
|
||||
* This is an internal method for fetching the player mapped to a specific channel.
|
||||
*
|
||||
* @param channel the Netty channel for which the player is being retrieved
|
||||
* @return the player associated with the given channel
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
CNPlayer getUser(Channel channel);
|
||||
|
||||
/**
|
||||
* Removes the player associated with the specified Netty channel.
|
||||
* This is an internal method for detaching a player from the given channel.
|
||||
*
|
||||
* @param channel the Netty channel from which the player will be removed
|
||||
* @return the player that was removed, or null if no player was associated
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
CNPlayer removeUser(Channel channel);
|
||||
|
||||
/**
|
||||
* Retrieves the player associated with the specified object.
|
||||
* This method is internal and can be used to get a player from various representations.
|
||||
*
|
||||
* @param player the object representing the player (could be a reference or other object type)
|
||||
* @return the player associated with the object
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
CNPlayer getUser(Object player);
|
||||
|
||||
|
||||
@@ -17,25 +17,27 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.network;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Represents a tracker for a specific player. This class stores and manages the state of the player
|
||||
* being tracked, including their crouching status, scale, spectator status, and passengers.
|
||||
*/
|
||||
public class Tracker {
|
||||
|
||||
private boolean isCrouching;
|
||||
private double scale;
|
||||
private boolean isSpectator;
|
||||
private final CNPlayer tracker;
|
||||
|
||||
private final CopyOnWriteArrayList<Integer> passengerIDs = new CopyOnWriteArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a new Tracker for the specified player.
|
||||
* Constructs a new Tracker
|
||||
*
|
||||
* @param tracker the player being tracked
|
||||
* @param tracker the tracker who is tracking the player
|
||||
*/
|
||||
public Tracker(CNPlayer tracker) {
|
||||
this.isCrouching = false;
|
||||
@@ -43,47 +45,102 @@ public class Tracker {
|
||||
this.tracker = tracker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the tracker
|
||||
*
|
||||
* @return the tracker
|
||||
*/
|
||||
public CNPlayer tracker() {
|
||||
return tracker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the tracked player is currently crouching.
|
||||
*
|
||||
* @return true if the player is crouching, false otherwise
|
||||
*/
|
||||
public boolean isCrouching() {
|
||||
return isCrouching;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the crouching status for the tracked player.
|
||||
*
|
||||
* @param crouching the new crouching status
|
||||
*/
|
||||
public void setCrouching(boolean crouching) {
|
||||
isCrouching = crouching;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the tracked player is in spectator mode.
|
||||
*
|
||||
* @return true if the player is a spectator, false otherwise
|
||||
*/
|
||||
public boolean isSpectator() {
|
||||
return isSpectator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the spectator status for the tracked player.
|
||||
*
|
||||
* @param spectator the new spectator status
|
||||
*/
|
||||
public void setSpectator(boolean spectator) {
|
||||
isSpectator = spectator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current scale of the tracked player.
|
||||
*
|
||||
* @return the scale of the player
|
||||
*/
|
||||
public double getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scale for the tracked player.
|
||||
*
|
||||
* @param scale the new scale value
|
||||
*/
|
||||
public void setScale(double scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a passenger ID to the list of passengers attached to the tracked player.
|
||||
*
|
||||
* @param passengerID the ID of the passenger to add
|
||||
*/
|
||||
public void addPassengerID(int passengerID) {
|
||||
this.passengerIDs.add(passengerID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a passenger ID from the list of passengers attached to the tracked player.
|
||||
*
|
||||
* @param passengerID the ID of the passenger to remove
|
||||
*/
|
||||
public void removePassengerID(int passengerID) {
|
||||
this.passengerIDs.remove((Object) passengerID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the set of passenger IDs attached to the tracked player.
|
||||
*
|
||||
* @return a set of passenger IDs
|
||||
*/
|
||||
public Set<Integer> getPassengerIDs() {
|
||||
return new HashSet<>(passengerIDs);
|
||||
return new ObjectOpenHashSet<>(passengerIDs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the tracked player has no passengers attached.
|
||||
*
|
||||
* @return true if the player has no passengers, false otherwise
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return passengerIDs.isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
+31
-4
@@ -17,21 +17,48 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.placeholder;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* An abstract placeholder class
|
||||
*/
|
||||
public abstract class AbstractPlaceholder implements Placeholder {
|
||||
|
||||
/**
|
||||
* Placeholder in string format
|
||||
*/
|
||||
protected String id;
|
||||
/**
|
||||
* The internal id
|
||||
*/
|
||||
protected int countId = PlaceholderCounter.getAndIncrease();
|
||||
/**
|
||||
* Refresh internal
|
||||
*/
|
||||
protected int refreshInterval;
|
||||
/**
|
||||
* The PlaceholderManager instance
|
||||
*/
|
||||
protected PlaceholderManager manager;
|
||||
protected Set<Placeholder> children = new HashSet<>();
|
||||
protected Set<Placeholder> parents = new HashSet<>();
|
||||
/**
|
||||
* The nested placeholders
|
||||
*/
|
||||
protected Set<Placeholder> children = new ObjectOpenHashSet<>();
|
||||
/**
|
||||
* The parent placeholders
|
||||
*/
|
||||
protected Set<Placeholder> parents = new ObjectOpenHashSet<>();
|
||||
|
||||
/**
|
||||
* Constructs a new placeholder
|
||||
*
|
||||
* @param manager manager
|
||||
* @param id id
|
||||
* @param refreshInterval refreshInterval
|
||||
*/
|
||||
protected AbstractPlaceholder(PlaceholderManager manager, String id, int refreshInterval) {
|
||||
if (refreshInterval == 0) {
|
||||
refreshInterval = -1;
|
||||
|
||||
@@ -19,6 +19,9 @@ package net.momirealms.customnameplates.api.placeholder;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Placeholder
|
||||
*/
|
||||
public interface Placeholder {
|
||||
|
||||
/**
|
||||
|
||||
+5
-5
@@ -17,12 +17,14 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.placeholder;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Utility class for managing a global counter for placeholder IDs.
|
||||
*/
|
||||
public class PlaceholderCounter {
|
||||
|
||||
private static int id = 1;
|
||||
private static final AtomicInteger ID = new AtomicInteger();
|
||||
|
||||
/**
|
||||
* Returns the current ID and increments the counter by 1.
|
||||
@@ -30,15 +32,13 @@ public class PlaceholderCounter {
|
||||
* @return the current ID
|
||||
*/
|
||||
public static int getAndIncrease() {
|
||||
int i = id;
|
||||
id++;
|
||||
return i;
|
||||
return ID.getAndIncrement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the ID counter back to 1.
|
||||
*/
|
||||
public static void reset() {
|
||||
id = 1;
|
||||
ID.set(1);
|
||||
}
|
||||
}
|
||||
+87
-1
@@ -19,15 +19,26 @@ package net.momirealms.customnameplates.api.placeholder.internal;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.CustomNameplatesAPI;
|
||||
import net.momirealms.customnameplates.api.feature.AdaptiveImage;
|
||||
import net.momirealms.customnameplates.api.feature.OffsetFont;
|
||||
import net.momirealms.customnameplates.api.feature.PreParsedDynamicText;
|
||||
import net.momirealms.customnameplates.api.helper.AdventureHelper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A class that represents an adaptive image combined with dynamic text, allowing
|
||||
* for the generation of image strings with custom margins, and dynamically rendered text.
|
||||
* <p>
|
||||
* This class provides methods to create the full image and text output, including
|
||||
* any necessary font and shadow adjustments based on specific settings.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of {@link AdaptiveImage} associated with this class
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public class AdaptiveImageText<T extends AdaptiveImage> {
|
||||
|
||||
private final String id;
|
||||
private final String text;
|
||||
private final T t;
|
||||
@@ -37,6 +48,17 @@ public class AdaptiveImageText<T extends AdaptiveImage> {
|
||||
private final int leftMargin;
|
||||
private final int rightMargin;
|
||||
|
||||
/**
|
||||
* Constructs an instance of {@link AdaptiveImageText} with the given parameters.
|
||||
*
|
||||
* @param id the unique identifier for this adaptive image text
|
||||
* @param text the base text to be used in the image
|
||||
* @param t the {@link AdaptiveImage} object that provides the image
|
||||
* @param removeShadowOld flag to indicate whether to remove shadow using old method
|
||||
* @param removeShadowNew flag to indicate whether to remove shadow using new method
|
||||
* @param leftMargin the left margin for positioning the image
|
||||
* @param rightMargin the right margin for positioning the image
|
||||
*/
|
||||
public AdaptiveImageText(String id, String text, T t, boolean removeShadowOld, boolean removeShadowNew, int rightMargin, int leftMargin) {
|
||||
this.text = text;
|
||||
this.id = id;
|
||||
@@ -48,22 +70,58 @@ public class AdaptiveImageText<T extends AdaptiveImage> {
|
||||
this.rightMargin = rightMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link AdaptiveImageText} with the specified parameters.
|
||||
*
|
||||
* @param id the unique identifier for this adaptive image text
|
||||
* @param text the base text to be used in the image
|
||||
* @param t the {@link AdaptiveImage} object that provides the image
|
||||
* @param removeShadowOld flag to indicate whether to remove shadow using old method
|
||||
* @param removeShadowNew flag to indicate whether to remove shadow using new method
|
||||
* @param leftMargin the left margin for positioning the image
|
||||
* @param rightMargin the right margin for positioning the image
|
||||
* @param <T> the type of {@link AdaptiveImage} associated with this class
|
||||
* @return a new instance of {@link AdaptiveImageText}
|
||||
*/
|
||||
public static <T extends AdaptiveImage> AdaptiveImageText<T> create(String id, final String text, final T t, final boolean removeShadowOld, final boolean removeShadowNew, int leftMargin, int rightMargin) {
|
||||
return new AdaptiveImageText<>(id, text, t, removeShadowOld, removeShadowNew, rightMargin, leftMargin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pre-parsed dynamic text associated with this adaptive image text.
|
||||
*
|
||||
* @return the pre-parsed dynamic text
|
||||
*/
|
||||
public PreParsedDynamicText getPreParsedDynamicText() {
|
||||
return preParsedDynamicText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unique identifier for this adaptive image text.
|
||||
*
|
||||
* @return the unique identifier
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base text associated with this adaptive image text.
|
||||
*
|
||||
* @return the base text
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the full string of text with both the prefix and suffix of the image,
|
||||
* rendering dynamic content and applying font and shadow adjustments.
|
||||
*
|
||||
* @param p1 the first {@link CNPlayer} used for dynamic text rendering
|
||||
* @param p2 the second {@link CNPlayer} used for dynamic text rendering
|
||||
* @return the full image and text string
|
||||
*/
|
||||
@NotNull
|
||||
public String getFull(CNPlayer p1, CNPlayer p2) {
|
||||
String parsed = preParsedDynamicText.fastCreate(p1).render(p2);
|
||||
@@ -83,6 +141,14 @@ public class AdaptiveImageText<T extends AdaptiveImage> {
|
||||
return prefixWithFont + parsed + suffixWithFont;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the image string with dynamic content applied, rendering
|
||||
* the image and applying font and shadow adjustments.
|
||||
*
|
||||
* @param p1 the first {@link CNPlayer} used for dynamic text rendering
|
||||
* @param p2 the second {@link CNPlayer} used for dynamic text rendering
|
||||
* @return the generated image string
|
||||
*/
|
||||
@NotNull
|
||||
public String getImage(CNPlayer p1, CNPlayer p2) {
|
||||
String parsed = preParsedDynamicText.fastCreate(p1).render(p2);
|
||||
@@ -95,8 +161,28 @@ public class AdaptiveImageText<T extends AdaptiveImage> {
|
||||
return imageWithFont;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rendered dynamic text for the specified players.
|
||||
*
|
||||
* @param p1 the first {@link CNPlayer} used for dynamic text rendering
|
||||
* @param p2 the second {@link CNPlayer} used for dynamic text rendering
|
||||
* @return the rendered dynamic text
|
||||
*/
|
||||
@NotNull
|
||||
public String getText(CNPlayer p1, CNPlayer p2) {
|
||||
return preParsedDynamicText.fastCreate(p1).render(p2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the text offset characters for the specified players.
|
||||
* The offsets are calculated based on the rendered text and its advance.
|
||||
*
|
||||
* @param p1 the first {@link CNPlayer} used for dynamic text rendering
|
||||
* @param p2 the second {@link CNPlayer} used for dynamic text rendering
|
||||
* @return the generated text offset characters
|
||||
*/
|
||||
@NotNull
|
||||
public String getTextOffsetCharacters(CNPlayer p1, CNPlayer p2) {
|
||||
return OffsetFont.createOffsets(CustomNameplatesAPI.getInstance().getTextAdvance(preParsedDynamicText.fastCreate(p1).render(p2)));
|
||||
}
|
||||
}
|
||||
+27
@@ -20,21 +20,48 @@ package net.momirealms.customnameplates.api.placeholder.internal;
|
||||
import net.momirealms.customnameplates.api.feature.PreParsedDynamicText;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
* Shift Text
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public class ShiftText {
|
||||
|
||||
/**
|
||||
* The font associated with the text.
|
||||
*/
|
||||
private final String font;
|
||||
|
||||
/**
|
||||
* The pre-parsed dynamic text, allowing for the use of placeholders and dynamic content.
|
||||
*/
|
||||
private final PreParsedDynamicText text;
|
||||
|
||||
/**
|
||||
* Constructs a ShiftText instance with the specified font and text.
|
||||
* The text is parsed dynamically for placeholders and other content.
|
||||
*
|
||||
* @param font the font to be associated with the text
|
||||
* @param text the dynamic text that may contain placeholders to be parsed
|
||||
*/
|
||||
public ShiftText(String font, String text) {
|
||||
this.font = font;
|
||||
this.text = new PreParsedDynamicText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the font associated with this ShiftText.
|
||||
*
|
||||
* @return the font as a String
|
||||
*/
|
||||
public String getFont() {
|
||||
return font;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the pre-parsed dynamic text associated with this ShiftText.
|
||||
*
|
||||
* @return the PreParsedDynamicText instance
|
||||
*/
|
||||
public PreParsedDynamicText getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
+16
-3
@@ -17,7 +17,20 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.placeholder.internal;
|
||||
|
||||
/**
|
||||
* Enum representing the static positions that an element can occupy.
|
||||
*/
|
||||
public enum StaticPosition {
|
||||
|
||||
LEFT, RIGHT, MIDDLE
|
||||
}
|
||||
/**
|
||||
* Represents the leftmost position.
|
||||
*/
|
||||
LEFT,
|
||||
/**
|
||||
* Represents the rightmost position.
|
||||
*/
|
||||
RIGHT,
|
||||
/**
|
||||
* Represents the center position.
|
||||
*/
|
||||
MIDDLE
|
||||
}
|
||||
+53
-1
@@ -22,43 +22,95 @@ import net.momirealms.customnameplates.api.CustomNameplatesAPI;
|
||||
import net.momirealms.customnameplates.api.feature.PreParsedDynamicText;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
* Class representing a static text element with customizable width, position, and content.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public class StaticText {
|
||||
|
||||
private final int width;
|
||||
private final StaticPosition position;
|
||||
private final PreParsedDynamicText text;
|
||||
|
||||
/**
|
||||
* Constructs a new StaticText instance.
|
||||
*
|
||||
* @param width the width of the text element (e.g., for layout purposes)
|
||||
* @param position the static position of the text element (LEFT, RIGHT, MIDDLE)
|
||||
* @param text the text content to be displayed, which can contain placeholders for dynamic rendering
|
||||
*/
|
||||
public StaticText(int width, StaticPosition position, String text) {
|
||||
this.width = width;
|
||||
this.position = position;
|
||||
this.text = new PreParsedDynamicText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the text element.
|
||||
*
|
||||
* @return the width of the text element
|
||||
*/
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the static position of the text element.
|
||||
*
|
||||
* @return the position of the text element (LEFT, RIGHT, MIDDLE)
|
||||
*/
|
||||
public StaticPosition getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pre-parsed dynamic text associated with this static text element.
|
||||
*
|
||||
* @return the PreParsedDynamicText instance
|
||||
*/
|
||||
public PreParsedDynamicText getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and renders the static text element, using null as the player context.
|
||||
* <p>
|
||||
* This method can be useful when rendering static text without needing player-specific dynamic values.
|
||||
*
|
||||
* @return the rendered static text as a String
|
||||
*/
|
||||
public String create() {
|
||||
return create(text.fastCreate(null).render(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and renders the static text element for a specific player context.
|
||||
*
|
||||
* @param player the player whose context will be used for dynamic text rendering
|
||||
* @return the rendered static text as a String
|
||||
*/
|
||||
public String create(CNPlayer player) {
|
||||
return create(text.fastCreate(player).render(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and renders the static text element with two player contexts (for relational rendering).
|
||||
*
|
||||
* @param p1 the first player whose context will be used for dynamic text rendering
|
||||
* @param p2 the second player whose context will be used for relational rendering
|
||||
* @return the rendered static text as a String
|
||||
*/
|
||||
public String create(CNPlayer p1, CNPlayer p2) {
|
||||
return create(text.fastCreate(p1).render(p2));
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper method to create and render the static text element with a given plain text.
|
||||
* <p>
|
||||
* This method will pass the rendered text, width, and position to the API for final rendering.
|
||||
*
|
||||
* @param text the plain text to be rendered
|
||||
* @return the rendered static text as a String
|
||||
*/
|
||||
public String create(String text) {
|
||||
return CustomNameplatesAPI.getInstance().createStaticText(text, width, position);
|
||||
}
|
||||
|
||||
+51
-1
@@ -25,9 +25,14 @@ import net.momirealms.customnameplates.api.feature.image.Image;
|
||||
import net.momirealms.customnameplates.api.helper.AdventureHelper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
* Represents a Vanilla HUD (Heads-Up Display) for displaying a dynamic progress bar,
|
||||
* typically used for showing health, energy, or other stats in a game.
|
||||
* This class handles the rendering of the HUD, which includes handling the current and maximum values,
|
||||
* and creating a visual display using a combination of empty, half, and full symbols.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public class VanillaHud {
|
||||
|
||||
private final String empty;
|
||||
private final String half;
|
||||
private final String full;
|
||||
@@ -35,6 +40,16 @@ public class VanillaHud {
|
||||
private final PreParsedDynamicText current;
|
||||
private final PreParsedDynamicText max;
|
||||
|
||||
/**
|
||||
* Constructs a VanillaHud with the specified parameters.
|
||||
*
|
||||
* @param empty The image representing an empty portion of the bar.
|
||||
* @param half The image representing a half-filled portion of the bar.
|
||||
* @param full The image representing a fully-filled portion of the bar.
|
||||
* @param reverse Whether the bar should be reversed (starts from full to empty).
|
||||
* @param current The current value to be displayed.
|
||||
* @param max The maximum value to be displayed.
|
||||
*/
|
||||
public VanillaHud(Image empty, Image half, Image full, boolean reverse, String current, String max) {
|
||||
this.empty = String.valueOf(empty.character().character()) + OffsetFont.NEG_2.character();
|
||||
this.half = String.valueOf(half.character().character()) + OffsetFont.NEG_2.character();
|
||||
@@ -44,26 +59,61 @@ public class VanillaHud {
|
||||
this.max = new PreParsedDynamicText(max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dynamic text for the current value.
|
||||
*
|
||||
* @return The dynamic text for the current value.
|
||||
*/
|
||||
public PreParsedDynamicText getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dynamic text for the maximum value.
|
||||
*
|
||||
* @return The dynamic text for the maximum value.
|
||||
*/
|
||||
public PreParsedDynamicText getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and renders the HUD for a general case (with no player context).
|
||||
*
|
||||
* @return The rendered HUD as a string.
|
||||
*/
|
||||
public String create() {
|
||||
return create(current.fastCreate(null).render(null), max.fastCreate(null).render(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and renders the HUD for a specific player.
|
||||
*
|
||||
* @param player The player whose current and max values will be rendered.
|
||||
* @return The rendered HUD as a string.
|
||||
*/
|
||||
public String create(CNPlayer player) {
|
||||
return create(current.fastCreate(player).render(player), max.fastCreate(player).render(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and renders the HUD for two players, using their respective values.
|
||||
*
|
||||
* @param p1 The first player.
|
||||
* @param p2 The second player.
|
||||
* @return The rendered HUD as a string.
|
||||
*/
|
||||
public String create(CNPlayer p1, CNPlayer p2) {
|
||||
return create(current.fastCreate(p1).render(p2), max.fastCreate(p1).render(p2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the actual HUD string representation, based on current and max values.
|
||||
*
|
||||
* @param current The current value as a string.
|
||||
* @param max The maximum value as a string.
|
||||
* @return The constructed and rendered HUD as a string.
|
||||
*/
|
||||
private String create(String current, String max) {
|
||||
double currentDouble;
|
||||
double maxDouble;
|
||||
|
||||
+9
-1
@@ -18,12 +18,15 @@
|
||||
package net.momirealms.customnameplates.api.requirement;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
|
||||
/**
|
||||
* A requirement that is always satisfied, representing an "empty" or default requirement.
|
||||
*/
|
||||
public class EmptyRequirement implements Requirement {
|
||||
|
||||
/**
|
||||
* A requirement that is always satisfied, representing an "empty" or default requirement.
|
||||
*/
|
||||
public static final EmptyRequirement INSTANCE = new EmptyRequirement();
|
||||
|
||||
/**
|
||||
@@ -57,6 +60,11 @@ public class EmptyRequirement implements Requirement {
|
||||
return "empty";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countId() {
|
||||
return CustomNameplates.getInstance().getRequirementManager().countId(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns -1, indicating that this requirement does not have a refresh interval.
|
||||
*
|
||||
|
||||
@@ -40,6 +40,13 @@ public interface Requirement {
|
||||
*/
|
||||
String type();
|
||||
|
||||
/**
|
||||
* Returns the int id for faster lookup
|
||||
*
|
||||
* @return count id
|
||||
*/
|
||||
int countId();
|
||||
|
||||
/**
|
||||
* Returns the refresh interval of the requirement.
|
||||
*
|
||||
|
||||
+8
@@ -87,4 +87,12 @@ public interface RequirementManager extends Reloadable {
|
||||
*/
|
||||
@NotNull
|
||||
Requirement parseSimpleRequirement(@NotNull String type, @NotNull Object value);
|
||||
|
||||
/**
|
||||
* Gets the count id for the requirement for faster lookup
|
||||
*
|
||||
* @param requirement requirement
|
||||
* @return the id
|
||||
*/
|
||||
int countId(Requirement requirement);
|
||||
}
|
||||
@@ -23,6 +23,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Interface to manage data storage
|
||||
*/
|
||||
public interface StorageManager extends Reloadable {
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,14 +17,67 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.storage;
|
||||
|
||||
/**
|
||||
* Enum representing the various types of storage systems supported for data persistence.
|
||||
* <p>
|
||||
* Each enum constant corresponds to a different type of storage backend that can be used
|
||||
* for saving and retrieving data. This includes file-based storage (JSON, YAML), relational
|
||||
* databases (H2, SQLite, MySQL, MariaDB), NoSQL databases (MongoDB), and caching systems (Redis).
|
||||
* </p>
|
||||
*/
|
||||
public enum StorageType {
|
||||
|
||||
/**
|
||||
* Represents storage in JSON format.
|
||||
* This format is typically used for lightweight data storage and easy serialization.
|
||||
*/
|
||||
JSON,
|
||||
|
||||
/**
|
||||
* Represents storage in YAML format.
|
||||
* YAML is often used for configuration files and is human-readable.
|
||||
*/
|
||||
YAML,
|
||||
|
||||
/**
|
||||
* Represents storage in an H2 database.
|
||||
* H2 is an in-memory SQL database that can also be used in file-based mode.
|
||||
*/
|
||||
H2,
|
||||
|
||||
/**
|
||||
* Represents storage in an SQLite database.
|
||||
* SQLite is a serverless, self-contained SQL database engine.
|
||||
*/
|
||||
SQLITE,
|
||||
|
||||
/**
|
||||
* Represents storage in a MySQL database.
|
||||
* MySQL is a widely used relational database management system (RDBMS).
|
||||
*/
|
||||
MYSQL,
|
||||
|
||||
/**
|
||||
* Represents storage in a MariaDB database.
|
||||
* MariaDB is a community-developed, open-source RDBMS that is a fork of MySQL.
|
||||
*/
|
||||
MARIADB,
|
||||
MONGODB,
|
||||
|
||||
/**
|
||||
* Represents storage in a MongoDB database.
|
||||
* MongoDB is a NoSQL database that stores data in flexible, JSON-like documents.
|
||||
*/
|
||||
MONGODB,
|
||||
|
||||
/**
|
||||
* Represents storage in Redis.
|
||||
* Redis is an in-memory data structure store, used as a database, cache, and message broker.
|
||||
*/
|
||||
Redis,
|
||||
|
||||
/**
|
||||
* Represents the absence of a storage type.
|
||||
* This is used when no storage system is configured or required.
|
||||
*/
|
||||
NONE
|
||||
}
|
||||
@@ -36,33 +36,57 @@ public class JsonData {
|
||||
private int flags;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link JsonData} instance.
|
||||
* Constructs a new {@link JsonData} instance with the specified nameplate and bubble, setting flags to 0.
|
||||
*
|
||||
* @param nameplate the nameplate value
|
||||
* @param bubble the bubble value
|
||||
*/
|
||||
public JsonData(String nameplate, String bubble) {
|
||||
this.nameplate = nameplate;
|
||||
this.bubble = bubble;
|
||||
this.flags = 0;
|
||||
this(nameplate, bubble, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link JsonData} instance with the specified nameplate, bubble, and flags.
|
||||
*
|
||||
* @param nameplate the nameplate value
|
||||
* @param bubble the bubble value
|
||||
* @param flags the flags value
|
||||
*/
|
||||
public JsonData(String nameplate, String bubble, int flags) {
|
||||
this.nameplate = nameplate;
|
||||
this.bubble = bubble;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link JsonData} instance with the specified nameplate, bubble, and a preview state flag.
|
||||
*
|
||||
* @param nameplate the nameplate value
|
||||
* @param bubble the bubble value
|
||||
* @param previewState the preview state
|
||||
*/
|
||||
public JsonData(String nameplate, String bubble, boolean previewState) {
|
||||
this.nameplate = nameplate;
|
||||
this.bubble = bubble;
|
||||
this.flags = encodeFlags(previewState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the preview state as a flag (0 or 1).
|
||||
*
|
||||
* @param previewState the preview state
|
||||
* @return 1 if preview state is true, otherwise 0
|
||||
*/
|
||||
public static int encodeFlags(boolean previewState) {
|
||||
return previewState ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the preview state from the flags.
|
||||
*
|
||||
* @param flags the flags value
|
||||
* @return true if the preview state flag is set, otherwise false
|
||||
*/
|
||||
public static boolean decodePreviewState(int flags) {
|
||||
return (flags & 1) == 1;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,13 @@ import java.util.UUID;
|
||||
* Represents player-specific data, including the player's nameplate, bubble, and UUID.
|
||||
*/
|
||||
public interface PlayerData {
|
||||
|
||||
/**
|
||||
* Default nameplate
|
||||
*/
|
||||
String DEFAULT_NAMEPLATE = "none";
|
||||
/**
|
||||
* Default bubble
|
||||
*/
|
||||
String DEFAULT_BUBBLE = "none";
|
||||
|
||||
/**
|
||||
|
||||
+16
-2
@@ -24,13 +24,27 @@ import java.util.UUID;
|
||||
* It includes the player's name, their nameplate and bubble data.
|
||||
*/
|
||||
public class PlayerDataImpl implements PlayerData {
|
||||
|
||||
/**
|
||||
* The UUID of the player
|
||||
*/
|
||||
protected UUID uuid;
|
||||
|
||||
/**
|
||||
* The nameplate identifier for the player
|
||||
*/
|
||||
protected String nameplate;
|
||||
|
||||
/**
|
||||
* The bubble identifier for the player
|
||||
*/
|
||||
protected String bubble;
|
||||
|
||||
/**
|
||||
* Flag indicating whether preview tags are enabled
|
||||
*/
|
||||
protected boolean previewTags;
|
||||
|
||||
public PlayerDataImpl(UUID uuid, String nameplate, String bubble, boolean previewTags) {
|
||||
private PlayerDataImpl(UUID uuid, String nameplate, String bubble, boolean previewTags) {
|
||||
this.uuid = uuid;
|
||||
this.nameplate = nameplate;
|
||||
this.bubble = bubble;
|
||||
|
||||
@@ -17,18 +17,44 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.util;
|
||||
|
||||
/**
|
||||
* Enum representing text alignment options.
|
||||
* <p>
|
||||
* This enum provides three types of text alignment: CENTER, LEFT, and RIGHT, each associated
|
||||
* with a unique ID for easy identification. These values are typically used to define the
|
||||
* positioning of text in layouts or UI components.
|
||||
* </p>
|
||||
*/
|
||||
public enum Alignment {
|
||||
|
||||
/**
|
||||
* Represents center-aligned text.
|
||||
*/
|
||||
CENTER(0),
|
||||
/**
|
||||
* Represents left-aligned text.
|
||||
*/
|
||||
LEFT(1),
|
||||
/**
|
||||
* Represents right-aligned text.
|
||||
*/
|
||||
RIGHT(2);
|
||||
|
||||
final int id;
|
||||
|
||||
/**
|
||||
* Constructs an {@code Alignment} instance with the specified ID.
|
||||
*
|
||||
* @param id the unique ID representing this alignment type
|
||||
*/
|
||||
Alignment(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the ID associated with this alignment.
|
||||
*
|
||||
* @return the unique ID of this alignment
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.momirealms.customnameplates.api.util;
|
||||
|
||||
public enum Billboard {
|
||||
FIXED(0),
|
||||
VERTICAL(1),
|
||||
HORIZONTAL(2),
|
||||
CENTER(3);
|
||||
|
||||
private final byte id;
|
||||
|
||||
Billboard(int index) {
|
||||
this.id = (byte) index;
|
||||
}
|
||||
|
||||
public byte id() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,21 @@ package net.momirealms.customnameplates.api.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Utility class for handling character and Unicode conversions.
|
||||
* This class provides methods to convert between Unicode escape sequences, character arrays,
|
||||
* and code points, as well as converting characters to their Unicode representations.
|
||||
*/
|
||||
public class CharacterUtils {
|
||||
|
||||
private CharacterUtils() {}
|
||||
|
||||
/**
|
||||
* Converts a Unicode string (e.g., "\\u0041\\u0042") into an array of characters.
|
||||
*
|
||||
* @param unicodeString a string containing Unicode escape sequences (e.g., "\\u0041\\u0042")
|
||||
* @return a character array corresponding to the Unicode string
|
||||
*/
|
||||
public static char[] unicodeToChars(String unicodeString) {
|
||||
String processedString = unicodeString.replace("\\u", "");
|
||||
int length = processedString.length() / 4;
|
||||
@@ -37,6 +50,14 @@ public class CharacterUtils {
|
||||
return chars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a character array to a single Unicode code point. If the array contains two characters
|
||||
* (a high surrogate and a low surrogate), it is combined into a single supplementary code point.
|
||||
*
|
||||
* @param chars the character array to convert
|
||||
* @return the Unicode code point corresponding to the character(s)
|
||||
* @throws IllegalArgumentException if the character array contains more than 2 characters
|
||||
*/
|
||||
public static int toCodePoint(char[] chars) {
|
||||
if (chars.length == 1) {
|
||||
return chars[0];
|
||||
@@ -47,6 +68,14 @@ public class CharacterUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a character array to an array of Unicode code points. If the array contains surrogate pairs,
|
||||
* they are combined into a single supplementary code point.
|
||||
*
|
||||
* @param chars the character array to convert
|
||||
* @return an array of Unicode code points corresponding to the characters
|
||||
* @throws IllegalArgumentException if there is an illegal surrogate pair
|
||||
*/
|
||||
public static int[] toCodePoints(char[] chars) {
|
||||
ArrayList<Integer> codePoints = new ArrayList<>();
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
@@ -67,6 +96,12 @@ public class CharacterUtils {
|
||||
return codePoints.stream().mapToInt(i -> i).toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a single character to its Unicode escape sequence (e.g., '\\u0041' for 'A').
|
||||
*
|
||||
* @param c the character to convert
|
||||
* @return a string representing the Unicode escape sequence for the character
|
||||
*/
|
||||
public static String char2Unicode(char c) {
|
||||
StringBuilder stringBuilder_1 = new StringBuilder("\\u");
|
||||
StringBuilder stringBuilder_2 = new StringBuilder(Integer.toHexString(c));
|
||||
@@ -76,6 +111,12 @@ public class CharacterUtils {
|
||||
return stringBuilder_1.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of characters to their Unicode escape sequences.
|
||||
*
|
||||
* @param c the character array to convert
|
||||
* @return a string representing the Unicode escape sequences for all characters in the array
|
||||
*/
|
||||
public static String char2Unicode(char[] c) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (char value : c) {
|
||||
|
||||
@@ -25,8 +25,19 @@ import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Utility class providing various helper methods for handling configuration data
|
||||
*/
|
||||
public class ConfigUtils {
|
||||
|
||||
private ConfigUtils() {}
|
||||
|
||||
/**
|
||||
* Creates a {@link CarouselText} object from the provided configuration section.
|
||||
*
|
||||
* @param section the configuration section containing properties for the CarouselText.
|
||||
* @return a {@link CarouselText} instance created from the section data.
|
||||
*/
|
||||
public static CarouselText carouselText(Section section) {
|
||||
return new CarouselText(
|
||||
section.getInt("duration", 200),
|
||||
@@ -36,6 +47,12 @@ public class ConfigUtils {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of {@link CarouselText} objects, sorted by their order from the given configuration section.
|
||||
*
|
||||
* @param section the configuration section containing multiple CarouselText entries.
|
||||
* @return an array of {@link CarouselText} instances, sorted by order.
|
||||
*/
|
||||
public static CarouselText[] carouselTexts(Section section) {
|
||||
TreeMap<Integer, CarouselText> map = new TreeMap<>();
|
||||
if (section == null) {
|
||||
@@ -58,10 +75,22 @@ public class ConfigUtils {
|
||||
return map.values().toArray(new CarouselText[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a comma-separated string to an ARGB color value.
|
||||
*
|
||||
* @param arg the comma-separated string representing the ARGB color.
|
||||
* @return the corresponding ARGB color integer value.
|
||||
*/
|
||||
public static int argb(String arg) {
|
||||
return argb(arg.split(","));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of strings to an ARGB color value.
|
||||
*
|
||||
* @param args an array of strings representing ARGB components (alpha, red, green, blue).
|
||||
* @return the corresponding ARGB color integer value.
|
||||
*/
|
||||
public static int argb(String[] args) {
|
||||
int alpha = args.length >= 1 ? Integer.parseInt(args[0]) : 64;
|
||||
int red = args.length >= 2 ? Integer.parseInt(args[1]) : 0;
|
||||
@@ -70,14 +99,35 @@ public class ConfigUtils {
|
||||
return argb(alpha, red, green, blue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given ARGB components to a single ARGB integer value.
|
||||
*
|
||||
* @param alpha the alpha component of the color.
|
||||
* @param red the red component of the color.
|
||||
* @param green the green component of the color.
|
||||
* @param blue the blue component of the color.
|
||||
* @return the corresponding ARGB color integer value.
|
||||
*/
|
||||
public static int argb(int alpha, int red, int green, int blue) {
|
||||
return (alpha << 24) | (red << 16) | (green << 8) | blue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a comma-separated string to a {@link Vector3} object.
|
||||
*
|
||||
* @param arg the comma-separated string representing the vector (x, y, z).
|
||||
* @return the corresponding {@link Vector3} object.
|
||||
*/
|
||||
public static Vector3 vector3(String arg) {
|
||||
return vector3(arg.split(","));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of strings to a {@link Vector3} object.
|
||||
*
|
||||
* @param args an array of strings representing the x, y, and z components of the vector.
|
||||
* @return the corresponding {@link Vector3} object.
|
||||
*/
|
||||
public static Vector3 vector3(String[] args) {
|
||||
float x = args.length >= 1 ? Float.parseFloat(args[0]) : 0f;
|
||||
float y = args.length >= 2 ? Float.parseFloat(args[1]) : 0f;
|
||||
@@ -85,10 +135,24 @@ public class ConfigUtils {
|
||||
return vector3(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Vector3} object from the provided float components.
|
||||
*
|
||||
* @param x the x component of the vector.
|
||||
* @param y the y component of the vector.
|
||||
* @param z the z component of the vector.
|
||||
* @return the corresponding {@link Vector3} object.
|
||||
*/
|
||||
public static Vector3 vector3(float x, float y, float z) {
|
||||
return new Vector3(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively retrieves all configuration files with a ".yml" extension from the given folder and its subfolders.
|
||||
*
|
||||
* @param configFolder the root folder to start searching for YAML files.
|
||||
* @return a list of valid configuration files sorted by name.
|
||||
*/
|
||||
public static List<File> getConfigsDeeply(File configFolder) {
|
||||
ArrayList<File> validConfigs = new ArrayList<>();
|
||||
Deque<File> fileDeque = new ArrayDeque<>();
|
||||
@@ -109,11 +173,26 @@ public class ConfigUtils {
|
||||
return validConfigs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a file located in the same folder as the provided file, with a new name.
|
||||
*
|
||||
* @param file the base file.
|
||||
* @param fileName the name of the file to retrieve.
|
||||
* @return the file located in the same folder with the specified name.
|
||||
*/
|
||||
public static File getFileInTheSameFolder(File file, String fileName) {
|
||||
File folder = file.getParentFile();
|
||||
return new File(folder, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely casts an object to the specified type, logging an error if the cast fails.
|
||||
*
|
||||
* @param object the object to cast.
|
||||
* @param clazz the class type to cast to.
|
||||
* @param <T> the type to cast to.
|
||||
* @return the cast object if successful, or null if the cast fails.
|
||||
*/
|
||||
public static <T> T safeCast(Object object, Class<T> clazz) {
|
||||
try {
|
||||
return clazz.cast(object);
|
||||
@@ -123,3 +202,4 @@ public class ConfigUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+21
-1
@@ -19,13 +19,33 @@ package net.momirealms.customnameplates.api.util;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* A utility class for generating self-incrementing entity IDs.
|
||||
* The class provides a thread-safe method for generating unique IDs that increase with each call.
|
||||
* The IDs are randomly initialized within a specific range to ensure non-repetition across instances.
|
||||
*/
|
||||
public class SelfIncreaseEntityID {
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation of this utility class.
|
||||
*/
|
||||
private SelfIncreaseEntityID() {}
|
||||
|
||||
/**
|
||||
* The current entity ID, initialized with a random value in a specific range.
|
||||
* The value is incremented each time {@link #getAndIncrease()} is called.
|
||||
*/
|
||||
private static int id = ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE / 4, Integer.MAX_VALUE / 3);
|
||||
|
||||
/**
|
||||
* Retrieves the current entity ID and increments it for the next call.
|
||||
* This method ensures that each ID is unique and increases incrementally.
|
||||
*
|
||||
* @return the current entity ID before it is incremented
|
||||
*/
|
||||
public static int getAndIncrease() {
|
||||
int i = id;
|
||||
id++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,22 +19,55 @@ package net.momirealms.customnameplates.api.util;
|
||||
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
|
||||
/**
|
||||
* A simple record representing a 3D vector with `x`, `y`, and `z` coordinates.
|
||||
* Provides utility methods for vector arithmetic such as addition and scaling.
|
||||
*/
|
||||
public record Vector3(double x, double y, double z) {
|
||||
|
||||
/**
|
||||
* A constant representing a zero vector (0, 0, 0).
|
||||
*/
|
||||
public static final Vector3 ZERO = new Vector3(0, 0, 0);
|
||||
|
||||
/**
|
||||
* Converts the vector into a platform-specific 3D vector representation.
|
||||
*
|
||||
* @return A platform-specific 3D vector object.
|
||||
*/
|
||||
public Object toVec3() {
|
||||
return CustomNameplates.getInstance().getPlatform().vec3(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds another vector to this vector and returns a new resulting vector.
|
||||
*
|
||||
* @param another The vector to be added to this vector.
|
||||
* @return A new `Vector3` representing the sum of this vector and the given vector.
|
||||
*/
|
||||
public Vector3 add(Vector3 another) {
|
||||
return new Vector3(this.x + another.x, this.y + another.y, this.z + another.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given `x`, `y`, and `z` values to the respective components of this vector
|
||||
* and returns a new resulting vector.
|
||||
*
|
||||
* @param x The value to add to the `x` component.
|
||||
* @param y The value to add to the `y` component.
|
||||
* @param z The value to add to the `z` component.
|
||||
* @return A new `Vector3` representing the sum of this vector and the given values.
|
||||
*/
|
||||
public Vector3 add(double x, double y, double z) {
|
||||
return new Vector3(this.x + x, this.y + y, this.z + z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales this vector by a given factor and returns a new resulting vector.
|
||||
*
|
||||
* @param value The factor to multiply each component of the vector by.
|
||||
* @return A new `Vector3` representing the scaled vector.
|
||||
*/
|
||||
public Vector3 multiply(double value) {
|
||||
return new Vector3(this.x * value, this.y * value, this.z * value);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.api.util;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* Utility class for zipping files and directories.
|
||||
* Provides methods for zipping entire directories and adding individual files to a zip archive.
|
||||
*/
|
||||
public class ZipUtils {
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation of utility class.
|
||||
*/
|
||||
private ZipUtils() {}
|
||||
|
||||
/**
|
||||
* Zips the contents of a directory into a zip file.
|
||||
* This method recursively walks through the directory and adds each file to the zip archive.
|
||||
*
|
||||
* @param folderPath The path to the folder to be zipped.
|
||||
* @param zipFilePath The path to the output zip file.
|
||||
* @throws IOException If an I/O error occurs while reading the directory or writing the zip file.
|
||||
*/
|
||||
public static void zipDirectory(Path folderPath, Path zipFilePath) throws IOException {
|
||||
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFilePath.toFile()))) {
|
||||
try (Stream<Path> paths = Files.walk(folderPath)) {
|
||||
for (Path path : (Iterable<Path>) paths::iterator) {
|
||||
if (Files.isDirectory(path)) {
|
||||
continue;
|
||||
}
|
||||
String zipEntryName = folderPath.relativize(path).toString().replace("\\", "/");
|
||||
ZipEntry zipEntry = new ZipEntry(zipEntryName);
|
||||
try (InputStream is = Files.newInputStream(path)) {
|
||||
addToZip(zipEntry, is, zos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a file's contents to the zip archive.
|
||||
*
|
||||
* @param zipEntry The zip entry (file) to be added to the zip archive.
|
||||
* @param is The input stream from which the file contents are read.
|
||||
* @param zos The zip output stream where the file will be written.
|
||||
* @throws IOException If an I/O error occurs while writing the file to the zip archive.
|
||||
*/
|
||||
public static void addToZip(ZipEntry zipEntry, InputStream is, ZipOutputStream zos) throws IOException {
|
||||
zos.putNextEntry(zipEntry);
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = is.read(buffer)) != -1) {
|
||||
zos.write(buffer, 0, bytesRead);
|
||||
}
|
||||
zos.closeEntry();
|
||||
}
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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.common.command;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TranslatableComponent;
|
||||
import net.momirealms.customnameplates.common.sender.SenderFactory;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
|
||||
/**
|
||||
* Abstract base class for command feature implementations within the Custom Nameplates command system.
|
||||
* This class provides utility methods for command registration, feedback handling, and configuration.
|
||||
*
|
||||
* @param <C> The type of the sender (e.g., a player or console sender) for the command.
|
||||
*/
|
||||
public abstract class AbstractCommandFeature<C> implements CommandFeature<C> {
|
||||
/**
|
||||
* The command manager
|
||||
*/
|
||||
protected final CustomNameplatesCommandManager<C> commandManager;
|
||||
/**
|
||||
* The command config
|
||||
*/
|
||||
protected CommandConfig commandConfig;
|
||||
|
||||
/**
|
||||
* Constructs an AbstractCommandFeature instance with the given command manager.
|
||||
*
|
||||
* @param commandManager The command manager to manage the commands associated with this feature.
|
||||
*/
|
||||
public AbstractCommandFeature(CustomNameplatesCommandManager<C> commandManager) {
|
||||
this.commandManager = commandManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method to retrieve the sender factory for the command.
|
||||
* Implementations must provide the logic for creating senders of type C.
|
||||
*
|
||||
* @return The sender factory for the command.
|
||||
*/
|
||||
protected abstract SenderFactory<?, C> getSenderFactory();
|
||||
|
||||
/**
|
||||
* Abstract method to assemble the command builder with the given manager.
|
||||
* Implementations must define how to build the command.
|
||||
*
|
||||
* @param manager The command manager responsible for managing the command.
|
||||
* @param builder The builder used to construct the command.
|
||||
* @return A command builder ready to be built.
|
||||
*/
|
||||
public abstract Command.Builder<? extends C> assembleCommand(CommandManager<C> manager, Command.Builder<C> builder);
|
||||
|
||||
/**
|
||||
* Registers the command with the provided command manager.
|
||||
* This method builds the command and registers it with the command manager.
|
||||
*
|
||||
* @param manager The command manager to register the command with.
|
||||
* @param builder The builder used to create the command.
|
||||
* @return The registered command.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Command<C> registerCommand(CommandManager<C> manager, Command.Builder<C> builder) {
|
||||
Command<C> command = (Command<C>) assembleCommand(manager, builder).build();
|
||||
manager.command(command);
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers any related functions or hooks. This method is a no-op by default
|
||||
* and can be overridden in subclasses to register additional functionality.
|
||||
*/
|
||||
@Override
|
||||
public void registerRelatedFunctions() {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters any related functions or hooks. This method is a no-op by default
|
||||
* and can be overridden in subclasses to unregister additional functionality.
|
||||
*/
|
||||
@Override
|
||||
public void unregisterRelatedFunctions() {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles feedback for the command execution, sending a translation message to the sender.
|
||||
* The feedback is suppressed if the "silent" flag is present in the command context.
|
||||
*
|
||||
* @param context The command context containing information about the sender and flags.
|
||||
* @param key The key for the translation component to be used as feedback.
|
||||
* @param args The arguments to be passed to the translation.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handleFeedback(CommandContext<?> context, TranslatableComponent.Builder key, Component... args) {
|
||||
if (context.flags().hasFlag("silent")) {
|
||||
return;
|
||||
}
|
||||
commandManager.handleCommandFeedback((C) context.sender(), key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles feedback for the command execution, sending a translation message to the sender.
|
||||
*
|
||||
* @param sender The sender to receive the feedback.
|
||||
* @param key The key for the translation component to be used as feedback.
|
||||
* @param args The arguments to be passed to the translation.
|
||||
*/
|
||||
@Override
|
||||
public void handleFeedback(C sender, TranslatableComponent.Builder key, Component... args) {
|
||||
commandManager.handleCommandFeedback(sender, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the command manager associated with this feature.
|
||||
*
|
||||
* @return The command manager.
|
||||
*/
|
||||
@Override
|
||||
public CustomNameplatesCommandManager<C> getCustomNameplatesCommandManager() {
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the configuration associated with the command.
|
||||
*
|
||||
* @return The command configuration.
|
||||
*/
|
||||
@Override
|
||||
public CommandConfig getCommandConfig() {
|
||||
return commandConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the configuration for the command.
|
||||
*
|
||||
* @param commandConfig The configuration to set for the command.
|
||||
*/
|
||||
public void setCommandConfig(CommandConfig commandConfig) {
|
||||
this.commandConfig = commandConfig;
|
||||
}
|
||||
}
|
||||
+34
-6
@@ -49,17 +49,39 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* An abstract implementation of the {@link CustomNameplatesCommandManager} that handles the management and registration of command features,
|
||||
* exception handling, and feedback handling within the Custom Nameplates plugin.
|
||||
*
|
||||
* @param <C> The type of the sender (e.g., player, console) for the commands.
|
||||
*/
|
||||
public abstract class AbstractCommandManager<C> implements CustomNameplatesCommandManager<C> {
|
||||
|
||||
/**
|
||||
* Registered commands
|
||||
*/
|
||||
protected final HashSet<CommandComponent<C>> registeredRootCommandComponents = new HashSet<>();
|
||||
/**
|
||||
* Registered features
|
||||
*/
|
||||
protected final HashSet<CommandFeature<C>> registeredFeatures = new HashSet<>();
|
||||
/**
|
||||
* The command manager
|
||||
*/
|
||||
protected final CommandManager<C> commandManager;
|
||||
/**
|
||||
* The NameplatesPlugin
|
||||
*/
|
||||
protected final NameplatesPlugin plugin;
|
||||
private final CustomNameplatesCaptionFormatter<C> captionFormatter = new CustomNameplatesCaptionFormatter<C>();
|
||||
private final MinecraftExceptionHandler.Decorator<C> decorator = (formatter, ctx, msg) -> msg;
|
||||
|
||||
private TriConsumer<C, String, Component> feedbackConsumer;
|
||||
|
||||
/**
|
||||
* Constructs an AbstractCommandManager instance with the provided plugin and command manager.
|
||||
*
|
||||
* @param plugin The plugin instance managing this command manager.
|
||||
* @param commandManager The command manager instance that handles the command registration.
|
||||
*/
|
||||
public AbstractCommandManager(NameplatesPlugin plugin, CommandManager<C> commandManager) {
|
||||
this.commandManager = commandManager;
|
||||
this.plugin = plugin;
|
||||
@@ -86,6 +108,12 @@ public abstract class AbstractCommandManager<C> implements CustomNameplatesComma
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a sender base on platform
|
||||
*
|
||||
* @param c sender
|
||||
* @return the wrapped sender
|
||||
*/
|
||||
protected abstract Sender wrapSender(C c);
|
||||
|
||||
private void inject() {
|
||||
@@ -108,7 +136,7 @@ public abstract class AbstractCommandManager<C> implements CustomNameplatesComma
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfig<C> getCommandConfig(YamlDocument document, String featureID) {
|
||||
public CommandConfig getCommandConfig(YamlDocument document, String featureID) {
|
||||
Section section = document.getSection(featureID);
|
||||
if (section == null) return null;
|
||||
return new CommandConfig.Builder<C>()
|
||||
@@ -119,7 +147,7 @@ public abstract class AbstractCommandManager<C> implements CustomNameplatesComma
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Command.Builder<C>> buildCommandBuilders(CommandConfig<C> config) {
|
||||
public Collection<Command.Builder<C>> buildCommandBuilders(CommandConfig config) {
|
||||
ArrayList<Command.Builder<C>> list = new ArrayList<>();
|
||||
for (String usage : config.getUsages()) {
|
||||
if (!usage.startsWith("/")) continue;
|
||||
@@ -135,7 +163,7 @@ public abstract class AbstractCommandManager<C> implements CustomNameplatesComma
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerFeature(CommandFeature<C> feature, CommandConfig<C> config) {
|
||||
public void registerFeature(CommandFeature<C> feature, CommandConfig config) {
|
||||
if (!config.isEnable()) throw new RuntimeException("Registering a disabled command feature is not allowed");
|
||||
for (Command.Builder<C> builder : buildCommandBuilders(config)) {
|
||||
Command<C> command = feature.registerCommand(commandManager, builder);
|
||||
@@ -155,7 +183,7 @@ public abstract class AbstractCommandManager<C> implements CustomNameplatesComma
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.getFeatures().values().forEach(feature -> {
|
||||
CommandConfig<C> config = getCommandConfig(document, feature.getFeatureID());
|
||||
CommandConfig config = getCommandConfig(document, feature.getFeatureID());
|
||||
if (config.isEnable()) {
|
||||
registerFeature(feature, config);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.common.command;
|
||||
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
|
||||
/**
|
||||
* A builder interface for constructing commands with configurable parameters.
|
||||
* This interface allows setting permissions, command nodes (subcommands), and
|
||||
* building the final {@link Command.Builder} object.
|
||||
*/
|
||||
public interface CommandBuilder<C> {
|
||||
|
||||
/**
|
||||
* Sets the permission required to execute the command.
|
||||
*
|
||||
* @param permission the permission string required for executing the command.
|
||||
* @return the current {@link CommandBuilder} instance for method chaining.
|
||||
*/
|
||||
CommandBuilder<C> setPermission(String permission);
|
||||
|
||||
/**
|
||||
* Sets the subcommands (nodes) for the command.
|
||||
* This allows defining a hierarchy of commands.
|
||||
*
|
||||
* @param subNodes the subcommands or nodes to add to the command.
|
||||
* @return the current {@link CommandBuilder} instance for method chaining.
|
||||
*/
|
||||
CommandBuilder<C> setCommandNode(String... subNodes);
|
||||
|
||||
/**
|
||||
* Retrieves the fully constructed {@link Command.Builder} instance.
|
||||
* This method returns the builder object that can be used to further configure
|
||||
* and register the command.
|
||||
*
|
||||
* @return the built {@link Command.Builder} instance.
|
||||
*/
|
||||
Command.Builder<C> getBuiltCommandBuilder();
|
||||
|
||||
/**
|
||||
* Basic implementation of the {@link CommandBuilder} interface.
|
||||
* This class provides a default implementation for constructing a command
|
||||
* with the given root node, permission, and subcommand nodes.
|
||||
*
|
||||
* @param <C> The type of context or object associated with the command.
|
||||
*/
|
||||
class BasicCommandBuilder<C> implements CommandBuilder<C> {
|
||||
|
||||
/**
|
||||
* The actual command builder used to construct the command.
|
||||
*/
|
||||
private Command.Builder<C> commandBuilder;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link BasicCommandBuilder} for building a command.
|
||||
*
|
||||
* @param commandManager the {@link CommandManager} instance used for creating the command builder.
|
||||
* @param rootNode the root node for the command.
|
||||
*/
|
||||
public BasicCommandBuilder(CommandManager<C> commandManager, String rootNode) {
|
||||
this.commandBuilder = commandManager.commandBuilder(rootNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the permission for the command.
|
||||
*
|
||||
* @param permission the permission required for executing the command.
|
||||
* @return the current {@link CommandBuilder} instance for method chaining.
|
||||
*/
|
||||
@Override
|
||||
public CommandBuilder<C> setPermission(String permission) {
|
||||
this.commandBuilder = this.commandBuilder.permission(permission);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subcommands (nodes) for the command.
|
||||
*
|
||||
* @param subNodes the subcommands to add to the command.
|
||||
* @return the current {@link CommandBuilder} instance for method chaining.
|
||||
*/
|
||||
@Override
|
||||
public CommandBuilder<C> setCommandNode(String... subNodes) {
|
||||
for (String sub : subNodes) {
|
||||
this.commandBuilder = this.commandBuilder.literal(sub);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the built {@link Command.Builder} instance.
|
||||
*
|
||||
* @return the built {@link Command.Builder} instance.
|
||||
*/
|
||||
@Override
|
||||
public Command.Builder<C> getBuiltCommandBuilder() {
|
||||
return commandBuilder;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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.common.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A configuration class for setting up command-related options such as enabling/disabling,
|
||||
* command usages, and required permissions.
|
||||
* <p>
|
||||
* This class provides a builder pattern implementation to easily create and configure
|
||||
* a {@link CommandConfig} object with a fluent API.
|
||||
*/
|
||||
public class CommandConfig {
|
||||
|
||||
/**
|
||||
* Flag indicating whether the command is enabled.
|
||||
*/
|
||||
private boolean enable = false;
|
||||
|
||||
/**
|
||||
* List of command usage examples or syntax hints.
|
||||
*/
|
||||
private List<String> usages = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Permission required to execute the command.
|
||||
*/
|
||||
private String permission = null;
|
||||
|
||||
/**
|
||||
* Private constructor to prevent direct instantiation.
|
||||
* Use the {@link Builder} class to construct an instance.
|
||||
*/
|
||||
private CommandConfig() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link CommandConfig} with the specified values.
|
||||
*
|
||||
* @param enable whether the command is enabled.
|
||||
* @param usages the list of command usages.
|
||||
* @param permission the permission required to execute the command.
|
||||
*/
|
||||
public CommandConfig(boolean enable, List<String> usages, String permission) {
|
||||
this.enable = enable;
|
||||
this.usages = usages;
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the command is enabled.
|
||||
*
|
||||
* @return true if the command is enabled, false otherwise.
|
||||
*/
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of command usages or syntax examples.
|
||||
*
|
||||
* @return the list of command usages.
|
||||
*/
|
||||
public List<String> getUsages() {
|
||||
return usages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the permission required to execute the command.
|
||||
*
|
||||
* @return the permission string.
|
||||
*/
|
||||
public String getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder class for constructing a {@link CommandConfig} object with customizable options.
|
||||
* This allows setting values for enabling the command, defining usages, and setting permissions.
|
||||
*
|
||||
* @param <C> the context type associated with the command.
|
||||
*/
|
||||
public static class Builder<C> {
|
||||
|
||||
/**
|
||||
* The {@link CommandConfig} object being built.
|
||||
*/
|
||||
private final CommandConfig config;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Builder} for {@link CommandConfig}.
|
||||
* Initializes the config object to default values.
|
||||
*/
|
||||
public Builder() {
|
||||
this.config = new CommandConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of command usages (examples or syntax hints).
|
||||
*
|
||||
* @param usages the list of command usages.
|
||||
* @return the current {@link Builder} instance for method chaining.
|
||||
*/
|
||||
public Builder<C> usages(List<String> usages) {
|
||||
config.usages = usages;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the permission required to execute the command.
|
||||
*
|
||||
* @param permission the permission string.
|
||||
* @return the current {@link Builder} instance for method chaining.
|
||||
*/
|
||||
public Builder<C> permission(String permission) {
|
||||
config.permission = permission;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the command is enabled.
|
||||
*
|
||||
* @param enable true to enable the command, false to disable it.
|
||||
* @return the current {@link Builder} instance for method chaining.
|
||||
*/
|
||||
public Builder<C> enable(boolean enable) {
|
||||
config.enable = enable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and returns the constructed {@link CommandConfig} object.
|
||||
*
|
||||
* @return the {@link CommandConfig} object.
|
||||
*/
|
||||
public CommandConfig build() {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.common.command;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TranslatableComponent;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
|
||||
/**
|
||||
* Represents the contract for a feature that provides a command in the Custom Nameplates system.
|
||||
* This interface defines methods for registering commands, handling feedback, and managing related functionality.
|
||||
*
|
||||
* @param <C> The type of the sender (e.g., player, console) for the command.
|
||||
*/
|
||||
public interface CommandFeature<C> {
|
||||
|
||||
/**
|
||||
* Registers the command with the provided command manager and builder.
|
||||
*
|
||||
* @param cloudCommandManager The command manager responsible for managing commands.
|
||||
* @param builder The command builder used to create the command.
|
||||
* @return The registered command.
|
||||
*/
|
||||
Command<C> registerCommand(CommandManager<C> cloudCommandManager, Command.Builder<C> builder);
|
||||
|
||||
/**
|
||||
* Retrieves a unique identifier for this feature.
|
||||
* The feature ID is used to identify the feature within the system.
|
||||
*
|
||||
* @return A unique identifier for this command feature.
|
||||
*/
|
||||
String getFeatureID();
|
||||
|
||||
/**
|
||||
* Registers any related functions or hooks that this feature may require.
|
||||
* This method may be used to register additional functionality necessary for the feature.
|
||||
*/
|
||||
void registerRelatedFunctions();
|
||||
|
||||
/**
|
||||
* Unregisters any related functions or hooks that were previously registered.
|
||||
* This method is used for cleaning up after the feature when it's no longer needed.
|
||||
*/
|
||||
void unregisterRelatedFunctions();
|
||||
|
||||
/**
|
||||
* Handles feedback for the command execution, sending a translation message to the sender.
|
||||
* The feedback may be affected by the flags in the command context (e.g., silent mode).
|
||||
*
|
||||
* @param context The command context containing information about the sender and flags.
|
||||
* @param key The key for the translation component to be used as feedback.
|
||||
* @param args The arguments to be passed to the translation.
|
||||
*/
|
||||
void handleFeedback(CommandContext<?> context, TranslatableComponent.Builder key, Component... args);
|
||||
|
||||
/**
|
||||
* Handles feedback for the command execution, sending a translation message to the sender.
|
||||
*
|
||||
* @param sender The sender to receive the feedback.
|
||||
* @param key The key for the translation component to be used as feedback.
|
||||
* @param args The arguments to be passed to the translation.
|
||||
*/
|
||||
void handleFeedback(C sender, TranslatableComponent.Builder key, Component... args);
|
||||
|
||||
/**
|
||||
* Retrieves the command manager associated with this feature.
|
||||
*
|
||||
* @return The command manager.
|
||||
*/
|
||||
CustomNameplatesCommandManager<C> getCustomNameplatesCommandManager();
|
||||
|
||||
/**
|
||||
* Retrieves the configuration associated with the command.
|
||||
*
|
||||
* @return The command configuration.
|
||||
*/
|
||||
CommandConfig getCommandConfig();
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.common.command;
|
||||
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TranslatableComponent;
|
||||
import net.kyori.adventure.util.Index;
|
||||
import net.momirealms.customnameplates.common.util.TriConsumer;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Interface for managing commands within the Custom Nameplates plugin. This interface defines methods for
|
||||
* registering features, handling feedback, and interacting with the command manager and configurations.
|
||||
*
|
||||
* @param <C> The type of the sender (e.g., player, console) for the commands.
|
||||
*/
|
||||
public interface CustomNameplatesCommandManager<C> {
|
||||
|
||||
/**
|
||||
* The default configuration file name for commands
|
||||
*/
|
||||
String commandsFile = "commands.yml";
|
||||
|
||||
/**
|
||||
* Unregisters all previously registered command features.
|
||||
*/
|
||||
void unregisterFeatures();
|
||||
|
||||
/**
|
||||
* Registers a command feature with the provided configuration.
|
||||
*
|
||||
* @param feature The command feature to register.
|
||||
* @param config The configuration for the feature.
|
||||
*/
|
||||
void registerFeature(CommandFeature<C> feature, CommandConfig config);
|
||||
|
||||
/**
|
||||
* Registers all default features based on the plugin configuration.
|
||||
*/
|
||||
void registerDefaultFeatures();
|
||||
|
||||
/**
|
||||
* Retrieves all registered command features in the form of an index.
|
||||
*
|
||||
* @return The index of registered command features.
|
||||
*/
|
||||
Index<String, CommandFeature<C>> getFeatures();
|
||||
|
||||
/**
|
||||
* Sets a custom feedback consumer that handles the feedback sent to the command sender.
|
||||
*
|
||||
* @param feedbackConsumer The custom feedback consumer.
|
||||
*/
|
||||
void setFeedbackConsumer(@NotNull TriConsumer<C, String, Component> feedbackConsumer);
|
||||
|
||||
/**
|
||||
* Provides the default feedback consumer for sending feedback messages.
|
||||
*
|
||||
* @return The default feedback consumer.
|
||||
*/
|
||||
TriConsumer<C, String, Component> defaultFeedbackConsumer();
|
||||
|
||||
/**
|
||||
* Retrieves the command configuration from a YAML document and a given feature ID.
|
||||
*
|
||||
* @param document The YAML document containing the configuration.
|
||||
* @param featureID The ID of the feature to retrieve configuration for.
|
||||
* @return The command configuration for the specified feature, or null if not found.
|
||||
*/
|
||||
CommandConfig getCommandConfig(YamlDocument document, String featureID);
|
||||
|
||||
/**
|
||||
* Builds a collection of command builders based on the given configuration.
|
||||
*
|
||||
* @param config The command configuration.
|
||||
* @return A collection of command builders.
|
||||
*/
|
||||
Collection<Command.Builder<C>> buildCommandBuilders(CommandConfig config);
|
||||
|
||||
/**
|
||||
* Retrieves the command manager associated with this command manager.
|
||||
*
|
||||
* @return The command manager.
|
||||
*/
|
||||
CommandManager<C> getCommandManager();
|
||||
|
||||
/**
|
||||
* Sends feedback to the sender based on the provided key and arguments.
|
||||
*
|
||||
* @param sender The sender of the command.
|
||||
* @param key The key used to retrieve the feedback message.
|
||||
* @param args The arguments to be included in the feedback message.
|
||||
*/
|
||||
void handleCommandFeedback(C sender, TranslatableComponent.Builder key, Component... args);
|
||||
|
||||
/**
|
||||
* Sends feedback to the sender based on the provided node and component.
|
||||
*
|
||||
* @param sender The sender of the command.
|
||||
* @param node The feedback node.
|
||||
* @param component The component containing the feedback message.
|
||||
*/
|
||||
void handleCommandFeedback(C sender, String node, Component component);
|
||||
}
|
||||
+89
-19
@@ -1,26 +1,18 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
* 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.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
* 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.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
* 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.common.dependency;
|
||||
@@ -113,6 +105,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 +226,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",
|
||||
@@ -336,10 +348,27 @@ public enum Dependency {
|
||||
|
||||
private static final String MAVEN_FORMAT = "%s/%s/%s/%s-%s.jar";
|
||||
|
||||
/**
|
||||
* Constructs a Dependency with the given group ID, artifact ID, repository, and custom artifact ID.
|
||||
*
|
||||
* @param groupId the group ID of the dependency
|
||||
* @param artifactId the artifact ID of the dependency
|
||||
* @param repo the repository for the dependency
|
||||
* @param customArtifactID the custom artifact ID for the dependency
|
||||
*/
|
||||
Dependency(String groupId, String artifactId, String repo, String customArtifactID) {
|
||||
this(groupId, artifactId, repo, customArtifactID, new Relocation[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Dependency with the given group ID, artifact ID, repository, custom artifact ID, and relocations.
|
||||
*
|
||||
* @param groupId the group ID of the dependency
|
||||
* @param artifactId the artifact ID of the dependency
|
||||
* @param repo the repository for the dependency
|
||||
* @param customArtifactID the custom artifact ID for the dependency
|
||||
* @param relocations any relocations associated with the dependency
|
||||
*/
|
||||
Dependency(String groupId, String artifactId, String repo, String customArtifactID, Relocation... relocations) {
|
||||
this.artifactId = artifactId;
|
||||
this.artifactIdSuffix = "";
|
||||
@@ -349,6 +378,16 @@ public enum Dependency {
|
||||
this.customArtifactID = customArtifactID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Dependency with the given group ID, artifact ID, repository, custom artifact ID, and relocations.
|
||||
*
|
||||
* @param groupId the group ID of the dependency
|
||||
* @param artifactId the artifact ID of the dependency
|
||||
* @param repo the repository for the dependency
|
||||
* @param customArtifactID the custom artifact ID for the dependency
|
||||
* @param artifactIdSuffix the custom artifact suffix
|
||||
* @param relocations any relocations associated with the dependency
|
||||
*/
|
||||
Dependency(String groupId, String artifactId, String repo, String customArtifactID, String artifactIdSuffix, Relocation... relocations) {
|
||||
this.artifactId = artifactId;
|
||||
this.artifactIdSuffix = artifactIdSuffix;
|
||||
@@ -358,10 +397,20 @@ public enum Dependency {
|
||||
this.customArtifactID = customArtifactID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the artifact suffix
|
||||
*
|
||||
* @param artifactIdSuffix the artifact suffix
|
||||
*/
|
||||
public void setArtifactIdSuffix(String artifactIdSuffix) {
|
||||
this.artifactIdSuffix = artifactIdSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version of the dependency based on the custom artifact ID.
|
||||
*
|
||||
* @return the version of the dependency
|
||||
*/
|
||||
public String getVersion() {
|
||||
return CustomNameplatesProperties.getValue(customArtifactID);
|
||||
}
|
||||
@@ -370,6 +419,12 @@ public enum Dependency {
|
||||
return s.replace("{}", ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename for the dependency's JAR file, optionally with a classifier.
|
||||
*
|
||||
* @param classifier the classifier for the JAR (e.g., "sources" or "javadoc")
|
||||
* @return the filename for the JAR
|
||||
*/
|
||||
public String getFileName(String classifier) {
|
||||
String name = customArtifactID.toLowerCase(Locale.ROOT).replace('_', '-');
|
||||
String extra = classifier == null || classifier.isEmpty()
|
||||
@@ -378,6 +433,11 @@ public enum Dependency {
|
||||
return name + "-" + this.getVersion() + extra + ".jar";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Maven repository path for the dependency.
|
||||
*
|
||||
* @return the Maven repository path
|
||||
*/
|
||||
String getMavenRepoPath() {
|
||||
return String.format(MAVEN_FORMAT,
|
||||
rewriteEscaping(groupId).replace(".", "/"),
|
||||
@@ -388,6 +448,11 @@ public enum Dependency {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of relocations for the dependency.
|
||||
*
|
||||
* @return a list of {@link Relocation} objects
|
||||
*/
|
||||
public List<Relocation> getRelocations() {
|
||||
return this.relocations;
|
||||
}
|
||||
@@ -406,6 +471,11 @@ public enum Dependency {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the repo
|
||||
*
|
||||
* @return the repo
|
||||
*/
|
||||
@Nullable
|
||||
public String getRepo() {
|
||||
return repo;
|
||||
+10
-8
@@ -30,18 +30,20 @@ package net.momirealms.customnameplates.common.dependency;
|
||||
*/
|
||||
public class DependencyDownloadException extends Exception {
|
||||
|
||||
public DependencyDownloadException() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new DependencyDownloadException with the specified detail message.
|
||||
*
|
||||
* @param message the detail message, which provides additional information about the error
|
||||
*/
|
||||
public DependencyDownloadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DependencyDownloadException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new DependencyDownloadException with the specified cause.
|
||||
*
|
||||
* @param cause the cause of the exception, which can be retrieved later with {@link Throwable#getCause()}
|
||||
*/
|
||||
public DependencyDownloadException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
File renamed without changes.
+5
@@ -61,6 +61,11 @@ public class DependencyManagerImpl implements DependencyManager {
|
||||
private final Executor loadingExecutor;
|
||||
private final NameplatesPlugin plugin;
|
||||
|
||||
/**
|
||||
* Constructs a DependencyManagerImpl instance
|
||||
*
|
||||
* @param plugin plugin
|
||||
*/
|
||||
public DependencyManagerImpl(NameplatesPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.registry = new DependencyRegistry();
|
||||
+11
-1
@@ -32,6 +32,12 @@ import com.google.gson.JsonElement;
|
||||
*/
|
||||
public class DependencyRegistry {
|
||||
|
||||
/**
|
||||
* Check if the dependency should be automatically loaded
|
||||
*
|
||||
* @param dependency dependency
|
||||
* @return should be automatically loaded or not
|
||||
*/
|
||||
public boolean shouldAutoLoad(Dependency dependency) {
|
||||
return switch (dependency) {
|
||||
// all used within 'isolated' classloaders, and are therefore not
|
||||
@@ -41,6 +47,11 @@ public class DependencyRegistry {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if gson is relocated
|
||||
*
|
||||
* @return relocated or not
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public static boolean isGsonRelocated() {
|
||||
return JsonElement.class.getName().startsWith("net.momirealms");
|
||||
@@ -58,5 +69,4 @@ public class DependencyRegistry {
|
||||
private static boolean slf4jPresent() {
|
||||
return classExists("org.slf4j.Logger") && classExists("org.slf4j.LoggerFactory");
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -66,6 +66,11 @@ public enum DependencyRepository {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the url of this repo
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.common.event;
|
||||
|
||||
/**
|
||||
* Interface representing an event or task that can be cancelled.
|
||||
* This interface defines methods to check and set the cancellation state of the event or task.
|
||||
*/
|
||||
public interface Cancellable {
|
||||
|
||||
/**
|
||||
* Gets the current cancelled state of the event or task.
|
||||
*
|
||||
* @return true if the event or task has been cancelled, false otherwise.
|
||||
*/
|
||||
boolean cancelled();
|
||||
|
||||
/**
|
||||
* Sets the cancelled state of the event or task.
|
||||
*
|
||||
* @param cancelled a boolean indicating whether the event is cancelled
|
||||
*/
|
||||
void cancelled(final boolean cancelled);
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.common.event;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
/**
|
||||
* An event that represents feedback generated by a command execution.
|
||||
* This event contains the sender of the command, the associated key, and the feedback message.
|
||||
*/
|
||||
public interface CommandFeedbackEvent<C> extends NameplatesEvent, Cancellable {
|
||||
|
||||
/**
|
||||
* Gets the sender of the command that triggered this event.
|
||||
*
|
||||
* @return the sender (e.g., player or entity) of the command.
|
||||
*/
|
||||
@Param(0)
|
||||
C sender();
|
||||
|
||||
/**
|
||||
* Gets the key associated with the feedback message.
|
||||
* This key may be used to identify the context or specific type of feedback.
|
||||
*
|
||||
* @return the key for the feedback message.
|
||||
*/
|
||||
@Param(1)
|
||||
String key();
|
||||
|
||||
/**
|
||||
* Gets the feedback message that will be sent in response to the command.
|
||||
* The message is represented by a {@link Component}, which allows for rich text formatting.
|
||||
*
|
||||
* @return the feedback message to be displayed or logged.
|
||||
*/
|
||||
@Param(2)
|
||||
Component message();
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
Loaded 100 of 384 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user