Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
f5d2d6a0bc | ||
|
|
7d6fba25e6 | ||
|
|
fcb045e0c8 | ||
|
|
df098a053e | ||
|
|
2958b4e1db | ||
|
|
84a37ed619 | ||
|
|
f66c800f3a | ||
|
|
0fb4ae37e4 | ||
|
|
9a9add1f03 | ||
|
|
5d48530eb6 | ||
|
|
f5e33f5647 | ||
|
|
ffdc7c49ce | ||
|
|
46d922ab15 | ||
|
|
aee8ebf9ae | ||
|
|
be086cd91f | ||
|
|
0b96cefcf2 | ||
|
|
8867b25307 | ||
|
|
bd6caee58f | ||
|
|
d0b057b391 | ||
|
|
2e03248555 | ||
|
|
5898d8e3d4 | ||
|
|
8bcb7d3380 | ||
|
|
59dda019d8 | ||
|
|
7512a97461 | ||
|
|
63075ad1bb | ||
|
|
2c9bdc662a | ||
|
|
545826801a | ||
|
|
26c30b8bab | ||
|
|
c022319b67 | ||
|
|
37da5df7e6 | ||
|
|
aa919d18e0 | ||
|
|
7eb3296294 | ||
|
|
d84c9f7031 | ||
|
|
ec840036ac | ||
|
|
a168cb8591 | ||
|
|
8856831a94 | ||
|
|
a387cf5127 | ||
|
|
6b2bbea6e1 | ||
|
|
67732ecf76 | ||
|
|
f361ad1015 | ||
|
|
57a1593315 | ||
|
|
a424c3345a | ||
|
|
047852eed9 | ||
|
|
5d2d3e0933 | ||
|
|
efe90b95b5 | ||
|
|
cad0e07411 | ||
|
|
f6de779090 | ||
|
|
5df341b2a1 | ||
|
|
2ba7ad95ba | ||
|
|
4b2ddf6cd1 | ||
|
|
e392e0fd4d | ||
|
|
10206e8b2a | ||
|
|
f935a61958 | ||
|
|
844e53ff1a | ||
|
|
7209b9772b | ||
|
|
3aa7e5c012 | ||
|
|
d8324da1d9 | ||
|
|
f66bc23037 | ||
|
|
425a08a57a | ||
|
|
f597e584ee | ||
|
|
886a3c53a3 | ||
|
|
90b07517a7 | ||
|
|
4ef7da87b4 | ||
|
|
a5fd4f237e | ||
|
|
5046372177 | ||
|
|
df86e4bc33 | ||
|
|
b5e83ca984 | ||
|
|
04bb10cb3d | ||
|
|
e7371cc02a | ||
|
|
bee0b26a9f | ||
|
|
343c0e5cb0 | ||
|
|
81d3a888b8 | ||
|
|
58e16e5376 | ||
|
|
cc8c3d6bcd | ||
|
|
3000b26bfa | ||
|
|
a800481574 | ||
|
|
82350ac0c4 | ||
|
|
35edd85434 | ||
|
|
99bfc28be8 | ||
|
|
5ee27c126c | ||
|
|
5282d5e8a7 | ||
|
|
0f7a72bf1e | ||
|
|
b36d0c23e1 | ||
|
|
f8219659c4 | ||
|
|
eb730c8631 | ||
|
|
12b8b74031 | ||
|
|
365aae10f5 | ||
|
|
5e299bb0d4 | ||
|
|
79a0892b09 | ||
|
|
a8bc4d8de5 | ||
|
|
6276d27d57 | ||
|
|
096e6330d6 | ||
|
|
e41686aa31 | ||
|
|
590b26ac2a | ||
|
|
a7dc0db15d | ||
|
|
c9250fea13 | ||
|
|
fa914d52a2 | ||
|
|
efbf2d3b64 | ||
|
|
40672aefb4 | ||
|
|
8fb4b8317d | ||
|
|
e68a333527 | ||
|
|
53317c3e4b | ||
|
|
c2c1b703b7 | ||
|
|
abcece373f | ||
|
|
be8cf27f37 | ||
|
|
6fafb85cec | ||
|
|
d18bf83ecb | ||
|
|
2c8aad7a75 | ||
|
|
9e8e57c6df | ||
|
|
1c433d1891 | ||
|
|
6e77eb55d0 | ||
|
|
3afa1bfb58 | ||
|
|
39e9d40e3e | ||
|
|
2e90d02166 | ||
|
|
9d88ead4e3 | ||
|
|
810b8f0593 | ||
|
|
930cdf8c00 | ||
|
|
a26e6dc784 | ||
|
|
e450b1429d |
No files matched your search
@@ -5,6 +5,9 @@ target/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### Unfinished ###
|
||||
platforms/sponge/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
|
||||
@@ -1,41 +1,44 @@
|
||||
# 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>
|
||||
[](https://github.com/Xiao-MoMi/Custom-Nameplates/)
|
||||

|
||||

|
||||

|
||||

|
||||
[](https://jitpack.io/#Xiao-MoMi/Custom-Nameplates)
|
||||
<a href="https://mo-mi.gitbook.io/xiaomomi-plugins/plugin-wiki/" alt="GitBook">
|
||||
<img src="https://img.shields.io/badge/docs-gitbook-brightgreen" alt="Gitbook"/>
|
||||
</a>
|
||||
|
||||
CustomNameplates is a Paper plugin that provides unlimited customization for nametags, bossbars, actionbars and chat bubbles.
|
||||
|
||||
## How to build
|
||||
|
||||
### Windows
|
||||
## How to Build
|
||||
|
||||
#### Command Line
|
||||
Install JDK 17 and set the JDK installation path to JAVA_HOME as an environment variable.\
|
||||
Start powershell and change directory to the project folder.\
|
||||
Execute ".\gradlew build" and get the jar at /target/CustomNameplates-universe-version.jar.
|
||||
Install JDK 17 & 21. \
|
||||
Start terminal and change directory to the project folder.\
|
||||
Execute ".\gradlew build" and get the artifact under /target folder
|
||||
|
||||
#### IDE
|
||||
Import the project and execute gradle build action.
|
||||
Import the project and execute gradle build action. \
|
||||
Get the artifact under /target folder
|
||||
|
||||
##### About Proxy
|
||||
If you are using a proxy, configurate the proxy in gradle.properties. Otherwise comment the lines in gradle.properties.
|
||||
## How to Contribute
|
||||
|
||||
## Support the developer
|
||||
#### Translations
|
||||
Clone this project and create a new language file in the /common/src/main/resources/translations directory. \
|
||||
Once your changes are ready, open a pull request for review. We appreciate your works!
|
||||
|
||||
Polymart: https://polymart.org/resource/customnameplates.2543 \
|
||||
Afdian: https://afdian.net/@xiaomomi
|
||||
## Support the Developer
|
||||
|
||||
## Use CustomNameplates API
|
||||
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>
|
||||
@@ -43,37 +46,37 @@ Afdian: https://afdian.net/@xiaomomi
|
||||
</repository>
|
||||
</repositories>
|
||||
```
|
||||
```
|
||||
```html
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.Xiao-MoMi</groupId>
|
||||
<artifactId>Custom-Nameplates</artifactId>
|
||||
<version>{LATEST}</version>
|
||||
<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:{LATEST}'
|
||||
compileOnly 'com.github.Xiao-MoMi:Custom-Nameplates:{VERSION}'
|
||||
}
|
||||
```
|
||||
### Gradle (Kotlin)
|
||||
|
||||
```
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://jitpack.io/")
|
||||
}
|
||||
```
|
||||
```
|
||||
```kotlin
|
||||
dependencies {
|
||||
compileOnly("com.github.Xiao-MoMi:Custom-Nameplates:{LATEST}")
|
||||
compileOnly("com.github.Xiao-MoMi:Custom-Nameplates:{VERSION}")
|
||||
}
|
||||
```
|
||||
+54
-4
@@ -1,12 +1,62 @@
|
||||
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://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT")
|
||||
compileOnly("me.clip:placeholderapi:2.11.5")
|
||||
implementation(project(":common"))
|
||||
implementation("net.kyori:adventure-api:4.15.0")
|
||||
// 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"]}")
|
||||
// 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")
|
||||
// GSON
|
||||
compileOnly("com.google.code.gson:gson:${rootProject.properties["gson_version"]}")
|
||||
// Fast util
|
||||
compileOnly("it.unimi.dsi:fastutil:${rootProject.properties["fastutil_version"]}")
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(17)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
options.release.set(17)
|
||||
dependsOn(tasks.clean)
|
||||
}
|
||||
|
||||
tasks {
|
||||
shadowJar {
|
||||
archiveClassifier = ""
|
||||
archiveFileName = "CustomNameplates-${rootProject.properties["project_version"]}.jar"
|
||||
relocate ("net.kyori", "net.momirealms.customnameplates.libraries")
|
||||
relocate("dev.dejvokep", "net.momirealms.customnameplates.libraries")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("mavenJava") {
|
||||
groupId = "net.momirealms"
|
||||
artifactId = "CustomNameplates"
|
||||
version = rootProject.version.toString()
|
||||
artifact(tasks.shadowJar)
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,584 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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;
|
||||
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.storage.data.PlayerData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
|
||||
protected final CustomNameplates plugin;
|
||||
protected final Channel channel;
|
||||
|
||||
protected Object player;
|
||||
|
||||
private volatile boolean isLoaded = false;
|
||||
private volatile boolean tempPreviewing = false;
|
||||
private volatile boolean toggleablePreviewing = false;
|
||||
|
||||
private String equippedNameplate;
|
||||
private String equippedBubble;
|
||||
|
||||
private final TeamView teamView = new TeamView();
|
||||
|
||||
// these maps might be visited by other threads through PlaceholderAPI
|
||||
private final Map<Integer, TimeStampData<String>> cachedValues = new ConcurrentHashMap<>(128);
|
||||
private final Map<Integer, WeakHashMap<CNPlayer, TimeStampData<String>>> cachedRelationalValues = new ConcurrentHashMap<>(128);
|
||||
private final Map<Integer, TimeStampData<Boolean>> cachedRequirements = new 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 = new WeakHashMap<>();
|
||||
private final ReadWriteLock trackerLock = new ReentrantReadWriteLock();
|
||||
|
||||
protected AbstractCNPlayer(CustomNameplates plugin, Channel channel) {
|
||||
this.plugin = plugin;
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Placeholder> activePlaceholdersToRefresh() {
|
||||
Placeholder[] activePlaceholders = activePlaceholders();
|
||||
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, Collection<CNPlayer> others) {
|
||||
if (placeholders.isEmpty()) return;
|
||||
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) {
|
||||
updatePlayerPlaceholder(playerPlaceholder);
|
||||
} else if (placeholder instanceof RelationalPlaceholder relationalPlaceholder) {
|
||||
updateRelationalPlaceholder(relationalPlaceholder, others);
|
||||
} else if (placeholder instanceof SharedPlaceholder sharedPlaceholder) {
|
||||
updateSharedPlaceholder(sharedPlaceholder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void childrenFirstList(Placeholder placeholder, List<Placeholder> list) {
|
||||
if (placeholder.children().isEmpty()) {
|
||||
list.add(placeholder);
|
||||
} else {
|
||||
for (Placeholder child : placeholder.children()) {
|
||||
childrenFirstList(child, list);
|
||||
}
|
||||
list.add(placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
private void parentLastList(Placeholder placeholder, List<Placeholder> list) {
|
||||
if (placeholder.parents().isEmpty()) {
|
||||
list.add(placeholder);
|
||||
} else {
|
||||
list.add(placeholder);
|
||||
for (Placeholder parent : placeholder.parents()) {
|
||||
parentLastList(parent, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
cachedValues.clear();
|
||||
cachedRelationalValues.clear();
|
||||
cachedRequirements.clear();
|
||||
cachedRelationalRequirements.clear();
|
||||
activeFeatures.clear();
|
||||
placeholder2Features.clear();
|
||||
feature2Placeholders.clear();
|
||||
}
|
||||
|
||||
public void setPlayer(Object player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel channel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Feature> activeFeatures(Placeholder placeholder) {
|
||||
return placeholder2Features.getOrDefault(placeholder, Collections.emptySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object player() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public void setLoaded(boolean loaded) {
|
||||
isLoaded = loaded;
|
||||
}
|
||||
|
||||
public void setTempPreviewing(boolean previewing) {
|
||||
this.tempPreviewing = previewing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTempPreviewing() {
|
||||
return tempPreviewing;
|
||||
}
|
||||
|
||||
public void setToggleablePreviewing(boolean previewing) {
|
||||
this.toggleablePreviewing = previewing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isToggleablePreviewing() {
|
||||
return toggleablePreviewing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoaded() {
|
||||
return isLoaded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(Feature feature) {
|
||||
activeFeatures.add(feature);
|
||||
Set<Placeholder> allPlaceholders = feature.allPlaceholders();
|
||||
feature2Placeholders.put(feature, allPlaceholders);
|
||||
for (Placeholder placeholder : allPlaceholders) {
|
||||
Set<Feature> featureSet = placeholder2Features.computeIfAbsent(placeholder, k -> new ObjectOpenHashSet<>());
|
||||
featureSet.add(feature);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFeature(Feature feature) {
|
||||
activeFeatures.remove(feature);
|
||||
Set<Placeholder> placeholders = feature2Placeholders.remove(feature);
|
||||
if (placeholders != null) {
|
||||
for (Placeholder placeholder : placeholders) {
|
||||
Set<Feature> featureSet = placeholder2Features.get(placeholder);
|
||||
featureSet.remove(feature);
|
||||
if (featureSet.isEmpty()) placeholder2Features.remove(placeholder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerValue(PlayerPlaceholder placeholder, TimeStampData<String> value) {
|
||||
cachedValues.put(placeholder.countId(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSharedValue(SharedPlaceholder placeholder, TimeStampData<String> value) {
|
||||
cachedValues.put(placeholder.countId(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
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 @NotNull String getCachedSharedValue(SharedPlaceholder placeholder) {
|
||||
return updateSharedPlaceholder(placeholder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getCachedPlayerValue(PlayerPlaceholder placeholder) {
|
||||
return updatePlayerPlaceholder(placeholder);
|
||||
}
|
||||
|
||||
@Override
|
||||
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 TimeStampData<String> getRawSharedValue(SharedPlaceholder placeholder) {
|
||||
return cachedValues.get(placeholder.countId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TimeStampData<String> getRawRelationalValue(RelationalPlaceholder placeholder, CNPlayer another) {
|
||||
WeakHashMap<CNPlayer, TimeStampData<String>> map = cachedRelationalValues.get(placeholder.countId());
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
return map.get(another);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Placeholder[] activePlaceholders() {
|
||||
Set<Placeholder> placeholders = new ObjectOpenHashSet<>();
|
||||
for (Feature feature : activeFeatures) {
|
||||
placeholders.addAll(feature.activePlaceholders());
|
||||
}
|
||||
return placeholders.toArray(new Placeholder[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(Requirement[] requirements) {
|
||||
int currentTicks = MainTask.getTicks();
|
||||
for (Requirement requirement : requirements) {
|
||||
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);
|
||||
data.updateTicks(false);
|
||||
data.data(satisfied);
|
||||
if (!satisfied) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolean satisfied = requirement.isSatisfied(this, this);
|
||||
data = new TimeStampData<>(satisfied, currentTicks, true);
|
||||
cachedRequirements.put(requirement.countId(), data);
|
||||
if (!satisfied) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(CNPlayer another, Requirement[] requirements) {
|
||||
int currentTicks = MainTask.getTicks();
|
||||
for (Requirement requirement : requirements) {
|
||||
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) {
|
||||
if (!data.data()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
boolean satisfied = requirement.isSatisfied(this, another);
|
||||
data.updateTicks(false);
|
||||
data.data(satisfied);
|
||||
if (!satisfied) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolean satisfied = requirement.isSatisfied(this, another);
|
||||
data = new TimeStampData<>(satisfied, currentTicks, true);
|
||||
innerMap.put(another, data);
|
||||
if (!satisfied) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tracker addPlayerToTracker(CNPlayer another) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePlayerFromTracker(CNPlayer another) {
|
||||
trackerLock.writeLock().lock();
|
||||
try {
|
||||
trackers.remove(another);
|
||||
} finally {
|
||||
trackerLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
trackerLock.readLock().lock();
|
||||
try {
|
||||
return trackers.get(another);
|
||||
} finally {
|
||||
trackerLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String equippedBubble() {
|
||||
if (equippedNameplate == null) return "none";
|
||||
return equippedBubble;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equippedBubble(String equippedBubble) {
|
||||
if (!isLoaded()) return false;
|
||||
if (!equippedBubble.equals(this.equippedBubble)) {
|
||||
this.equippedBubble = equippedBubble;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String equippedNameplate() {
|
||||
if (equippedNameplate == null) return "none";
|
||||
return equippedNameplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equippedNameplate(String equippedNameplate) {
|
||||
if (!isLoaded()) return false;
|
||||
if (!equippedNameplate.equals(this.equippedNameplate)) {
|
||||
this.equippedNameplate = equippedNameplate;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
plugin.getStorageManager().dataSource().updatePlayerData(PlayerData.builder()
|
||||
.uuid(uuid())
|
||||
.nameplate(equippedNameplate())
|
||||
.bubble(equippedBubble())
|
||||
.previewTags(isToggleablePreviewing())
|
||||
.build(), plugin.getScheduler().async());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamView teamView() {
|
||||
return teamView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) return true;
|
||||
if (object == null || getClass() != object.getClass()) return false;
|
||||
AbstractCNPlayer that = (AbstractCNPlayer) object;
|
||||
return entityID() == that.entityID() && uuid().equals(that.uuid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return entityID();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import net.momirealms.customnameplates.api.feature.Feature;
|
||||
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;
|
||||
|
||||
public interface CNPlayer {
|
||||
|
||||
/**
|
||||
* Returns the player's name.
|
||||
*
|
||||
* @return the player's name
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* Returns the UUID of the player.
|
||||
*
|
||||
* @return the player's UUID
|
||||
*/
|
||||
UUID uuid();
|
||||
|
||||
/**
|
||||
* Returns the underlying player object (server-side representation).
|
||||
*
|
||||
* @return the player object
|
||||
*/
|
||||
Object player();
|
||||
|
||||
/**
|
||||
* Returns the channel of the player
|
||||
*
|
||||
* @return the channel
|
||||
*/
|
||||
Channel channel();
|
||||
|
||||
/**
|
||||
* Returns the entity ID of the player.
|
||||
*
|
||||
* @return the entity ID
|
||||
*/
|
||||
int entityID();
|
||||
|
||||
/**
|
||||
* Returns the player's current position as a {@link Vector3}.
|
||||
*
|
||||
* @return the player's position
|
||||
*/
|
||||
Vector3 position();
|
||||
|
||||
/**
|
||||
* Returns the name of the world the player is in.
|
||||
*
|
||||
* @return the world name
|
||||
*/
|
||||
String world();
|
||||
|
||||
/**
|
||||
* Checks if the player is currently online.
|
||||
*
|
||||
* @return true if the player is online, false otherwise
|
||||
*/
|
||||
boolean isOnline();
|
||||
|
||||
/**
|
||||
*
|
||||
* Checks if the player is on spectator mode
|
||||
*
|
||||
* @return true if the player is on spectator mode, false otherwise
|
||||
*/
|
||||
boolean isSpectator();
|
||||
|
||||
/**
|
||||
* Returns the scale of the player.
|
||||
*
|
||||
* @return the player's scale
|
||||
*/
|
||||
double scale();
|
||||
|
||||
/**
|
||||
* Checks if the player is crouching.
|
||||
*
|
||||
* @return true if the player is crouching, false otherwise
|
||||
*/
|
||||
boolean isCrouching();
|
||||
|
||||
/**
|
||||
* Checks if the player has been fully loaded into the system.
|
||||
*
|
||||
* @return true if the player is loaded, false otherwise
|
||||
*/
|
||||
boolean isLoaded();
|
||||
|
||||
/**
|
||||
* Checks if the player is currently previewing
|
||||
*
|
||||
* @return true if the player is previewing, false otherwise
|
||||
*/
|
||||
boolean isTempPreviewing();
|
||||
|
||||
/**
|
||||
* Checks if the player has turned their nameplate on
|
||||
*
|
||||
* @return true if the player has turned their nameplate on, false otherwise
|
||||
*/
|
||||
boolean isToggleablePreviewing();
|
||||
|
||||
/**
|
||||
* Checks if the player has the specified permission.
|
||||
*
|
||||
* @param permission the permission to check
|
||||
* @return true if the player has the permission, false otherwise
|
||||
*/
|
||||
boolean hasPermission(String permission);
|
||||
|
||||
/**
|
||||
* Returns the player's current time
|
||||
*
|
||||
* @return the player's time
|
||||
*/
|
||||
long playerTime();
|
||||
|
||||
/**
|
||||
* Checks if the player is flying.
|
||||
*
|
||||
* @return true if the player is flying, false otherwise
|
||||
*/
|
||||
boolean isFlying();
|
||||
|
||||
/**
|
||||
* Returns the remaining air level for the player.
|
||||
*
|
||||
* @return the player's remaining air
|
||||
*/
|
||||
int remainingAir();
|
||||
|
||||
/**
|
||||
* Retrieves the set of features that are actively using the specified placeholder.
|
||||
*
|
||||
* @param placeholder the placeholder to check
|
||||
* @return the set of active features using the placeholder
|
||||
*/
|
||||
Set<Feature> activeFeatures(Placeholder placeholder);
|
||||
|
||||
/**
|
||||
* Returns the placeholders that are actively used by the player's features.
|
||||
*
|
||||
* @return an array of active placeholders
|
||||
*/
|
||||
Placeholder[] activePlaceholders();
|
||||
|
||||
/**
|
||||
* Retrieves the list of placeholders that need to be refreshed based on their refresh intervals.
|
||||
*
|
||||
* @return a list of placeholders to refresh
|
||||
*/
|
||||
List<Placeholder> activePlaceholdersToRefresh();
|
||||
|
||||
/**
|
||||
* Forces an update for the specified placeholders and relational placeholders with another player.
|
||||
*
|
||||
* @param placeholders the placeholders to update
|
||||
* @param another the players related to the placeholders
|
||||
*/
|
||||
void forceUpdatePlaceholders(Set<Placeholder> placeholders, Collection<CNPlayer> another);
|
||||
|
||||
/**
|
||||
* Retrieves the cached data for a given placeholder.
|
||||
*
|
||||
* @param placeholder the placeholder to retrieve data for
|
||||
* @return the cached data as a string
|
||||
*/
|
||||
@NotNull
|
||||
String getCachedSharedValue(SharedPlaceholder placeholder);
|
||||
|
||||
/**
|
||||
* Retrieves the cached data for a given placeholder.
|
||||
*
|
||||
* @param placeholder the placeholder to retrieve data for
|
||||
* @return the cached data as a string
|
||||
*/
|
||||
@NotNull
|
||||
String getCachedPlayerValue(PlayerPlaceholder placeholder);
|
||||
|
||||
/**
|
||||
* Retrieves the cached relational data between this player and another for a given placeholder.
|
||||
*
|
||||
* @param placeholder the relational placeholder
|
||||
* @param another the other player
|
||||
* @return the relational data as a string
|
||||
*/
|
||||
@NotNull
|
||||
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.
|
||||
*
|
||||
* @param placeholder the relational placeholder
|
||||
* @param another the other player
|
||||
* @return the cached relational TickStampData, or null if none exists
|
||||
*/
|
||||
@Nullable
|
||||
TimeStampData<String> getRawRelationalValue(RelationalPlaceholder placeholder, CNPlayer another);
|
||||
|
||||
/**
|
||||
* Caches the specified {@link TimeStampData} for the given placeholder.
|
||||
*
|
||||
* @param placeholder the placeholder to cache
|
||||
* @param value the value to cache
|
||||
*/
|
||||
void setPlayerValue(PlayerPlaceholder placeholder, TimeStampData<String> value);
|
||||
|
||||
/**
|
||||
* Caches the specified {@link TimeStampData} for the given placeholder.
|
||||
*
|
||||
* @param placeholder the placeholder to cache
|
||||
* @param value the value to cache
|
||||
*/
|
||||
void setSharedValue(SharedPlaceholder placeholder, TimeStampData<String> value);
|
||||
|
||||
/**
|
||||
* Caches the specified relational {@link TimeStampData} for a given placeholder and player.
|
||||
*
|
||||
* @param placeholder the relational placeholder
|
||||
* @param another the other player
|
||||
* @param value the value to cache
|
||||
*/
|
||||
void setRelationalValue(RelationalPlaceholder placeholder, CNPlayer another, TimeStampData<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
|
||||
*
|
||||
* @param feature the feature to add
|
||||
*/
|
||||
void addFeature(Feature feature);
|
||||
|
||||
/**
|
||||
* Removes a feature from the player.
|
||||
*
|
||||
* @param feature the feature to remove
|
||||
*/
|
||||
void removeFeature(Feature feature);
|
||||
|
||||
/**
|
||||
* Checks if the player meets the specified requirements.
|
||||
*
|
||||
* @param requirements the requirements to check
|
||||
* @return true if all requirements are met, false otherwise
|
||||
*/
|
||||
boolean isMet(Requirement[] requirements);
|
||||
|
||||
/**
|
||||
* Checks if the player meets the specified relational requirements with another player.
|
||||
*
|
||||
* @param another the other player
|
||||
* @param requirements the relational requirements to check
|
||||
* @return true if all requirements are met, false otherwise
|
||||
*/
|
||||
boolean isMet(CNPlayer another, Requirement[] requirements);
|
||||
|
||||
/**
|
||||
* Adds a player to be track this player, creating a tracker for relational placeholders.
|
||||
*
|
||||
* @param another the player
|
||||
* @return the tracker instance
|
||||
*/
|
||||
Tracker addPlayerToTracker(CNPlayer another);
|
||||
|
||||
/**
|
||||
* Removes a player from tracking this player.
|
||||
*
|
||||
* @param another the player to stop tracking
|
||||
*/
|
||||
void removePlayerFromTracker(CNPlayer another);
|
||||
|
||||
/**
|
||||
* Retrieves the set of nearby players tracking this player.
|
||||
*
|
||||
* @return the set of nearby players
|
||||
*/
|
||||
Collection<CNPlayer> nearbyPlayers();
|
||||
|
||||
/**
|
||||
* Adds passenger entities to the tracker for another player.
|
||||
*
|
||||
* @param another the player whose passengers to track
|
||||
* @param passengers the IDs of the passenger entities
|
||||
*/
|
||||
void trackPassengers(CNPlayer another, int... passengers);
|
||||
|
||||
/**
|
||||
* Removes passenger entities from the tracker for another player.
|
||||
*
|
||||
* @param another the player whose passengers to stop tracking
|
||||
* @param passengers the IDs of the passenger entities
|
||||
*/
|
||||
void untrackPassengers(CNPlayer another, int... passengers);
|
||||
|
||||
/**
|
||||
* Retrieves the IDs of tracked passenger entities for another player.
|
||||
*
|
||||
* @param another the viewer
|
||||
* @return the set of passenger entity IDs
|
||||
*/
|
||||
Set<Integer> getTrackedPassengerIds(CNPlayer another);
|
||||
|
||||
/**
|
||||
* Retrieves the IDs of all passenger entities currently associated with this player.
|
||||
*
|
||||
* @return the set of passenger entity IDs
|
||||
*/
|
||||
Set<Integer> passengers();
|
||||
|
||||
/**
|
||||
* Retrieves the tracker instance for another player.
|
||||
*
|
||||
* @param another the viewer
|
||||
* @return the tracker instance, or null if none exists
|
||||
*/
|
||||
Tracker getTracker(CNPlayer another);
|
||||
|
||||
/**
|
||||
* Returns the ID of the currently equipped bubble for the player.
|
||||
*
|
||||
* @return the ID of the equipped bubble
|
||||
*/
|
||||
String equippedBubble();
|
||||
|
||||
/**
|
||||
* Sets the equipped bubble for the player.
|
||||
* Operation would fail if player is not loaded.
|
||||
*
|
||||
* @param equippedBubble the new bubble ID to equip
|
||||
* @return success or not
|
||||
*/
|
||||
boolean equippedBubble(String equippedBubble);
|
||||
|
||||
/**
|
||||
* Returns the ID of the currently equipped nameplate for the player.
|
||||
*
|
||||
* @return the ID of the equipped nameplate
|
||||
*/
|
||||
String equippedNameplate();
|
||||
|
||||
/**
|
||||
* Sets the equipped nameplate for the player.
|
||||
* Operation would fail if player is not loaded.
|
||||
*
|
||||
* @param equippedNameplate the new nameplate ID to equip
|
||||
* @return success or not
|
||||
*/
|
||||
boolean equippedNameplate(String equippedNameplate);
|
||||
|
||||
/**
|
||||
* Save the player's current nameplate/bubble to database
|
||||
*/
|
||||
void save();
|
||||
|
||||
/**
|
||||
* Get the player's team view
|
||||
*
|
||||
* @return team view
|
||||
*/
|
||||
TeamView teamView();
|
||||
|
||||
/**
|
||||
* Check if the player is initialized
|
||||
*
|
||||
* @return initialized or not
|
||||
*/
|
||||
boolean isInitialized();
|
||||
}
|
||||
@@ -0,0 +1,519 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning;
|
||||
import dev.dejvokep.boostedyaml.libs.org.snakeyaml.engine.v2.common.ScalarStyle;
|
||||
import dev.dejvokep.boostedyaml.libs.org.snakeyaml.engine.v2.nodes.Tag;
|
||||
import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings;
|
||||
import dev.dejvokep.boostedyaml.settings.general.GeneralSettings;
|
||||
import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings;
|
||||
import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings;
|
||||
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.common.locale.TranslationManager;
|
||||
import net.momirealms.customnameplates.common.plugin.CustomNameplatesProperties;
|
||||
import net.momirealms.customnameplates.common.plugin.config.ConfigLoader;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
|
||||
public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
|
||||
private static YamlDocument MAIN_CONFIG;
|
||||
|
||||
public static YamlDocument getMainConfig() {
|
||||
if (MAIN_CONFIG == null) {
|
||||
throw new IllegalStateException("Main config not loaded");
|
||||
}
|
||||
return MAIN_CONFIG;
|
||||
}
|
||||
|
||||
private static ConfigManager instance;
|
||||
|
||||
protected final CustomNameplates plugin;
|
||||
|
||||
protected boolean debug;
|
||||
protected boolean checkUpdate;
|
||||
protected boolean metrics;
|
||||
protected boolean nametagModule;
|
||||
protected boolean actionbarModule;
|
||||
protected boolean imageModule;
|
||||
protected boolean bossBarModule;
|
||||
protected boolean bubbleModule;
|
||||
protected boolean nameplateModule;
|
||||
protected boolean backgroundModule;
|
||||
protected boolean hideTeamNames;
|
||||
protected int defaultPlaceholderRefreshInterval;
|
||||
protected int defaultConditionRefreshInterval;
|
||||
protected int delaySend;
|
||||
protected boolean catchOtherActionBar;
|
||||
protected boolean displaySystemChat;
|
||||
protected int otherActionBarStayTime;
|
||||
|
||||
protected String namespace;
|
||||
protected String font;
|
||||
|
||||
protected boolean generateOnStart;
|
||||
|
||||
protected char initialChar;
|
||||
|
||||
protected String imagePath;
|
||||
protected String nameplatePath;
|
||||
protected String bubblePath;
|
||||
protected String spaceSplitPath;
|
||||
protected String backgroundPath;
|
||||
|
||||
protected boolean enableShader;
|
||||
protected boolean hideScoreBoardNumber;
|
||||
protected boolean animatedText;
|
||||
protected boolean itemsAdderEffect;
|
||||
|
||||
protected BossBar.Color removedBarColor;
|
||||
protected boolean bossBar1_20_2;
|
||||
protected boolean bossBar1_17;
|
||||
|
||||
protected boolean legacyUnicodes;
|
||||
|
||||
protected boolean packItemsAdder;
|
||||
protected boolean packItemsAdderLegacy;
|
||||
protected boolean packOraxen;
|
||||
protected boolean packNexo;
|
||||
protected boolean packCreativeCentral;
|
||||
|
||||
protected boolean chatUnsafe;
|
||||
protected boolean chatTR;
|
||||
protected boolean chatVenture;
|
||||
protected boolean chatHusk;
|
||||
protected boolean chatCarbon;
|
||||
protected boolean chatAdvanced;
|
||||
protected boolean chatEss;
|
||||
protected boolean chatChatControlRed;
|
||||
protected boolean chatChatty;
|
||||
|
||||
protected String configVersion;
|
||||
|
||||
public ConfigManager(CustomNameplates plugin) {
|
||||
this.plugin = plugin;
|
||||
instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
configVersion = CustomNameplatesProperties.getValue("config");
|
||||
MAIN_CONFIG = loadConfig("config.yml",
|
||||
GeneralSettings.builder()
|
||||
.setRouteSeparator('.')
|
||||
.setUseDefaults(false)
|
||||
.build(),
|
||||
LoaderSettings
|
||||
.builder()
|
||||
.setAutoUpdate(true)
|
||||
.build(),
|
||||
DumperSettings.builder()
|
||||
.setEscapeUnprintable(false)
|
||||
.setScalarFormatter((tag, value, role, def) -> {
|
||||
if (role == NodeRole.KEY) {
|
||||
return ScalarStyle.PLAIN;
|
||||
} else {
|
||||
return tag == Tag.STR ? ScalarStyle.DOUBLE_QUOTED : ScalarStyle.PLAIN;
|
||||
}
|
||||
})
|
||||
.build(),
|
||||
UpdaterSettings
|
||||
.builder()
|
||||
.setVersioning(new BasicVersioning("config-version"))
|
||||
.addIgnoredRoute(configVersion, "other-settings.placeholder-refresh-interval", '.')
|
||||
.addIgnoredRoute(configVersion, "other-settings.font-templates", '.')
|
||||
.addIgnoredRoute(configVersion, "other-settings.shift-fonts", '.')
|
||||
.build());
|
||||
try {
|
||||
MAIN_CONFIG.save(resolveConfig("config.yml").toFile());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
private void loadSettings() {
|
||||
YamlDocument config = MAIN_CONFIG;
|
||||
AdventureHelper.legacySupport = config.getBoolean("other-settings.legacy-color-code-support", true);
|
||||
TranslationManager.forceLocale(TranslationManager.parseLocale(config.getString("force-locale", "")));
|
||||
|
||||
// Basics
|
||||
debug = config.getBoolean("debug", false);
|
||||
metrics = config.getBoolean("metrics", false);
|
||||
checkUpdate = config.getBoolean("update-checker", false);
|
||||
|
||||
// Modules
|
||||
nametagModule = config.getBoolean("modules.nametags", true);
|
||||
actionbarModule = config.getBoolean("modules.actionbars", true);
|
||||
imageModule = config.getBoolean("modules.images", true);
|
||||
bossBarModule = config.getBoolean("modules.bossbars", true);
|
||||
bubbleModule = config.getBoolean("modules.bubbles", true);
|
||||
backgroundModule = config.getBoolean("modules.backgrounds", true);
|
||||
nameplateModule = config.getBoolean("modules.nameplates", true);
|
||||
|
||||
// Integrations
|
||||
packItemsAdder = config.getBoolean("integrations.resource-pack.ItemsAdder", false);
|
||||
packItemsAdderLegacy = config.getBoolean("integrations.resource-pack.ItemsAdder-old-method", false);
|
||||
if (packItemsAdder) packItemsAdderLegacy = false;
|
||||
packOraxen = config.getBoolean("integrations.resource-pack.Oraxen", false);
|
||||
packCreativeCentral = config.getBoolean("integrations.resource-pack.Creative-Central");
|
||||
packNexo = config.getBoolean("integrations.resource-pack.Nexo");
|
||||
|
||||
chatUnsafe = config.getBoolean("other-settings.unsafe-chat-event", false);
|
||||
chatEss = config.getBoolean("integrations.chat.Essentials", false);
|
||||
chatCarbon = config.getBoolean("integrations.chat.CarbonChat", false);
|
||||
chatHusk = config.getBoolean("integrations.chat.HuskChat", false);
|
||||
chatAdvanced = config.getBoolean("integrations.chat.AdvancedChat", false);
|
||||
chatTR = config.getBoolean("integrations.chat.TrChat", false);
|
||||
chatVenture = config.getBoolean("integrations.chat.VentureChat", false);
|
||||
chatChatControlRed = config.getBoolean("integrations.chat.ChatControlRed", false);
|
||||
chatChatty = config.getBoolean("integrations.chat.Chatty", false);
|
||||
|
||||
// Packs
|
||||
generateOnStart = !config.getBoolean("resource-pack.disable-generation-on-start", false);
|
||||
namespace = config.getString("resource-pack.namespace", "nameplates");
|
||||
font = config.getString("resource-pack.font", "default");
|
||||
initialChar = config.getChar("resource-pack.initial-char", '뀁');
|
||||
CharacterArranger.reset(initialChar);
|
||||
|
||||
nameplatePath = config.getString("resource-pack.image-path.nameplates", "font/nameplates/");
|
||||
backgroundPath = config.getString("resource-pack.image-path.backgrounds", "font/backgrounds/");
|
||||
imagePath = config.getString("resource-pack.image-path.images", "font/images/");
|
||||
bubblePath = config.getString("resource-pack.image-path.bubbles", "font/bubbles/");
|
||||
spaceSplitPath = config.getString("resource-pack.image-path.space-split", "font/base/");
|
||||
|
||||
enableShader = config.getBoolean("resource-pack.shader.enable", true);
|
||||
hideScoreBoardNumber = config.getBoolean("resource-pack.shader.hide-scoreboard-number", false);
|
||||
animatedText = config.getBoolean("resource-pack.shader.animated-text", false);
|
||||
itemsAdderEffect = config.getBoolean("resource-pack.shader.ItemsAdder-text-effects", false);
|
||||
|
||||
removedBarColor = BossBar.Color.valueOf(config.getString("resource-pack.transparent-bossbar.color", "YELLOW").toUpperCase(Locale.ENGLISH));
|
||||
bossBar1_20_2 = config.getBoolean("resource-pack.transparent-bossbar.1_20_2+", true);
|
||||
bossBar1_17 = config.getBoolean("resource-pack.transparent-bossbar.1_17-1_20_1", true);
|
||||
|
||||
legacyUnicodes = config.getBoolean("resource-pack.legacy-unicodes", true);
|
||||
|
||||
// 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.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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
Reloadable.super.unload();
|
||||
}
|
||||
|
||||
public static int delaySend() {
|
||||
return instance.delaySend;
|
||||
}
|
||||
|
||||
public static String spaceSplitPath() {
|
||||
return instance.spaceSplitPath;
|
||||
}
|
||||
|
||||
public static String bubblePath() {
|
||||
return instance.bubblePath;
|
||||
}
|
||||
|
||||
public static String imagePath() {
|
||||
return instance.imagePath;
|
||||
}
|
||||
|
||||
public static String backgroundPath() {
|
||||
return instance.backgroundPath;
|
||||
}
|
||||
|
||||
public static String nameplatePath() {
|
||||
return instance.nameplatePath;
|
||||
}
|
||||
|
||||
public static boolean generateOnStart() {
|
||||
return instance.generateOnStart;
|
||||
}
|
||||
|
||||
public static String namespace() {
|
||||
return instance.namespace;
|
||||
}
|
||||
|
||||
public static String font() {
|
||||
return instance.font;
|
||||
}
|
||||
|
||||
public static String configVersion() {
|
||||
return instance.configVersion;
|
||||
}
|
||||
|
||||
public static char initialChar() {
|
||||
return instance.initialChar;
|
||||
}
|
||||
|
||||
public static boolean hideTeamNames() {
|
||||
return instance.hideTeamNames;
|
||||
}
|
||||
|
||||
public static boolean actionbarModule() {
|
||||
return instance.actionbarModule;
|
||||
}
|
||||
|
||||
public static boolean nametagModule() {
|
||||
return instance.nametagModule;
|
||||
}
|
||||
|
||||
public static boolean catchOtherActionBar() {
|
||||
return instance.catchOtherActionBar;
|
||||
}
|
||||
|
||||
public static boolean displaySystemChat() {
|
||||
return instance.displaySystemChat;
|
||||
}
|
||||
|
||||
public static boolean packItemsAdder() {
|
||||
return instance.packItemsAdder;
|
||||
}
|
||||
|
||||
public static boolean packItemsAdderLegacy() {
|
||||
return instance.packItemsAdderLegacy;
|
||||
}
|
||||
|
||||
public static boolean packOraxen() {
|
||||
return instance.packOraxen;
|
||||
}
|
||||
|
||||
public static boolean packNexo() {
|
||||
return instance.packNexo;
|
||||
}
|
||||
|
||||
public static boolean packCreativeCentral() { return instance.packCreativeCentral; }
|
||||
|
||||
public static boolean hideScoreBoardNumber() {
|
||||
return instance.hideScoreBoardNumber;
|
||||
}
|
||||
|
||||
public static boolean animatedText() {
|
||||
return instance.animatedText;
|
||||
}
|
||||
|
||||
public static boolean itemsAdderEffect() {
|
||||
return instance.itemsAdderEffect;
|
||||
}
|
||||
|
||||
public static BossBar.Color removedBarColor() {
|
||||
return instance.removedBarColor;
|
||||
}
|
||||
|
||||
public static boolean imageModule() {
|
||||
return instance.imageModule;
|
||||
}
|
||||
|
||||
public static boolean bossbarModule() {
|
||||
return instance.bossBarModule;
|
||||
}
|
||||
|
||||
public static boolean bubbleModule() {
|
||||
return instance.bubbleModule;
|
||||
}
|
||||
|
||||
public static boolean backgroundModule() {
|
||||
return instance.backgroundModule;
|
||||
}
|
||||
|
||||
public static boolean nameplateModule() {
|
||||
return instance.nameplateModule;
|
||||
}
|
||||
|
||||
public static boolean debug() {
|
||||
return instance.debug;
|
||||
}
|
||||
|
||||
public static boolean checkUpdate() {
|
||||
return instance.checkUpdate;
|
||||
}
|
||||
|
||||
public static boolean metrics() {
|
||||
return instance.metrics;
|
||||
}
|
||||
|
||||
public static int defaultPlaceholderRefreshInterval() {
|
||||
return instance.defaultPlaceholderRefreshInterval;
|
||||
}
|
||||
|
||||
public static int defaultConditionRefreshInterval() {
|
||||
return instance.defaultConditionRefreshInterval;
|
||||
}
|
||||
|
||||
public static int otherActionBarStayTime() {
|
||||
return instance.otherActionBarStayTime;
|
||||
}
|
||||
|
||||
public static boolean enableShader() {
|
||||
return instance.enableShader;
|
||||
}
|
||||
|
||||
public static boolean legacyUnicodes() {
|
||||
return instance.legacyUnicodes;
|
||||
}
|
||||
|
||||
public static boolean bossBar1_20_2() {
|
||||
return instance.bossBar1_20_2;
|
||||
}
|
||||
|
||||
public static boolean bossBar1_17() {
|
||||
return instance.bossBar1_17;
|
||||
}
|
||||
|
||||
public static boolean chatUnsafe() {
|
||||
return instance.chatUnsafe;
|
||||
}
|
||||
|
||||
public static boolean chatTrChat() {
|
||||
return instance.chatTR;
|
||||
}
|
||||
|
||||
public static boolean chatVenture() {
|
||||
return instance.chatVenture;
|
||||
}
|
||||
|
||||
public static boolean chatHusk() {
|
||||
return instance.chatHusk;
|
||||
}
|
||||
|
||||
public static boolean chatEss() {
|
||||
return instance.chatEss;
|
||||
}
|
||||
|
||||
public static boolean chatCarbon() {
|
||||
return instance.chatCarbon;
|
||||
}
|
||||
|
||||
public static boolean chatAdvanced() {
|
||||
return instance.chatAdvanced;
|
||||
}
|
||||
|
||||
public static boolean chatChatControlRed() {
|
||||
return instance.chatChatControlRed;
|
||||
}
|
||||
|
||||
public static boolean chatChatty() {
|
||||
return instance.chatChatty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public YamlDocument loadConfig(String filePath) {
|
||||
return loadConfig(filePath, '.');
|
||||
}
|
||||
|
||||
@Override
|
||||
public YamlDocument loadConfig(String filePath, char routeSeparator) {
|
||||
try (InputStream inputStream = new FileInputStream(resolveConfig(filePath).toFile())) {
|
||||
return YamlDocument.create(
|
||||
inputStream,
|
||||
plugin.getResourceStream(filePath),
|
||||
GeneralSettings.builder().setRouteSeparator(routeSeparator).build(),
|
||||
LoaderSettings
|
||||
.builder()
|
||||
.setAutoUpdate(true)
|
||||
.build(),
|
||||
DumperSettings.builder()
|
||||
.setScalarFormatter((tag, value, role, def) -> {
|
||||
if (role == NodeRole.KEY) {
|
||||
return ScalarStyle.PLAIN;
|
||||
} else {
|
||||
return tag == Tag.STR ? ScalarStyle.DOUBLE_QUOTED : ScalarStyle.PLAIN;
|
||||
}
|
||||
})
|
||||
.build(),
|
||||
UpdaterSettings
|
||||
.builder()
|
||||
.setVersioning(new BasicVersioning("config-version"))
|
||||
.build()
|
||||
);
|
||||
} catch (IOException e) {
|
||||
plugin.getPluginLogger().severe("Failed to load config " + filePath, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public YamlDocument loadConfig(String filePath, GeneralSettings generalSettings, LoaderSettings loaderSettings, DumperSettings dumperSettings, UpdaterSettings updaterSettings) {
|
||||
try (InputStream inputStream = new FileInputStream(resolveConfig(filePath).toFile())) {
|
||||
return YamlDocument.create(
|
||||
inputStream,
|
||||
plugin.getResourceStream(filePath),
|
||||
generalSettings,
|
||||
loaderSettings,
|
||||
dumperSettings,
|
||||
updaterSettings
|
||||
);
|
||||
} catch (IOException e) {
|
||||
plugin.getPluginLogger().severe("Failed to load config " + filePath, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public YamlDocument loadData(File file) {
|
||||
try (InputStream inputStream = new FileInputStream(file)) {
|
||||
return YamlDocument.create(inputStream);
|
||||
} catch (IOException e) {
|
||||
plugin.getPluginLogger().severe("Failed to load config " + file, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Path resolveConfig(String filePath) {
|
||||
if (filePath == null || filePath.isEmpty()) {
|
||||
throw new IllegalArgumentException("ResourcePath cannot be null or empty");
|
||||
}
|
||||
filePath = filePath.replace('\\', '/');
|
||||
Path configFile = plugin.getConfigDirectory().resolve(filePath);
|
||||
// if the config doesn't exist, create it based on the template in the resources dir
|
||||
if (!Files.exists(configFile)) {
|
||||
try {
|
||||
Files.createDirectories(configFile.getParent());
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
try (InputStream is = plugin.getResourceStream(filePath)) {
|
||||
if (is == null) {
|
||||
throw new IllegalArgumentException("The embedded resource '" + filePath + "' cannot be found");
|
||||
}
|
||||
Files.copy(is, configFile);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return configFile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
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;
|
||||
import net.momirealms.customnameplates.api.feature.bossbar.BossBarManager;
|
||||
import net.momirealms.customnameplates.api.feature.bubble.BubbleManager;
|
||||
import net.momirealms.customnameplates.api.feature.chat.ChatManager;
|
||||
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;
|
||||
import net.momirealms.customnameplates.api.requirement.RequirementManager;
|
||||
import net.momirealms.customnameplates.api.storage.StorageManager;
|
||||
import net.momirealms.customnameplates.common.dependency.DependencyManager;
|
||||
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 java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Abstract class representing the core plugin management of CustomNameplates.
|
||||
* Provides access to managers for various features.
|
||||
*/
|
||||
public abstract class CustomNameplates implements NameplatesPlugin {
|
||||
|
||||
private static CustomNameplates instance;
|
||||
|
||||
protected DependencyManager dependencyManager;
|
||||
protected TranslationManager translationManager;
|
||||
protected Consumer<Supplier<String>> debugger = (s) -> getPluginLogger().info("[DEBUG] " + s.get());
|
||||
protected ConfigManager configManager;
|
||||
protected PacketSender packetSender;
|
||||
protected PipelineInjector pipelineInjector;
|
||||
protected PlaceholderManager placeholderManager;
|
||||
protected RequirementManager requirementManager;
|
||||
protected ActionBarManager actionBarManager;
|
||||
protected BossBarManager bossBarManager;
|
||||
protected UnlimitedTagManager unlimitedTagManager;
|
||||
protected Platform platform;
|
||||
protected MainTask mainTask;
|
||||
protected SchedulerTask scheduledMainTask;
|
||||
protected ConcurrentHashMap<UUID, CNPlayer> onlinePlayerMap = new ConcurrentHashMap<>();
|
||||
protected Int2ObjectOpenHashMap<CNPlayer> entityIDFastLookup = new Int2ObjectOpenHashMap<>();
|
||||
protected AdvanceManager advanceManager;
|
||||
protected BackgroundManager backgroundManager;
|
||||
protected EventManager eventManager;
|
||||
protected StorageManager storageManager;
|
||||
protected BubbleManager bubbleManager;
|
||||
protected ChatManager chatManager;
|
||||
protected ImageManager imageManager;
|
||||
protected NameplateManager nameplateManager;
|
||||
protected ResourcePackManager resourcePackManager;
|
||||
protected CustomNameplatesAPI api;
|
||||
|
||||
private String buildByBit = "%%__BUILTBYBIT__%%";
|
||||
private String polymart = "%%__POLYMART__%%";
|
||||
private String time = "%%__TIMESTAMP__%%";
|
||||
private String user = "%%__USER__%%";
|
||||
private String username = "%%__USERNAME__%%";
|
||||
private boolean isLatest = false;
|
||||
|
||||
protected CustomNameplates() {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the plugin
|
||||
*/
|
||||
@Override
|
||||
public abstract void reload();
|
||||
|
||||
/**
|
||||
* Disables the plugin, canceling any scheduled tasks.
|
||||
*/
|
||||
@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.
|
||||
*
|
||||
* @param supplier a supplier that provides debug messages
|
||||
*/
|
||||
@Override
|
||||
public void debug(Supplier<String> supplier) {
|
||||
this.debugger.accept(supplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dependency manager for managing external dependencies.
|
||||
*
|
||||
* @return the {@link DependencyManager} instance
|
||||
*/
|
||||
@Override
|
||||
public DependencyManager getDependencyManager() {
|
||||
return dependencyManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translation manager for managing language translations.
|
||||
*
|
||||
* @return the {@link TranslationManager} instance
|
||||
*/
|
||||
@Override
|
||||
public TranslationManager getTranslationManager() {
|
||||
return translationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration manager for managing plugin configurations.
|
||||
*
|
||||
* @return the {@link ConfigManager} instance
|
||||
*/
|
||||
@Override
|
||||
public ConfigManager getConfigManager() {
|
||||
return configManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the manager responsible for handling placeholders.
|
||||
*
|
||||
* @return the {@link PlaceholderManager} instance
|
||||
*/
|
||||
public PlaceholderManager getPlaceholderManager() {
|
||||
return placeholderManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the packet sender responsible for sending network packets to players.
|
||||
*
|
||||
* @return the {@link PacketSender} instance
|
||||
*/
|
||||
public PacketSender getPacketSender() {
|
||||
return packetSender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requirement manager responsible for managing requirements.
|
||||
*
|
||||
* @return the {@link RequirementManager} instance
|
||||
*/
|
||||
public RequirementManager getRequirementManager() {
|
||||
return requirementManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the action bar manager responsible for managing action bar displays.
|
||||
*
|
||||
* @return the {@link ActionBarManager} instance
|
||||
*/
|
||||
public ActionBarManager getActionBarManager() {
|
||||
return actionBarManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the manager responsible for handling unlimited tags.
|
||||
*
|
||||
* @return the {@link UnlimitedTagManager} instance
|
||||
*/
|
||||
public UnlimitedTagManager getUnlimitedTagManager() {
|
||||
return unlimitedTagManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the manager responsible for handling font advances.
|
||||
*
|
||||
* @return the {@link AdvanceManager} instance
|
||||
*/
|
||||
public AdvanceManager getAdvanceManager() {
|
||||
return advanceManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the background manager responsible for handling background images.
|
||||
*
|
||||
* @return the {@link BackgroundManager} instance
|
||||
*/
|
||||
public BackgroundManager getBackgroundManager() {
|
||||
return backgroundManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the event manager responsible for managing events.
|
||||
*
|
||||
* @return the {@link EventManager} instance
|
||||
*/
|
||||
@Override
|
||||
public EventManager getEventManager() {
|
||||
return eventManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage manager responsible for handling data storage.
|
||||
*
|
||||
* @return the {@link StorageManager} instance
|
||||
*/
|
||||
public StorageManager getStorageManager() {
|
||||
return storageManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nameplate manager responsible for managing nameplate images.
|
||||
*
|
||||
* @return the {@link NameplateManager} instance
|
||||
*/
|
||||
public NameplateManager getNameplateManager() {
|
||||
return nameplateManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image manager responsible for handling images used within the plugin.
|
||||
*
|
||||
* @return the {@link ImageManager} instance
|
||||
*/
|
||||
public ImageManager getImageManager() {
|
||||
return imageManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bubble manager responsible for managing chat bubbles.
|
||||
*
|
||||
* @return the {@link BubbleManager} instance
|
||||
*/
|
||||
public BubbleManager getBubbleManager() {
|
||||
return bubbleManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the chat manager responsible for managing chat-related features.
|
||||
*
|
||||
* @return the {@link ChatManager} instance
|
||||
*/
|
||||
public ChatManager getChatManager() {
|
||||
return chatManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource pack manager responsible for managing custom resource packs.
|
||||
*
|
||||
* @return the {@link ResourcePackManager} instance
|
||||
*/
|
||||
public ResourcePackManager getResourcePackManager() {
|
||||
return resourcePackManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API class
|
||||
*
|
||||
* @return api
|
||||
*/
|
||||
public CustomNameplatesAPI getAPI() {
|
||||
return api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the platform object for accessing platform-specific functionality.
|
||||
*
|
||||
* @return the {@link Platform} instance
|
||||
*/
|
||||
public Platform getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collection of all currently online players.
|
||||
*
|
||||
* @return a collection of {@link CNPlayer} instances
|
||||
*/
|
||||
public Collection<CNPlayer> getOnlinePlayers() {
|
||||
return new ObjectArrayList<>(onlinePlayerMap.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a player by their UUID.
|
||||
*
|
||||
* @param uuid the UUID of the player
|
||||
* @return the {@link CNPlayer} instance, or null if not found
|
||||
*/
|
||||
public CNPlayer getPlayer(UUID uuid) {
|
||||
return onlinePlayerMap.get(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a player by their entity ID.
|
||||
*
|
||||
* @param entityID the entity ID of the player
|
||||
* @return the {@link CNPlayer} instance, or null if not found
|
||||
*/
|
||||
public CNPlayer getPlayer(int entityID) {
|
||||
return entityIDFastLookup.get(entityID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of CustomNameplates.
|
||||
*
|
||||
* @return the {@link CustomNameplates} instance
|
||||
*/
|
||||
public static CustomNameplates getInstance() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.AdaptiveImage;
|
||||
import net.momirealms.customnameplates.api.feature.OffsetFont;
|
||||
import net.momirealms.customnameplates.api.feature.background.Background;
|
||||
import net.momirealms.customnameplates.api.feature.bubble.Bubble;
|
||||
import net.momirealms.customnameplates.api.feature.nameplate.Nameplate;
|
||||
import net.momirealms.customnameplates.api.helper.AdventureHelper;
|
||||
import net.momirealms.customnameplates.api.placeholder.internal.StaticPosition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public record CustomNameplatesAPI(CustomNameplates plugin) {
|
||||
|
||||
private static CustomNameplatesAPI instance;
|
||||
|
||||
public CustomNameplatesAPI(CustomNameplates plugin) {
|
||||
this.plugin = plugin;
|
||||
instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CustomNameplates plugin instance.
|
||||
*
|
||||
* @return the CustomNameplates plugin
|
||||
*/
|
||||
@Override
|
||||
public CustomNameplates plugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a player by their UUID.
|
||||
*
|
||||
* @param uuid the player's UUID
|
||||
* @return the CNPlayer object if found, otherwise null
|
||||
*/
|
||||
@Nullable
|
||||
public CNPlayer getPlayer(UUID uuid) {
|
||||
return plugin.getPlayer(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a Background by its ID.
|
||||
*
|
||||
* @param id the background ID
|
||||
* @return an Optional containing the Background if found, or empty if not
|
||||
*/
|
||||
@NotNull
|
||||
public Optional<Background> getBackground(@NotNull String id) {
|
||||
return Optional.ofNullable(plugin.getBackgroundManager().backgroundById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a Nameplate by its ID.
|
||||
*
|
||||
* @param id the nameplate ID
|
||||
* @return an Optional containing the Nameplate if found, or empty if not
|
||||
*/
|
||||
@NotNull
|
||||
public Optional<Nameplate> getNameplate(@NotNull String id) {
|
||||
return Optional.ofNullable(plugin.getNameplateManager().nameplateById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a Bubble by its ID.
|
||||
*
|
||||
* @param id the bubble ID
|
||||
* @return an Optional containing the Bubble if found, or empty if not
|
||||
*/
|
||||
@NotNull
|
||||
public Optional<Bubble> getBubble(@NotNull String id) {
|
||||
return Optional.ofNullable(plugin.getBubbleManager().bubbleById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a text string with an image, applying margins around the image.
|
||||
*
|
||||
* @param text the text to be displayed
|
||||
* @param adaptiveImage the image to insert with the text
|
||||
* @param leftMargin the margin to apply on the left of the image
|
||||
* @param rightMargin the margin to apply on the right of the image
|
||||
* @return the resulting string with the image and margins
|
||||
*/
|
||||
@NotNull
|
||||
public String createTextWithImage(@NotNull String text, @NotNull AdaptiveImage adaptiveImage, float leftMargin, float rightMargin) {
|
||||
if (AdventureHelper.legacySupport) {
|
||||
text = AdventureHelper.legacyToMiniMessage(text);
|
||||
}
|
||||
float advance = plugin.getAdvanceManager().getLineAdvance(text);
|
||||
return adaptiveImage.createImagePrefix(advance, leftMargin, rightMargin) + text + adaptiveImage.createImageSuffix(advance, leftMargin, rightMargin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width advance (text length in visual representation) for a given text.
|
||||
*
|
||||
* @param text the text to measure
|
||||
* @return the advance width of the text
|
||||
*/
|
||||
public float getTextAdvance(@NotNull String text) {
|
||||
return plugin.getAdvanceManager().getLineAdvance(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a statically positioned text, aligning it to the left, right, or middle
|
||||
* of the specified width.
|
||||
*
|
||||
* @param text the text to be positioned
|
||||
* @param width the total width for the text positioning
|
||||
* @param position the desired static position (LEFT, RIGHT, MIDDLE)
|
||||
* @return the resulting string with the appropriate positioning
|
||||
*/
|
||||
@NotNull
|
||||
public String createStaticText(@NotNull String text, int width, @NotNull StaticPosition position) {
|
||||
float parsedWidth = CustomNameplates.getInstance().getAdvanceManager().getLineAdvance(text);
|
||||
switch (position) {
|
||||
case LEFT -> {
|
||||
return text + AdventureHelper.surroundWithNameplatesFont(OffsetFont.createOffsets(width - parsedWidth));
|
||||
}
|
||||
case RIGHT -> {
|
||||
return AdventureHelper.surroundWithNameplatesFont(OffsetFont.createOffsets(width - parsedWidth)) + text;
|
||||
}
|
||||
case MIDDLE -> {
|
||||
int half = (int) ((width - parsedWidth) / 2);
|
||||
String left = AdventureHelper.surroundWithNameplatesFont(OffsetFont.createOffsets(half));
|
||||
String right = AdventureHelper.surroundWithNameplatesFont(OffsetFont.createOffsets(width - parsedWidth - half));
|
||||
return left + text + right;
|
||||
}
|
||||
default -> {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of CustomNameplatesAPI.
|
||||
* Throws an exception if the API has not been initialized.
|
||||
*
|
||||
* @return the CustomNameplatesAPI instance
|
||||
*/
|
||||
public static CustomNameplatesAPI getInstance() {
|
||||
if (instance == null) {
|
||||
throw new RuntimeException("Nameplates API has not been initialized yet.");
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api;
|
||||
|
||||
import net.momirealms.customnameplates.api.manager.*;
|
||||
import net.momirealms.customnameplates.api.scheduler.Scheduler;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public abstract class CustomNameplatesPlugin extends JavaPlugin {
|
||||
|
||||
protected static CustomNameplatesPlugin instance;
|
||||
protected Scheduler scheduler;
|
||||
protected StorageManager storageManager;
|
||||
protected VersionManager versionManager;
|
||||
protected AdventureManager adventureManager;
|
||||
protected RequirementManager requirementManager;
|
||||
protected BossBarManager bossBarManager;
|
||||
protected ImageManager imageManager;
|
||||
protected PlaceholderManager placeholderManager;
|
||||
protected ResourcePackManager resourcePackManager;
|
||||
protected BackGroundManager backGroundManager;
|
||||
protected TeamManager teamManager;
|
||||
protected NameplateManager nameplateManager;
|
||||
protected ActionBarManager actionBarManager;
|
||||
protected WidthManager widthManager;
|
||||
protected BubbleManager bubbleManager;
|
||||
|
||||
protected CustomNameplatesPlugin() {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
/* Get plugin instance */
|
||||
public static CustomNameplatesPlugin getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/* Get plugin instance */
|
||||
public static CustomNameplatesPlugin get() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/* reload the plugin */
|
||||
public abstract void reload();
|
||||
|
||||
/* Get the scheduler */
|
||||
public Scheduler getScheduler() {
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
/* Get the storage manager */
|
||||
public StorageManager getStorageManager() {
|
||||
return storageManager;
|
||||
}
|
||||
|
||||
/* Get the requirement manager */
|
||||
public RequirementManager getRequirementManager() {
|
||||
return requirementManager;
|
||||
}
|
||||
|
||||
/* Get the image manager */
|
||||
public ImageManager getImageManager() {
|
||||
return imageManager;
|
||||
}
|
||||
|
||||
/* Get the background manager */
|
||||
public BackGroundManager getBackGroundManager() {
|
||||
return backGroundManager;
|
||||
}
|
||||
|
||||
/* Get the resource pack manager */
|
||||
public ResourcePackManager getResourcePackManager() {
|
||||
return resourcePackManager;
|
||||
}
|
||||
|
||||
/* Get the adventure manager */
|
||||
public AdventureManager getAdventure() {
|
||||
return adventureManager;
|
||||
}
|
||||
|
||||
/* Get the version manager */
|
||||
public VersionManager getVersionManager() {
|
||||
return versionManager;
|
||||
}
|
||||
|
||||
/* Get the bossbar manager */
|
||||
public BossBarManager getBossBarManager() {
|
||||
return bossBarManager;
|
||||
}
|
||||
|
||||
/* Get the placeholder manager */
|
||||
public PlaceholderManager getPlaceholderManager() {
|
||||
return placeholderManager;
|
||||
}
|
||||
|
||||
/* Get the team manager */
|
||||
public TeamManager getTeamManager() {
|
||||
return teamManager;
|
||||
}
|
||||
|
||||
/* Get the actionbar manager */
|
||||
public ActionBarManager getActionBarManager() {
|
||||
return actionBarManager;
|
||||
}
|
||||
|
||||
/* Get the nameplate manager */
|
||||
public NameplateManager getNameplateManager() {
|
||||
return nameplateManager;
|
||||
}
|
||||
|
||||
/* Get the width manager */
|
||||
public WidthManager getWidthManager() {
|
||||
return widthManager;
|
||||
}
|
||||
|
||||
/* Get the bubble manager */
|
||||
public BubbleManager getBubbleManager() {
|
||||
return bubbleManager;
|
||||
}
|
||||
|
||||
/* debug get config by file name */
|
||||
public abstract YamlConfiguration getConfig(String file);
|
||||
|
||||
/* debug message */
|
||||
public abstract void debug(String s);
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
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 ObjectOpenHashSet<>());
|
||||
private int timer;
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
private boolean state;
|
||||
|
||||
public MainTask(CustomNameplates plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public static int getTicks() {
|
||||
return RUN_TICKS;
|
||||
}
|
||||
|
||||
public static boolean hasRequested(int countId) {
|
||||
return !requestedSharedPlaceholders.add(countId);
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
RUN_TICKS = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
public static HealthyProfile getHealthyProfile() {
|
||||
long total1 = TIME_1.values().stream().mapToLong(Integer::longValue).sum();
|
||||
long total2 = TIME_2.values().stream().mapToLong(Integer::longValue).sum();
|
||||
|
||||
long total = total1 + total2;
|
||||
double size = TIME_1.size();
|
||||
|
||||
double load = total / size / 50_000_000;
|
||||
|
||||
return new HealthyProfile(
|
||||
load,
|
||||
(long) (total / size),
|
||||
(int) (total1 / size),
|
||||
(int) (total2 / size)
|
||||
);
|
||||
}
|
||||
|
||||
public static class HealthyProfile {
|
||||
|
||||
private final double load;
|
||||
private final long totalTimeNS;
|
||||
|
||||
private final int actionBarConditionNS;
|
||||
private final int refreshPlaceholderNS;
|
||||
|
||||
public HealthyProfile(
|
||||
double load,
|
||||
long totalTimeNS,
|
||||
int actionBarConditionNS,
|
||||
int refreshPlaceholderNS
|
||||
) {
|
||||
this.actionBarConditionNS = actionBarConditionNS;
|
||||
this.refreshPlaceholderNS = refreshPlaceholderNS;
|
||||
this.load = load;
|
||||
this.totalTimeNS = totalTimeNS;
|
||||
}
|
||||
|
||||
public int getActionBarConditionNS() {
|
||||
return actionBarConditionNS;
|
||||
}
|
||||
|
||||
public int getRefreshPlaceholderNS() {
|
||||
return refreshPlaceholderNS;
|
||||
}
|
||||
|
||||
public double getLoad() {
|
||||
return load;
|
||||
}
|
||||
|
||||
public long getTotalTimeNS() {
|
||||
return totalTimeNS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.bossbar.BossBar;
|
||||
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.Vector3;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Platform interface to abstract platform-specific operations for Minecraft components, packets, and placeholders.
|
||||
*/
|
||||
public interface Platform {
|
||||
|
||||
/**
|
||||
* Converts a JSON string to a Minecraft component.
|
||||
*
|
||||
* @param json the JSON string
|
||||
* @return the Minecraft component object
|
||||
*/
|
||||
Object jsonToMinecraftComponent(String json);
|
||||
|
||||
/**
|
||||
* Converts a Minecraft component to a JSON string.
|
||||
*
|
||||
* @param component the Minecraft component
|
||||
* @return the JSON string representation
|
||||
*/
|
||||
String minecraftComponentToJson(Object component);
|
||||
|
||||
/**
|
||||
* Creates a vector object from the specified coordinates.
|
||||
*
|
||||
* @param x the X coordinate
|
||||
* @param y the Y coordinate
|
||||
* @param z the Z coordinate
|
||||
* @return a vector object
|
||||
*/
|
||||
Object vec3(double x, double y, double z);
|
||||
|
||||
/**
|
||||
* Registers a platform-specific placeholder.
|
||||
*
|
||||
* @param id the placeholder ID
|
||||
* @return the registered {@link Placeholder} object
|
||||
*/
|
||||
Placeholder registerPlatformPlaceholder(String id);
|
||||
|
||||
/**
|
||||
* Handles an event triggered when a packet is sent to a player.
|
||||
*
|
||||
* @param player the player receiving the packet
|
||||
* @param event the packet event
|
||||
*/
|
||||
void onPacketSend(CNPlayer player, PacketEvent event);
|
||||
|
||||
/**
|
||||
* Creates an action bar text packet for displaying a message in the action bar.
|
||||
*
|
||||
* @param component the component containing the text
|
||||
* @return the action bar packet object
|
||||
*/
|
||||
Object setActionBarTextPacket(Object component);
|
||||
|
||||
/**
|
||||
* Creates a boss bar packet for displaying a boss bar to a player.
|
||||
*
|
||||
* @param uuid the UUID of the boss bar
|
||||
* @param component the component containing the boss bar text
|
||||
* @param progress the boss bar progress (0.0 to 1.0)
|
||||
* @param overlay the boss bar overlay style
|
||||
* @param color the boss bar color
|
||||
* @return the boss bar packet object
|
||||
*/
|
||||
Object createBossBarPacket(UUID uuid, Object component, float progress, BossBar.Overlay overlay, BossBar.Color color);
|
||||
|
||||
/**
|
||||
* Creates a packet to remove a boss bar.
|
||||
*
|
||||
* @param uuid the UUID of the boss bar to remove
|
||||
* @return the remove boss bar packet object
|
||||
*/
|
||||
Object removeBossBarPacket(UUID uuid);
|
||||
|
||||
/**
|
||||
* Creates a packet to update the name of a boss bar.
|
||||
*
|
||||
* @param uuid the UUID of the boss bar
|
||||
* @param component the component containing the new name
|
||||
* @return the update boss bar name packet object
|
||||
*/
|
||||
Object updateBossBarNamePacket(UUID uuid, Object component);
|
||||
|
||||
/**
|
||||
* 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 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
|
||||
* @return a list of packets for creating the text display
|
||||
*/
|
||||
List<Object> createTextDisplayPacket(
|
||||
int entityID, UUID uuid,
|
||||
Vector3 position, float pitch, float yaw, double headYaw,
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates a modifier for interpolation delay.
|
||||
*
|
||||
* @param delay the interpolation delay
|
||||
* @return a consumer that applies the modifier to a list of packets
|
||||
*/
|
||||
Consumer<List<Object>> createInterpolationDelayModifier(int delay);
|
||||
|
||||
/**
|
||||
* Creates a modifier for transformation interpolation duration.
|
||||
*
|
||||
* @param duration the transformation interpolation duration
|
||||
* @return a consumer that applies the modifier to a list of packets
|
||||
*/
|
||||
Consumer<List<Object>> createTransformationInterpolationDurationModifier(int duration);
|
||||
|
||||
/**
|
||||
* Creates a modifier to change the text component of a packet.
|
||||
*
|
||||
* @param component the new text component
|
||||
* @return a consumer that applies the modifier to a list of packets
|
||||
*/
|
||||
Consumer<List<Object>> createTextComponentModifier(Object component);
|
||||
|
||||
/**
|
||||
* Creates a modifier to change the scale of a text display.
|
||||
*
|
||||
* @param scale the new scale
|
||||
* @return a consumer that applies the modifier to a list of packets
|
||||
*/
|
||||
Consumer<List<Object>> createScaleModifier(Vector3 scale);
|
||||
|
||||
/**
|
||||
* Creates a modifier to change the translation of a text display.
|
||||
*
|
||||
* @param translation the new translation
|
||||
* @return a consumer that applies the modifier to a list of packets
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Updates an existing text display entity with modifiers.
|
||||
*
|
||||
* @param entityID the entity ID of the text display
|
||||
* @param modifiers the list of modifiers to apply
|
||||
* @return the update text display packet object
|
||||
*/
|
||||
Object updateTextDisplayPacket(int entityID, List<Consumer<List<Object>>> modifiers);
|
||||
|
||||
/**
|
||||
* Creates a packet to set passengers for a vehicle entity.
|
||||
*
|
||||
* @param vehicle the vehicle entity ID
|
||||
* @param passengers the passenger entity IDs
|
||||
* @return the set passengers packet object
|
||||
*/
|
||||
Object setPassengersPacket(int vehicle, int[] passengers);
|
||||
|
||||
/**
|
||||
* Creates a packet to remove entities from the game world.
|
||||
*
|
||||
* @param entityID the entity IDs to remove
|
||||
* @return the remove entity packet object
|
||||
*/
|
||||
Object removeEntityPacket(int... entityID);
|
||||
|
||||
/**
|
||||
* Gets the biome based on location
|
||||
*
|
||||
* @param world world
|
||||
* @param x x
|
||||
* @param y y
|
||||
* @param z z
|
||||
* @return the biome key
|
||||
*/
|
||||
String getBiome(String world, int x, int y, int z);
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.data;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface DataStorageInterface {
|
||||
|
||||
/**
|
||||
* Initialize the data resource
|
||||
*/
|
||||
void initialize();
|
||||
|
||||
/**
|
||||
* Close the data resource
|
||||
*/
|
||||
void disable();
|
||||
|
||||
/**
|
||||
* Get the storage data source type
|
||||
*
|
||||
* @return {@link StorageType}
|
||||
*/
|
||||
StorageType getStorageType();
|
||||
|
||||
/**
|
||||
* Get a player's data by uuid
|
||||
* This player can be an offline one
|
||||
*
|
||||
* @param uuid uuid
|
||||
* @return player data
|
||||
*/
|
||||
CompletableFuture<Optional<PlayerData>> getPlayerData(UUID uuid);
|
||||
|
||||
CompletableFuture<Boolean> updatePlayerData(UUID uuid, PlayerData playerData);
|
||||
|
||||
CompletableFuture<Boolean> updateOrInsertPlayerData(UUID uuid, PlayerData playerData);
|
||||
|
||||
Set<UUID> getUniqueUsers(boolean legacy);
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.data;
|
||||
|
||||
import net.momirealms.customnameplates.api.CustomNameplatesPlugin;
|
||||
import net.momirealms.customnameplates.api.mechanic.bubble.Bubble;
|
||||
import net.momirealms.customnameplates.api.mechanic.nameplate.Nameplate;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class OnlineUser {
|
||||
|
||||
private final Player player;
|
||||
private String nameplate;
|
||||
private String bubble;
|
||||
|
||||
public OnlineUser(Player player, PlayerData playerData) {
|
||||
this.player = player;
|
||||
this.nameplate = playerData.getNameplate();
|
||||
this.bubble = playerData.getBubble();
|
||||
}
|
||||
|
||||
public PlayerData toPlayerData() {
|
||||
return PlayerData.builder()
|
||||
.setBubble(bubble)
|
||||
.setNameplate(nameplate)
|
||||
.build();
|
||||
}
|
||||
|
||||
public UUID getUUID() {
|
||||
return player.getUniqueId();
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original nameplate key from data
|
||||
*/
|
||||
@NotNull
|
||||
public String getNameplateKey() {
|
||||
return nameplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original bubble key from data
|
||||
*/
|
||||
@NotNull
|
||||
public String getBubbleKey() {
|
||||
return bubble;
|
||||
}
|
||||
|
||||
/**
|
||||
* This value might be inconsistent with the key get by "getNameplateKey()"
|
||||
* Because if a player doesn't have a nameplate, his nameplate would be the default one
|
||||
*/
|
||||
@Nullable
|
||||
public Nameplate getNameplate() {
|
||||
String temp = nameplate;
|
||||
if (temp.equals("none")) {
|
||||
temp = CustomNameplatesPlugin.get().getNameplateManager().getDefaultNameplate();
|
||||
}
|
||||
return CustomNameplatesPlugin.get().getNameplateManager().getNameplate(temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* This value might be inconsistent with the key get by "getBubbleKey()"
|
||||
* Because if a player doesn't have a bubble, his bubble would be the default one
|
||||
*/
|
||||
@Nullable
|
||||
public Bubble getBubble() {
|
||||
String temp = nameplate;
|
||||
if (temp.equals("none")) {
|
||||
temp = CustomNameplatesPlugin.get().getBubbleManager().getDefaultBubble();
|
||||
}
|
||||
return CustomNameplatesPlugin.get().getBubbleManager().getBubble(temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set nameplate for a player
|
||||
*
|
||||
* @param nameplate nameplate
|
||||
*/
|
||||
public void setNameplate(String nameplate) {
|
||||
this.nameplate = nameplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bubble for a player
|
||||
*
|
||||
* @param bubble bubble
|
||||
*/
|
||||
public void setBubble(String bubble) {
|
||||
this.bubble = bubble;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.data;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PlayerData {
|
||||
|
||||
@SerializedName("nameplate")
|
||||
private String nameplate;
|
||||
@SerializedName("bubble")
|
||||
private String bubble;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static PlayerData empty() {
|
||||
return new PlayerData.Builder()
|
||||
.setNameplate("none")
|
||||
.setBubble("none")
|
||||
.build();
|
||||
}
|
||||
|
||||
public String getNameplate() {
|
||||
return nameplate;
|
||||
}
|
||||
|
||||
public String getBubble() {
|
||||
return bubble;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final PlayerData playerData;
|
||||
|
||||
public Builder() {
|
||||
this.playerData = new PlayerData();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder setNameplate(@Nullable String nameplate) {
|
||||
this.playerData.nameplate = nameplate;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder setBubble(@Nullable String bubble) {
|
||||
this.playerData.bubble = bubble;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PlayerData build() {
|
||||
return this.playerData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.event;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* An event triggered when player sends a message
|
||||
*/
|
||||
public class BubblesSpawnEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
private boolean cancelled;
|
||||
private String bubble;
|
||||
private String text;
|
||||
private static final HandlerList handlerList = new HandlerList();
|
||||
|
||||
public BubblesSpawnEvent(@NotNull Player who, String bubble, String text) {
|
||||
super(who, true);
|
||||
this.cancelled = false;
|
||||
this.bubble = bubble;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
cancelled = cancel;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlerList;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return getHandlerList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bubble's key
|
||||
*/
|
||||
public String getBubble() {
|
||||
return bubble;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bubble
|
||||
*
|
||||
* @param bubble bubble's key
|
||||
*/
|
||||
public void setBubble(String bubble) {
|
||||
this.bubble = bubble;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bubble text content
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bubble text content
|
||||
*
|
||||
* @param text text
|
||||
*/
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.event;
|
||||
|
||||
import net.momirealms.customnameplates.api.CustomNameplatesPlugin;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Plugin reload event
|
||||
*/
|
||||
public class CustomNameplatesReloadEvent extends Event {
|
||||
|
||||
private static final HandlerList handlerList = new HandlerList();
|
||||
private final CustomNameplatesPlugin plugin;
|
||||
|
||||
public CustomNameplatesReloadEvent(CustomNameplatesPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlerList;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return getHandlerList();
|
||||
}
|
||||
|
||||
public CustomNameplatesPlugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.event;
|
||||
|
||||
import net.momirealms.customnameplates.api.storage.data.PlayerData;
|
||||
import net.momirealms.customnameplates.common.event.NameplatesEvent;
|
||||
import net.momirealms.customnameplates.common.event.Param;
|
||||
|
||||
/**
|
||||
* Represents an event that is triggered when player data is loaded.
|
||||
* This event provides access to the {@link PlayerData} for further processing.
|
||||
*/
|
||||
public interface DataLoadEvent extends NameplatesEvent {
|
||||
|
||||
/**
|
||||
* Returns the {@link PlayerData} associated with this event.
|
||||
*
|
||||
* @return the loaded player data
|
||||
*/
|
||||
@Param(0)
|
||||
PlayerData data();
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.event;
|
||||
|
||||
import net.momirealms.customnameplates.api.data.OnlineUser;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Player data loaded event
|
||||
*/
|
||||
public class NameplateDataLoadEvent extends Event {
|
||||
|
||||
private static final HandlerList handlerList = new HandlerList();
|
||||
private final UUID uuid;
|
||||
private final OnlineUser onlineUser;
|
||||
|
||||
public NameplateDataLoadEvent(UUID uuid, OnlineUser onlineUser) {
|
||||
super(true);
|
||||
this.uuid = uuid;
|
||||
this.onlineUser = onlineUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UUID
|
||||
*
|
||||
* @return uuid
|
||||
*/
|
||||
public UUID getUUID() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the online user
|
||||
*
|
||||
* @return online user
|
||||
*/
|
||||
public OnlineUser getOnlineUser() {
|
||||
return onlineUser;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlerList;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return getHandlerList();
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.event;
|
||||
|
||||
import net.momirealms.customnameplates.common.event.NameplatesEvent;
|
||||
|
||||
/**
|
||||
* Represents an event that is triggered when the nameplates configuration is reloaded.
|
||||
*/
|
||||
public interface NameplatesReloadEvent extends NameplatesEvent {
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.feature;
|
||||
|
||||
public interface AdaptiveImage {
|
||||
|
||||
/**
|
||||
* Creates the prefix for the image with the specified advance and margins.
|
||||
*
|
||||
* @param advance the advance for the image
|
||||
* @param leftMargin the left margin for the image
|
||||
* @param rightMargin the right margin for the image
|
||||
* @return the generated image prefix
|
||||
*/
|
||||
String createImagePrefix(float advance, float leftMargin, float rightMargin);
|
||||
|
||||
/**
|
||||
* Creates the suffix for the image with the specified advance and margins.
|
||||
*
|
||||
* @param advance the advance for the image
|
||||
* @param leftMargin the left margin for the image
|
||||
* @param rightMargin the right margin for the image
|
||||
* @return the generated image suffix
|
||||
*/
|
||||
String createImageSuffix(float advance, float leftMargin, float rightMargin);
|
||||
|
||||
/**
|
||||
* Creates the full image string with the specified advance and margins.
|
||||
*
|
||||
* @param advance the advance for the image
|
||||
* @param leftMargin the left margin for the image
|
||||
* @param rightMargin the right margin for the image
|
||||
* @return the generated image string
|
||||
*/
|
||||
String createImage(float advance, float leftMargin, float rightMargin);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.feature;
|
||||
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
|
||||
/**
|
||||
* Represents a piece of carousel text, which cycles through a series of texts with associated requirements and duration.
|
||||
*/
|
||||
public class CarouselText {
|
||||
|
||||
private final int duration;
|
||||
private final Requirement[] requirements;
|
||||
private final String rawText;
|
||||
private final PreParsedDynamicText preParsedDynamicText;
|
||||
private final boolean updateOnDisplay;
|
||||
|
||||
/**
|
||||
* Constructs a new CarouselText instance.
|
||||
*
|
||||
* @param duration the duration (in ticks) for how long this text is displayed
|
||||
* @param requirements the requirements for displaying this text
|
||||
* @param rawText the raw text content
|
||||
* @param updateOnDisplay whether the text should be updated when displayed
|
||||
*/
|
||||
public CarouselText(int duration, Requirement[] requirements, String rawText, boolean updateOnDisplay) {
|
||||
this.duration = duration;
|
||||
this.requirements = requirements;
|
||||
this.rawText = rawText;
|
||||
this.preParsedDynamicText = new PreParsedDynamicText(rawText);
|
||||
this.preParsedDynamicText.init();
|
||||
this.updateOnDisplay = updateOnDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duration (in ticks) for how long this text will be displayed.
|
||||
*
|
||||
* @return the display duration
|
||||
*/
|
||||
public int duration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requirements that must be met to display this text.
|
||||
*
|
||||
* @return an array of requirements
|
||||
*/
|
||||
public Requirement[] requirements() {
|
||||
return requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw text content.
|
||||
*
|
||||
* @return the raw text
|
||||
*/
|
||||
public String text() {
|
||||
return rawText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pre-parsed dynamic text, which processes placeholders or dynamic content.
|
||||
*
|
||||
* @return the pre-parsed dynamic text
|
||||
*/
|
||||
public PreParsedDynamicText preParsedDynamicText() {
|
||||
return preParsedDynamicText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the text should be updated each time it is displayed.
|
||||
*
|
||||
* @return true if the text updates on display, false otherwise
|
||||
*/
|
||||
public boolean updateOnDisplay() {
|
||||
return updateOnDisplay;
|
||||
}
|
||||
}
|
||||
+18
-8
@@ -15,20 +15,30 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.character;
|
||||
package net.momirealms.customnameplates.api.feature;
|
||||
|
||||
/**
|
||||
* Utility class for automatically arranging characters.
|
||||
* Provides methods to increase, retrieve, and reset the current character.
|
||||
*/
|
||||
public class CharacterArranger {
|
||||
|
||||
/**
|
||||
* The current character being managed by the arranger.
|
||||
*/
|
||||
public static char currentChar;
|
||||
|
||||
/**
|
||||
* Increases the current character by 1.
|
||||
*/
|
||||
public static void increase() {
|
||||
currentChar = (char) (currentChar + '\u0001');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and increase the char arranged automatically by the plugin
|
||||
* Retrieves the current character and then increases it.
|
||||
*
|
||||
* @return char
|
||||
* @return the current character before increase
|
||||
*/
|
||||
public static char getAndIncrease() {
|
||||
char temp = currentChar;
|
||||
@@ -37,9 +47,9 @@ public class CharacterArranger {
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase and get the char arranged automatically by the plugin
|
||||
* Increases the current character and then retrieves it.
|
||||
*
|
||||
* @return char
|
||||
* @return the current character after increase
|
||||
*/
|
||||
public static char increaseAndGet() {
|
||||
increase();
|
||||
@@ -47,11 +57,11 @@ public class CharacterArranger {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the initial char
|
||||
* Resets the current character to the specified value.
|
||||
*
|
||||
* @param c char
|
||||
* @param c the character to reset to
|
||||
*/
|
||||
public static void reset(char c) {
|
||||
currentChar = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.feature;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
|
||||
/**
|
||||
* Represents a listener for player chat events, providing a callback method
|
||||
* when a player sends a message in a specific channel.
|
||||
*/
|
||||
public interface ChatListener {
|
||||
|
||||
/**
|
||||
* Called when a player sends a chat message in a specified channel.
|
||||
*
|
||||
* @param player the player who sent the message
|
||||
* @param message the content of the message
|
||||
* @param channel the channel where the message was sent
|
||||
*/
|
||||
void onPlayerChat(CNPlayer player, String message, String channel);
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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.feature;
|
||||
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents a configured character with associated image, dimensions, and advance (spacing).
|
||||
*/
|
||||
public class ConfiguredCharacter {
|
||||
|
||||
private final char character;
|
||||
private final File imageFile;
|
||||
private final int height;
|
||||
private final int ascent;
|
||||
private final float advance;
|
||||
|
||||
/**
|
||||
* Creates a new ConfiguredCharacter instance using an automatically assigned character.
|
||||
*
|
||||
* @param imageFile the image file associated with this character
|
||||
* @param ascent the ascent value (distance from the baseline to the top of the character)
|
||||
* @param height the height of the character
|
||||
* @return a new ConfiguredCharacter instance
|
||||
*/
|
||||
public static ConfiguredCharacter create(File imageFile, int ascent, int height) {
|
||||
return new ConfiguredCharacter(CharacterArranger.getAndIncrease(), imageFile, ascent, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ConfiguredCharacter instance using an automatically assigned character and a specified advance value.
|
||||
*
|
||||
* @param imageFile the image file associated with this character
|
||||
* @param ascent the ascent value (distance from the baseline to the top of the character)
|
||||
* @param height the height of the character
|
||||
* @param advance the advance (spacing) for this character
|
||||
* @return a new ConfiguredCharacter instance
|
||||
*/
|
||||
public static ConfiguredCharacter create(File imageFile, int ascent, int height, float advance) {
|
||||
return new ConfiguredCharacter(CharacterArranger.getAndIncrease(), imageFile, ascent, height, advance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ConfiguredCharacter instance with specified character, image, ascent, height, and advance values.
|
||||
*
|
||||
* @param character the character to associate
|
||||
* @param imageFile the image file
|
||||
* @param ascent the ascent value
|
||||
* @param height the height of the character
|
||||
* @param advance the advance (spacing) for the character
|
||||
*/
|
||||
public ConfiguredCharacter(char character, File imageFile, int ascent, int height, float advance) {
|
||||
this.character = character;
|
||||
this.imageFile = imageFile;
|
||||
this.ascent = ascent;
|
||||
this.height = height;
|
||||
this.advance = advance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ConfiguredCharacter instance with automatic advance calculation.
|
||||
*
|
||||
* @param character the character to associate
|
||||
* @param imageFile the image file
|
||||
* @param ascent the ascent value
|
||||
* @param height the height of the character
|
||||
*/
|
||||
public ConfiguredCharacter(char character, File imageFile, int ascent, int height) {
|
||||
this.character = character;
|
||||
this.imageFile = imageFile;
|
||||
this.ascent = ascent;
|
||||
this.height = height;
|
||||
|
||||
if (this.ascent > this.height) {
|
||||
CustomNameplates.getInstance().getPluginLogger().severe(String.format(
|
||||
"Found an issue in the image config. Ascent(%s) is higher than height(%s). %s", ascent, height, imageFile.getAbsolutePath()));
|
||||
}
|
||||
|
||||
try {
|
||||
BufferedImage bufferedImage = ImageIO.read(imageFile);
|
||||
int imageHeight = bufferedImage.getHeight();
|
||||
int imageWidth = bufferedImage.getWidth();
|
||||
|
||||
float scale = (float) height / imageHeight;
|
||||
int i;
|
||||
outer:
|
||||
for (i = imageWidth - 1; i >= 0; --i) {
|
||||
for (int k = 0; k < imageHeight; ++k) {
|
||||
int rgb = bufferedImage.getRGB(i, k);
|
||||
int alpha = (rgb >> 24) & 0xff;
|
||||
if (alpha != 0) {
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
advance = (float) Math.round((i + 1) * scale) + 1f;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character associated with this ConfiguredCharacter.
|
||||
*
|
||||
* @return the character
|
||||
*/
|
||||
public char character() {
|
||||
return character;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ascent value of this character.
|
||||
*
|
||||
* @return the ascent value
|
||||
*/
|
||||
public int ascent() {
|
||||
return ascent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the advance (spacing) of this character.
|
||||
*
|
||||
* @return the advance value
|
||||
*/
|
||||
public float advance() {
|
||||
return advance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height of this character.
|
||||
*
|
||||
* @return the character height
|
||||
*/
|
||||
public int height() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image file associated with this character.
|
||||
*
|
||||
* @return the image file
|
||||
*/
|
||||
public File imageFile() {
|
||||
return imageFile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.feature;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.placeholder.Placeholder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Represents dynamic text that can be rendered for a specific player, with support for placeholders and custom text functions.
|
||||
*/
|
||||
public class DynamicText {
|
||||
|
||||
private final String text;
|
||||
private final List<Function<CNPlayer, String>> texts;
|
||||
private final Set<Placeholder> placeholders;
|
||||
|
||||
/**
|
||||
* Constructs a new DynamicText instance.
|
||||
*
|
||||
* @param text the raw text string
|
||||
* @param texts a list of functions that generate text dynamically based on the player
|
||||
* @param placeholders a set of placeholders used in the text
|
||||
*/
|
||||
public DynamicText(String text, List<Function<CNPlayer, String>> texts, Set<Placeholder> placeholders) {
|
||||
this.text = text;
|
||||
this.texts = texts;
|
||||
this.placeholders = placeholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of placeholders associated with this dynamic text.
|
||||
*
|
||||
* @return a set of placeholders
|
||||
*/
|
||||
public Set<Placeholder> placeholders() {
|
||||
return placeholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the dynamic text for the specified player by applying the text functions.
|
||||
*
|
||||
* @param viewer the player for whom the text is being rendered
|
||||
* @return the rendered text
|
||||
*/
|
||||
public String render(CNPlayer viewer) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Function<CNPlayer, String> function : texts) {
|
||||
builder.append(function.apply(viewer));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw text string.
|
||||
*
|
||||
* @return the raw text
|
||||
*/
|
||||
public String text() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.feature;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.placeholder.Placeholder;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents a feature that can utilize placeholders and manage updates based on player interaction.
|
||||
*/
|
||||
public interface Feature {
|
||||
|
||||
/**
|
||||
* Returns the name of the feature.
|
||||
*
|
||||
* @return the feature name
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* Returns the set of placeholders that are currently active within this feature.
|
||||
*
|
||||
* @return a set of active placeholders
|
||||
*/
|
||||
Set<Placeholder> activePlaceholders();
|
||||
|
||||
/**
|
||||
* Returns the set of all placeholders that this feature can use.
|
||||
*
|
||||
* @return a set of all possible placeholders
|
||||
*/
|
||||
Set<Placeholder> allPlaceholders();
|
||||
|
||||
/**
|
||||
* Notifies the feature that placeholders for the specified player have been updated.
|
||||
*
|
||||
* @param p1 the player whose placeholders have been updated
|
||||
* @param force if true, forces an update even if no changes are detected
|
||||
*/
|
||||
void notifyPlaceholderUpdates(CNPlayer p1, boolean force);
|
||||
}
|
||||
+17
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
* 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
|
||||
@@ -15,20 +15,26 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
package net.momirealms.customnameplates.api.feature;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
|
||||
public interface ActionBarManager {
|
||||
/**
|
||||
* Listener for handling player join and quit events.
|
||||
*/
|
||||
public interface JoinQuitListener {
|
||||
|
||||
/**
|
||||
* Get the actionbar sent by other plugins in MiniMessage format
|
||||
* Return "" if no other actionbar received
|
||||
* Called when a player joins the server.
|
||||
*
|
||||
* @param player receiver
|
||||
* @return text
|
||||
* @param player the player who joined
|
||||
*/
|
||||
@NotNull
|
||||
String getOtherPluginActionBar(Player player);
|
||||
void onPlayerJoin(CNPlayer player);
|
||||
|
||||
/**
|
||||
* Called when a player quits the server.
|
||||
*
|
||||
* @param player the player who quit
|
||||
*/
|
||||
void onPlayerQuit(CNPlayer player);
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.feature;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public enum OffsetFont {
|
||||
|
||||
NEG_1('\uf800', -1, -3),
|
||||
NEG_2('\uf801', -2, -4),
|
||||
NEG_3('\uf802', -3, -5),
|
||||
NEG_4('\uf803', -4, -6),
|
||||
NEG_5('\uf804', -5, -7),
|
||||
NEG_6('\uf805', -6, -8),
|
||||
NEG_7('\uf806', -7, -9),
|
||||
NEG_8('\uf807', -8, -10),
|
||||
NEG_9('\uf808', -9, -11),
|
||||
NEG_10('\uf809', -10, -12),
|
||||
NEG_11('\uf80a', -11, -13),
|
||||
NEG_12('\uf80b', -12, -14),
|
||||
NEG_13('\uf80c', -13, -15),
|
||||
NEG_14('\uf80d', -14, -16),
|
||||
NEG_15('\uf80e', -15, -17),
|
||||
NEG_16('\uf80f', -16, -18),
|
||||
NEG_24('\uf810', -24, -26),
|
||||
NEG_32('\uf811', -32, -34),
|
||||
NEG_48('\uf812', -48, -50),
|
||||
NEG_64('\uf813', -64, -66),
|
||||
NEG_128('\uf814', -128, -130),
|
||||
NEG_256('\uf815', -256, -258),
|
||||
POS_1('\uf830', 1, -1),
|
||||
POS_2('\uf831', 2, 1),
|
||||
POS_3('\uf832', 3, 2),
|
||||
POS_4('\uf833', 4, 3),
|
||||
POS_5('\uf834', 5, 4),
|
||||
POS_6('\uf835', 6, 5),
|
||||
POS_7('\uf836', 7, 6),
|
||||
POS_8('\uf837', 8, 7),
|
||||
POS_9('\uf838', 9, 8),
|
||||
POS_10('\uf839', 10, 9),
|
||||
POS_11('\uf83a', 11, 10),
|
||||
POS_12('\uf83b', 12, 11),
|
||||
POS_13('\uf83c', 13, 12),
|
||||
POS_14('\uf83d', 14, 13),
|
||||
POS_15('\uf83e', 15, 14),
|
||||
POS_16('\uf83f', 16, 15),
|
||||
POS_24('\uf840', 24, 23),
|
||||
POS_32('\uf841', 32, 31),
|
||||
POS_48('\uf842', 48, 47),
|
||||
POS_64('\uf843', 64, 63),
|
||||
POS_128('\uf844', 128, 127),
|
||||
POS_256('\uf845', 256, 255);
|
||||
|
||||
private static final HashMap<Integer, OffsetFont> negFastLookup = new HashMap<>();
|
||||
private static final HashMap<Integer, OffsetFont> posFastLookup = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (OffsetFont f : OffsetFont.values()) {
|
||||
if (f.advance > 0) {
|
||||
posFastLookup.put(f.advance, f);
|
||||
} else {
|
||||
negFastLookup.put(-f.advance, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final char character;
|
||||
private final int advance;
|
||||
private final int height;
|
||||
|
||||
OffsetFont(char character, int advance, int height) {
|
||||
this.character = character;
|
||||
this.advance = advance;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public char character() {
|
||||
return this.character;
|
||||
}
|
||||
|
||||
public float advance() {
|
||||
return this.advance;
|
||||
}
|
||||
|
||||
public int height() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public static String createOffsets(float offset) {
|
||||
if (offset >= 0) {
|
||||
return shortestPosChars(offset);
|
||||
} else {
|
||||
return shortestNegChars(-offset);
|
||||
}
|
||||
}
|
||||
|
||||
public static String shortestNegChars(float advance) {
|
||||
int n = (int) Math.ceil(advance);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
while (n >= 256) {
|
||||
stringBuilder.append(OffsetFont.NEG_256.character());
|
||||
n -= 256;
|
||||
}
|
||||
if (n - 128 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_128.character());
|
||||
n -= 128;
|
||||
}
|
||||
if (n - 64 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_64.character());
|
||||
n -= 64;
|
||||
}
|
||||
if (n - 48 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_48.character());
|
||||
n -= 48;
|
||||
}
|
||||
if (n - 32 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_32.character());
|
||||
n -= 32;
|
||||
}
|
||||
if (n - 24 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_24.character());
|
||||
n -= 24;
|
||||
}
|
||||
if (n - 16 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_16.character());
|
||||
n -= 16;
|
||||
}
|
||||
if (n == 0) return stringBuilder.toString();
|
||||
stringBuilder.append(negFastLookup.get(n).character());
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public static String shortestPosChars(float advance) {
|
||||
int n = (int) Math.ceil(advance);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
while (n >= 256) {
|
||||
stringBuilder.append(OffsetFont.POS_256.character());
|
||||
n -= 256;
|
||||
}
|
||||
if (n - 128 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_128.character());
|
||||
n -= 128;
|
||||
}
|
||||
if (n - 64 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_64.character());
|
||||
n -= 64;
|
||||
}
|
||||
if (n - 48 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_48.character());
|
||||
n -= 48;
|
||||
}
|
||||
if (n - 32 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_32.character());
|
||||
n -= 32;
|
||||
}
|
||||
if (n - 24 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_24.character());
|
||||
n -= 24;
|
||||
}
|
||||
if (n - 16 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_16.character());
|
||||
n -= 16;
|
||||
}
|
||||
if (n == 0) return stringBuilder.toString();
|
||||
stringBuilder.append(posFastLookup.get(n).character());
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.feature;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
|
||||
/**
|
||||
* Listener for handling player actions
|
||||
*/
|
||||
public interface PlayerListener {
|
||||
|
||||
/**
|
||||
* Called when a player changes the world
|
||||
*
|
||||
* @param player the player who changes the world
|
||||
*/
|
||||
void onChangeWorld(CNPlayer player);
|
||||
|
||||
/**
|
||||
* Called when a player respawns
|
||||
*
|
||||
* @param player the player who respawns
|
||||
*/
|
||||
void onRespawn(CNPlayer player);
|
||||
|
||||
/**
|
||||
* Called when a player teleports
|
||||
*
|
||||
* @param player the player who respawns
|
||||
*/
|
||||
void onTeleport(CNPlayer player);
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.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.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PreParsedDynamicText {
|
||||
|
||||
private final String text;
|
||||
private final List<Function<CNPlayer, Function<CNPlayer, String>>> textFunctions = new ObjectArrayList<>();
|
||||
private final Set<Placeholder> set = new ObjectOpenHashSet<>();
|
||||
private boolean init = false;
|
||||
|
||||
public PreParsedDynamicText(String text) {
|
||||
this.text = Objects.requireNonNull(text);
|
||||
}
|
||||
|
||||
public PreParsedDynamicText(String text, boolean init) {
|
||||
this.text = Objects.requireNonNull(text);
|
||||
if (init) init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
if (init) return;
|
||||
init = true;
|
||||
PlaceholderManager manager = CustomNameplates.getInstance().getPlaceholderManager();
|
||||
List<String> detectedPlaceholders = manager.detectPlaceholders(text);
|
||||
List<Function<CNPlayer, Function<CNPlayer, String>>> convertor = new ArrayList<>(detectedPlaceholders.size());
|
||||
List<Placeholder> placeholders = new ArrayList<>(detectedPlaceholders.size());
|
||||
for (String id : detectedPlaceholders) {
|
||||
Placeholder placeholder = manager.getPlaceholder(id);
|
||||
placeholders.add(placeholder);
|
||||
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.getCachedPlayerValue(playerPlaceholder);
|
||||
} else {
|
||||
return playerPlaceholder.request(null);
|
||||
}
|
||||
});
|
||||
} else if (placeholder instanceof SharedPlaceholder sharedPlaceholder) {
|
||||
convertor.add((owner) -> (viewer) -> {
|
||||
if (owner != null) {
|
||||
return owner.getCachedSharedValue(sharedPlaceholder);
|
||||
} else {
|
||||
return sharedPlaceholder.request();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
convertor.add((owner) -> (viewer) -> id);
|
||||
}
|
||||
}
|
||||
int placeholderSize = placeholders.size();
|
||||
StringBuilder original0 = new StringBuilder(text);
|
||||
int lastIndex = 0;
|
||||
for (int i = 0; i < placeholderSize; i++) {
|
||||
String id = placeholders.get(i).id();
|
||||
int index = original0.indexOf(id, lastIndex);
|
||||
if (index == -1) {
|
||||
throw new RuntimeException("Placeholder ID not found in text");
|
||||
}
|
||||
if (index != lastIndex) {
|
||||
String textBefore = original0.substring(lastIndex, index);
|
||||
textFunctions.add((owner) -> (viewer) -> textBefore);
|
||||
}
|
||||
textFunctions.add(convertor.get(i));
|
||||
lastIndex = index + id.length();
|
||||
}
|
||||
if (lastIndex < original0.length()) {
|
||||
String remaining = original0.substring(lastIndex);
|
||||
textFunctions.add((owner) -> (viewer) -> remaining);
|
||||
}
|
||||
// To optimize the tree height
|
||||
set.addAll(new ObjectArrayList<>(placeholders));
|
||||
}
|
||||
|
||||
public DynamicText fastCreate(CNPlayer player) {
|
||||
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);
|
||||
}
|
||||
|
||||
public Set<Placeholder> placeholders() {
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) return true;
|
||||
if (object == null || getClass() != object.getClass()) return false;
|
||||
PreParsedDynamicText that = (PreParsedDynamicText) object;
|
||||
return text.equals(that.text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return text.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.feature;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
|
||||
/**
|
||||
* Represents a feature that involves relationships between two players and supports placeholder updates for both players.
|
||||
*/
|
||||
public interface RelationalFeature extends Feature {
|
||||
|
||||
/**
|
||||
* Notifies the feature that placeholders for the relationship between two players have been updated.
|
||||
*
|
||||
* @param p1 the first player
|
||||
* @param p2 the second player
|
||||
* @param force if true, forces an update even if no changes are detected
|
||||
*/
|
||||
void notifyPlaceholderUpdates(CNPlayer p1, CNPlayer p2, boolean force);
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.feature;
|
||||
|
||||
import net.momirealms.customnameplates.api.MainTask;
|
||||
|
||||
/**
|
||||
* Represents a data structure that stores an object and tracks when it was last updated,
|
||||
* using packed ticks and a boolean flag to indicate changes.
|
||||
*
|
||||
* @param <D> the type of data being stored
|
||||
*/
|
||||
public class TimeStampData<D> {
|
||||
|
||||
private D data;
|
||||
private int packedTicks;
|
||||
|
||||
/**
|
||||
* Constructs a new TickStampData instance.
|
||||
*
|
||||
* @param data the data to store
|
||||
* @param ticks the number of ticks to store
|
||||
* @param changed whether the value has changed
|
||||
*/
|
||||
public TimeStampData(D data, int ticks, boolean changed) {
|
||||
this.data = data;
|
||||
this.packedTicks = packBooleanAndTicks(changed, ticks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the stored data.
|
||||
*
|
||||
* @param data the new data
|
||||
*/
|
||||
public void data(D data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the packed ticks and change status.
|
||||
*
|
||||
* @param changed whether the value has changed
|
||||
*/
|
||||
public void updateTicks(boolean changed) {
|
||||
this.packedTicks = packBooleanAndTicks(changed, MainTask.getTicks());
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the flag
|
||||
*/
|
||||
public void resetChangedFlag() {
|
||||
this.packedTicks = packedTicks & 0x7FFFFFFF;;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stored data.
|
||||
*
|
||||
* @return the data
|
||||
*/
|
||||
public D data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value has changed since the last update.
|
||||
*
|
||||
* @return true if the value has changed, false otherwise
|
||||
*/
|
||||
public boolean hasValueChanged() {
|
||||
return unpackBoolean(packedTicks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stored number of ticks.
|
||||
*
|
||||
* @return the number of ticks
|
||||
*/
|
||||
public int ticks() {
|
||||
return unpackTicks(packedTicks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the boolean change flag and ticks into a single integer.
|
||||
*
|
||||
* @param hasValueChanged whether the value has changed
|
||||
* @param ticks the number of ticks
|
||||
* @return the packed integer
|
||||
*/
|
||||
public static int packBooleanAndTicks(boolean hasValueChanged, int ticks) {
|
||||
int numberMasked = ticks & 0x7FFFFFFF; // Mask for 31 bits
|
||||
int booleanBit = hasValueChanged ? 1 << 31 : 0; // Set the highest bit for the boolean flag
|
||||
return booleanBit | numberMasked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the number of ticks from the packed integer.
|
||||
*
|
||||
* @param packed the packed integer
|
||||
* @return the number of ticks
|
||||
*/
|
||||
public static int unpackTicks(int packed) {
|
||||
return packed & 0x7FFFFFFF; // Extract the lower 31 bits for ticks
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the boolean change flag from the packed integer.
|
||||
*
|
||||
* @param packed the packed integer
|
||||
* @return true if the value has changed, false otherwise
|
||||
*/
|
||||
public static boolean unpackBoolean(int packed) {
|
||||
return (packed & 0x80000000) != 0; // Check the highest bit for the boolean flag
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.feature.actionbar;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.CarouselText;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
|
||||
public interface ActionBarConfig {
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the ActionBar configuration.
|
||||
*
|
||||
* @return the configuration ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Returns the list of requirements for the ActionBar.
|
||||
*
|
||||
* @return an array of requirements
|
||||
*/
|
||||
Requirement[] requirements();
|
||||
|
||||
/**
|
||||
* Returns the carousel texts used in the ActionBar.
|
||||
*
|
||||
* @return an array of carousel texts
|
||||
*/
|
||||
CarouselText[] carouselTexts();
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing an ActionBarConfig.
|
||||
*
|
||||
* @return a new builder instance
|
||||
*/
|
||||
static Builder builder() {
|
||||
return new ActionBarConfigImpl.BuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for creating an ActionBarConfig.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Sets the unique ID for the ActionBar configuration.
|
||||
*
|
||||
* @param id the configuration ID
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets the requirements for the ActionBar.
|
||||
*
|
||||
* @param requirements an array of requirements
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder requirement(Requirement[] requirements);
|
||||
|
||||
/**
|
||||
* Sets the carousel texts for the ActionBar.
|
||||
*
|
||||
* @param carouselTexts an array of carousel texts
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder carouselText(CarouselText[] carouselTexts);
|
||||
|
||||
/**
|
||||
* Builds and returns the ActionBarConfig.
|
||||
*
|
||||
* @return the constructed ActionBarConfig
|
||||
*/
|
||||
ActionBarConfig build();
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.feature.actionbar;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.CarouselText;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
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) {
|
||||
this.id = requireNonNull(id);
|
||||
this.requirements = requireNonNull(requirements);
|
||||
this.carouselTexts = requireNonNull(carouselTexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Requirement[] requirements() {
|
||||
return requirements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CarouselText[] carouselTexts() {
|
||||
return carouselTexts;
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private Requirement[] requirements;
|
||||
private CarouselText[] carouselTexts;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder requirement(Requirement[] requirements) {
|
||||
this.requirements = requirements;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder carouselText(CarouselText[] carouselTexts) {
|
||||
this.carouselTexts = carouselTexts;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionBarConfig build() {
|
||||
return new ActionBarConfigImpl(id, requirements, carouselTexts);
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.feature.actionbar;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface ActionBarManager extends Reloadable {
|
||||
|
||||
/**
|
||||
* Refreshes the conditions of all ActionBars.
|
||||
*/
|
||||
void refreshConditions();
|
||||
|
||||
/**
|
||||
* Checks heartbeats for any necessary updates or actions related to ActionBars.
|
||||
*/
|
||||
void checkHeartBeats();
|
||||
|
||||
/**
|
||||
* Retrieves the ActionBar configuration by its name.
|
||||
*
|
||||
* @param name the name of the ActionBar configuration
|
||||
* @return the corresponding ActionBarConfig, or null if not found
|
||||
*/
|
||||
@Nullable
|
||||
ActionBarConfig configById(String name);
|
||||
|
||||
/**
|
||||
* Returns all available ActionBar configurations.
|
||||
*
|
||||
* @return an array of all ActionBarConfig instances
|
||||
*/
|
||||
ActionBarConfig[] actionBarConfigs();
|
||||
|
||||
/**
|
||||
* Gets the external ActionBar for a specific player.
|
||||
*
|
||||
* @param player the player
|
||||
* @return the external ActionBar string for the player
|
||||
*/
|
||||
@Nullable
|
||||
String getExternalActionBar(CNPlayer player);
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.feature.advance;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
import net.momirealms.customnameplates.common.util.Tuple;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AdvanceManager extends Reloadable {
|
||||
|
||||
/**
|
||||
* Retrieves custom font advance data by its ID.
|
||||
*
|
||||
* @param id the ID of the custom font
|
||||
* @return the custom font advance data
|
||||
*/
|
||||
@Nullable
|
||||
ConfigurableFontAdvanceData customFontDataById(String id);
|
||||
|
||||
/**
|
||||
* Retrieves character font advance data by its ID.
|
||||
*
|
||||
* @param id the ID of the character font
|
||||
* @return the character font advance data
|
||||
*/
|
||||
@Nullable
|
||||
CharacterFontAdvanceData templateFontDataById(String id);
|
||||
|
||||
/**
|
||||
* Calculates the total advance (width) for a line of text.
|
||||
*
|
||||
* @param text the text to calculate the advance for
|
||||
* @return the total line advance
|
||||
*/
|
||||
float getLineAdvance(String text);
|
||||
|
||||
/**
|
||||
* Calculates the advance (width) for a series of characters with a specific font and style.
|
||||
*
|
||||
* @param chars the array of characters
|
||||
* @param font the font key
|
||||
* @param bold whether the text is bold
|
||||
* @return the total character advance
|
||||
*/
|
||||
float getCharAdvance(char[] chars, Key font, boolean bold);
|
||||
|
||||
/**
|
||||
* Calculates the number of lines needed to fit the text within a specified width.
|
||||
*
|
||||
* @param text the text to calculate the number of lines for
|
||||
* @param width the maximum width of each line
|
||||
* @return the number of lines required
|
||||
*/
|
||||
int getLines(String text, int width);
|
||||
|
||||
/**
|
||||
* Converts a MiniMessage-formatted string into an iterable list of tuples.
|
||||
* Each tuple contains text, its corresponding font key, and whether it is bold.
|
||||
*
|
||||
* @param text the MiniMessage-formatted string
|
||||
* @return a list of tuples representing the iterable text parts
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
List<Tuple<String, Key, Boolean>> miniMessageToIterable(String text);
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.feature.advance;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface CharacterFontAdvanceData {
|
||||
|
||||
/**
|
||||
* Returns the size of the character font advance data, typically the number of characters.
|
||||
*
|
||||
* @return the size of the data
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Retrieves the advance (width) for a specific character code point.
|
||||
*
|
||||
* @param codePoint the code point of the character
|
||||
* @return the advance value for the character, or null if not found
|
||||
*/
|
||||
Float getAdvance(int codePoint);
|
||||
|
||||
/**
|
||||
* Returns the map containing the character code points and their corresponding advance values.
|
||||
*
|
||||
* @return a map of character code points and their advances
|
||||
*/
|
||||
Map<Integer, Float> data();
|
||||
|
||||
/**
|
||||
* Returns the unique identifier for this font advance data.
|
||||
*
|
||||
* @return the font advance data ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Generates a list of font provider configurations based on the provided properties.
|
||||
*
|
||||
* @param properties a map of properties for font provider configuration
|
||||
* @return a list of JSON objects representing the font providers
|
||||
*/
|
||||
List<JsonObject> fontProvider(Map<String, Object> properties);
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing CharacterFontAdvanceData.
|
||||
*
|
||||
* @return a new builder instance
|
||||
*/
|
||||
static Builder builder() {
|
||||
return new CharacterFontAdvanceDataImpl.BuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for creating CharacterFontAdvanceData.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Sets the advance data for the characters.
|
||||
*
|
||||
* @param data a map of character code points and their advance values
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder advance(Map<Integer, Float> data);
|
||||
|
||||
/**
|
||||
* Sets the unique ID for the font advance data.
|
||||
*
|
||||
* @param id the ID of the font advance data
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets a function to provide the font provider configuration.
|
||||
*
|
||||
* @param function a function that takes properties and returns a list of JSON objects representing font providers
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder fontProviderFunction(Function<Map<String, Object>, List<JsonObject>> function);
|
||||
|
||||
/**
|
||||
* Builds and returns the CharacterFontAdvanceData instance.
|
||||
*
|
||||
* @return the constructed CharacterFontAdvanceData
|
||||
*/
|
||||
CharacterFontAdvanceData build();
|
||||
}
|
||||
}
|
||||
+95
@@ -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.api.feature.advance;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class CharacterFontAdvanceDataImpl implements CharacterFontAdvanceData {
|
||||
|
||||
private final Map<Integer, Float> data;
|
||||
private final String id;
|
||||
private final Function<Map<String, Object>, List<JsonObject>> fontProviderFunction;
|
||||
|
||||
public 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float getAdvance(int codePoint) {
|
||||
return data.get(codePoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, Float> data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JsonObject> fontProvider(Map<String, Object> properties) {
|
||||
return fontProviderFunction.apply(properties);
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private final Int2FloatOpenHashMap data = new Int2FloatOpenHashMap();
|
||||
private String id;
|
||||
private Function<Map<String, Object>, List<JsonObject>> fontProviderFunction = (stringObjectMap -> null);
|
||||
|
||||
@Override
|
||||
public Builder advance(Map<Integer, Float> data) {
|
||||
this.data.putAll(data);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder fontProviderFunction(Function<Map<String, Object>, List<JsonObject>> function) {
|
||||
this.fontProviderFunction = function;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharacterFontAdvanceData build() {
|
||||
return new CharacterFontAdvanceDataImpl(id, data, fontProviderFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.feature.advance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents configurable font advance data, including default advance values and per-character advances.
|
||||
*/
|
||||
public interface ConfigurableFontAdvanceData {
|
||||
|
||||
/**
|
||||
* Returns the default advance (width) used when no specific value is defined for a character.
|
||||
*
|
||||
* @return the default advance width
|
||||
*/
|
||||
float defaultAdvance();
|
||||
|
||||
/**
|
||||
* Retrieves the advance (width) for a specific character code point.
|
||||
*
|
||||
* @param codePoint the code point of the character
|
||||
* @return the advance value for the character, or the default advance if not defined
|
||||
*/
|
||||
float getAdvance(int codePoint);
|
||||
|
||||
/**
|
||||
* Returns the unique identifier for this configurable font advance data.
|
||||
*
|
||||
* @return the font advance data ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing ConfigurableFontAdvanceData.
|
||||
*
|
||||
* @return a new builder instance
|
||||
*/
|
||||
static Builder builder() {
|
||||
return new ConfigurableFontAdvanceDataImpl.BuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for creating ConfigurableFontAdvanceData.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Sets the unique ID for the configurable font advance data.
|
||||
*
|
||||
* @param id the ID of the font advance data
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets the default advance (width) for characters that do not have specific advances.
|
||||
*
|
||||
* @param width the default advance width
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder defaultAdvance(float width);
|
||||
|
||||
/**
|
||||
* Sets the advance (width) for a specific character code point.
|
||||
*
|
||||
* @param codePoint the code point of the character
|
||||
* @param width the advance width for the character
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder advance(int codePoint, float width);
|
||||
|
||||
/**
|
||||
* Sets the parent fonts used by this configurable font advance data.
|
||||
*
|
||||
* @param font a list of parent fonts
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder parentFont(List<CharacterFontAdvanceData> font);
|
||||
|
||||
/**
|
||||
* Builds and returns the ConfigurableFontAdvanceData instance.
|
||||
*
|
||||
* @return the constructed ConfigurableFontAdvanceData
|
||||
*/
|
||||
ConfigurableFontAdvanceData build();
|
||||
}
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.feature.advance;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class ConfigurableFontAdvanceDataImpl implements ConfigurableFontAdvanceData {
|
||||
|
||||
private final float defaultAdvance;
|
||||
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) {
|
||||
this.id = requireNonNull(id);
|
||||
this.defaultAdvance = defaultAdvance;
|
||||
for (CharacterFontAdvanceData parent : parentFonts) {
|
||||
// To optimize memory, especially for those fonts that have over 100,000 characters
|
||||
if (parent.size() > 2048) {
|
||||
parents.add(parent);
|
||||
} else {
|
||||
data.putAll(parent.data());
|
||||
}
|
||||
}
|
||||
data.putAll(customData);
|
||||
Collections.reverse(parents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float defaultAdvance() {
|
||||
return defaultAdvance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAdvance(int codePoint) {
|
||||
Float width = data.get(codePoint);
|
||||
if (width == null) {
|
||||
for (CharacterFontAdvanceData parent : parents) {
|
||||
width = parent.getAdvance(codePoint);
|
||||
if (width != null) {
|
||||
return width;
|
||||
}
|
||||
}
|
||||
return defaultAdvance;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
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;
|
||||
private String id;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder defaultAdvance(float width) {
|
||||
this.defaultAdvance = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder advance(int codePoint, float width) {
|
||||
this.customData.put(codePoint, width);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder parentFont(List<CharacterFontAdvanceData> font) {
|
||||
this.parents.addAll(font);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurableFontAdvanceData build() {
|
||||
return new ConfigurableFontAdvanceDataImpl(id, defaultAdvance, customData, parents);
|
||||
}
|
||||
}
|
||||
}
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* 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.feature.background;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.AdaptiveImage;
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
|
||||
/**
|
||||
* Represents a background configuration
|
||||
*/
|
||||
public interface Background extends AdaptiveImage {
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the background configuration.
|
||||
*
|
||||
* @return the background ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Returns the configured character for the left side of the background.
|
||||
*
|
||||
* @return the left-side configured character
|
||||
*/
|
||||
ConfiguredCharacter left();
|
||||
|
||||
/**
|
||||
* Returns the configured character for width 1.
|
||||
*
|
||||
* @return the configured character for width 1
|
||||
*/
|
||||
ConfiguredCharacter width_1();
|
||||
|
||||
/**
|
||||
* Returns the configured character for width 2.
|
||||
*
|
||||
* @return the configured character for width 2
|
||||
*/
|
||||
ConfiguredCharacter width_2();
|
||||
|
||||
/**
|
||||
* Returns the configured character for width 4.
|
||||
*
|
||||
* @return the configured character for width 4
|
||||
*/
|
||||
ConfiguredCharacter width_4();
|
||||
|
||||
/**
|
||||
* Returns the configured character for width 8.
|
||||
*
|
||||
* @return the configured character for width 8
|
||||
*/
|
||||
ConfiguredCharacter width_8();
|
||||
|
||||
/**
|
||||
* Returns the configured character for width 16.
|
||||
*
|
||||
* @return the configured character for width 16
|
||||
*/
|
||||
ConfiguredCharacter width_16();
|
||||
|
||||
/**
|
||||
* Returns the configured character for width 32.
|
||||
*
|
||||
* @return the configured character for width 32
|
||||
*/
|
||||
ConfiguredCharacter width_32();
|
||||
|
||||
/**
|
||||
* Returns the configured character for width 64.
|
||||
*
|
||||
* @return the configured character for width 64
|
||||
*/
|
||||
ConfiguredCharacter width_64();
|
||||
|
||||
/**
|
||||
* Returns the configured character for width 128.
|
||||
*
|
||||
* @return the configured character for width 128
|
||||
*/
|
||||
ConfiguredCharacter width_128();
|
||||
|
||||
/**
|
||||
* Returns the configured character for the right side of the background.
|
||||
*
|
||||
* @return the right-side configured character
|
||||
*/
|
||||
ConfiguredCharacter right();
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing a Background configuration.
|
||||
*
|
||||
* @return a new builder instance
|
||||
*/
|
||||
static Builder builder() {
|
||||
return new BackgroundImpl.BuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for constructing Background configurations.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Sets the unique ID for the background.
|
||||
*
|
||||
* @param id the background ID
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets the configured character for the left side of the background.
|
||||
*
|
||||
* @param character the configured character for the left side
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder left(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Sets the configured character for width 1.
|
||||
*
|
||||
* @param character the configured character for width 1
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder width_1(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Sets the configured character for width 2.
|
||||
*
|
||||
* @param character the configured character for width 2
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder width_2(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Sets the configured character for width 4.
|
||||
*
|
||||
* @param character the configured character for width 4
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder width_4(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Sets the configured character for width 8.
|
||||
*
|
||||
* @param character the configured character for width 8
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder width_8(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Sets the configured character for width 16.
|
||||
*
|
||||
* @param character the configured character for width 16
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder width_16(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Sets the configured character for width 32.
|
||||
*
|
||||
* @param character the configured character for width 32
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder width_32(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Sets the configured character for width 64.
|
||||
*
|
||||
* @param character the configured character for width 64
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder width_64(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Sets the configured character for width 128.
|
||||
*
|
||||
* @param character the configured character for width 128
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder width_128(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Sets the configured character for the right side of the background.
|
||||
*
|
||||
* @param character the configured character for the right side
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder right(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Builds and returns the configured Background instance.
|
||||
*
|
||||
* @return the constructed Background
|
||||
*/
|
||||
Background build();
|
||||
}
|
||||
}
|
||||
+327
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.feature.background;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
import net.momirealms.customnameplates.api.feature.OffsetFont;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createImagePrefix(float advance, float leftMargin, float rightMargin) {
|
||||
if (advance <= 0) return "";
|
||||
String offset1 = OffsetFont.shortestNegChars(advance + rightMargin + right.advance());
|
||||
advance = leftMargin + advance + rightMargin;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append(left.character());
|
||||
while (advance >= 128) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_128.character());
|
||||
advance -= 128;
|
||||
}
|
||||
if (advance - 64 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_64.character());
|
||||
advance -= 64;
|
||||
}
|
||||
if (advance - 32 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_32.character());
|
||||
advance -= 32;
|
||||
}
|
||||
if (advance - 16 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_16.character());
|
||||
advance -= 16;
|
||||
}
|
||||
if (advance - 8 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_8.character());
|
||||
advance -= 8;
|
||||
}
|
||||
if (advance - 4 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_4.character());
|
||||
advance -= 4;
|
||||
}
|
||||
if (advance - 2 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_2.character());
|
||||
advance -= 2;
|
||||
}
|
||||
if (advance - 1 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_1.character());
|
||||
}
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(right.character());
|
||||
stringBuilder.append(offset1);
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createImageSuffix(float advance, float leftMargin, float rightMargin) {
|
||||
if (advance <= 0) return "";
|
||||
return OffsetFont.shortestPosChars(rightMargin + right.advance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createImage(float advance, float leftMargin, float rightMargin) {
|
||||
if (advance <= 0) return "";
|
||||
advance = advance + leftMargin + rightMargin + 2;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append(left.character());
|
||||
while (advance >= 128) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_128.character());
|
||||
advance -= 128;
|
||||
}
|
||||
if (advance - 64 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_64.character());
|
||||
advance -= 64;
|
||||
}
|
||||
if (advance - 32 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_32.character());
|
||||
advance -= 32;
|
||||
}
|
||||
if (advance - 16 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_16.character());
|
||||
advance -= 16;
|
||||
}
|
||||
if (advance - 8 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_8.character());
|
||||
advance -= 8;
|
||||
}
|
||||
if (advance - 4 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_4.character());
|
||||
advance -= 4;
|
||||
}
|
||||
if (advance - 2 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_2.character());
|
||||
advance -= 2;
|
||||
}
|
||||
if (advance - 1 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_1.character());
|
||||
}
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(right.character());
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) return true;
|
||||
if (object == null || getClass() != object.getClass()) return false;
|
||||
BackgroundImpl that = (BackgroundImpl) object;
|
||||
return Objects.equals(id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(id);
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private ConfiguredCharacter left;
|
||||
private ConfiguredCharacter width_1;
|
||||
private ConfiguredCharacter width_2;
|
||||
private ConfiguredCharacter width_4;
|
||||
private ConfiguredCharacter width_8;
|
||||
private ConfiguredCharacter width_16;
|
||||
private ConfiguredCharacter width_32;
|
||||
private ConfiguredCharacter width_64;
|
||||
private ConfiguredCharacter width_128;
|
||||
private ConfiguredCharacter right;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder left(ConfiguredCharacter character) {
|
||||
this.left = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder width_1(ConfiguredCharacter character) {
|
||||
this.width_1 = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder width_2(ConfiguredCharacter character) {
|
||||
this.width_2 = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder width_4(ConfiguredCharacter character) {
|
||||
this.width_4 = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder width_8(ConfiguredCharacter character) {
|
||||
this.width_8 = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder width_16(ConfiguredCharacter character) {
|
||||
this.width_16 = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder width_32(ConfiguredCharacter character) {
|
||||
this.width_32 = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder width_64(ConfiguredCharacter character) {
|
||||
this.width_64 = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder width_128(ConfiguredCharacter character) {
|
||||
this.width_128 = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder right(ConfiguredCharacter character) {
|
||||
this.right = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Background build() {
|
||||
return new BackgroundImpl(id, left, width_1, width_2, width_4, width_8, width_16, width_32, width_64, width_128, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
* 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
|
||||
@@ -15,32 +15,28 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
package net.momirealms.customnameplates.api.feature.background;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.tag.team.TeamTagPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface TeamTagManager {
|
||||
public interface BackgroundManager extends Reloadable {
|
||||
|
||||
/**
|
||||
* Create team tag for a player
|
||||
* If failed, the return value would be null
|
||||
* This happens when there already exists a team tag for a player
|
||||
* Retrieves a Background configuration by its unique ID.
|
||||
*
|
||||
* @return team tag
|
||||
* @param id the unique ID of the background
|
||||
* @return the corresponding Background, or null if not found
|
||||
*/
|
||||
@Nullable
|
||||
TeamTagPlayer createTagForPlayer(Player player, String prefix, String suffix);
|
||||
Background backgroundById(String id);
|
||||
|
||||
/**
|
||||
* Remove a team tag from map by uuid
|
||||
* Returns a collection of all available Background configurations.
|
||||
*
|
||||
* @param uuid uuid
|
||||
* @return team tag
|
||||
* @return a collection of Background instances
|
||||
*/
|
||||
@Nullable
|
||||
TeamTagPlayer removeTeamPlayerFromMap(UUID uuid);
|
||||
Collection<Background> getBackgrounds();
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.feature.bossbar;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface BossBar {
|
||||
|
||||
/**
|
||||
* Returns the unique UUID of the BossBar.
|
||||
*
|
||||
* @return the UUID of the BossBar
|
||||
*/
|
||||
UUID uuid();
|
||||
|
||||
/**
|
||||
* Returns the progress value of the BossBar.
|
||||
* The value should be between 0.0 (empty) and 1.0 (full).
|
||||
*
|
||||
* @return the progress value of the BossBar
|
||||
*/
|
||||
float progress();
|
||||
|
||||
/**
|
||||
* Returns the color of the BossBar.
|
||||
*
|
||||
* @return the color of the BossBar
|
||||
*/
|
||||
Color color();
|
||||
|
||||
/**
|
||||
* Returns the overlay style of the BossBar, defining how the bar is divided.
|
||||
*
|
||||
* @return the overlay style of the BossBar
|
||||
*/
|
||||
Overlay overlay();
|
||||
|
||||
enum Overlay {
|
||||
PROGRESS,
|
||||
NOTCHED_6,
|
||||
NOTCHED_10,
|
||||
NOTCHED_12,
|
||||
NOTCHED_20
|
||||
}
|
||||
|
||||
enum Color {
|
||||
BLUE,
|
||||
GREEN,
|
||||
PINK,
|
||||
PURPLE,
|
||||
RED,
|
||||
WHITE,
|
||||
YELLOW
|
||||
}
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.feature.bossbar;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.CarouselText;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
|
||||
public interface BossBarConfig {
|
||||
|
||||
/**
|
||||
* The default overlay style for the BossBar.
|
||||
*/
|
||||
BossBar.Overlay DEFAULT_OVERLAY = BossBar.Overlay.PROGRESS;
|
||||
|
||||
/**
|
||||
* The default color for the BossBar.
|
||||
*/
|
||||
BossBar.Color DEFAULT_COLOR = BossBar.Color.YELLOW;
|
||||
|
||||
/**
|
||||
* Returns the unique ID for the BossBar configuration.
|
||||
*
|
||||
* @return the configuration ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Returns the requirements for the BossBar.
|
||||
*
|
||||
* @return an array of requirements
|
||||
*/
|
||||
Requirement[] requirements();
|
||||
|
||||
/**
|
||||
* Returns the carousel texts used in the BossBar.
|
||||
*
|
||||
* @return an array of carousel texts
|
||||
*/
|
||||
CarouselText[] carouselTexts();
|
||||
|
||||
/**
|
||||
* Returns the overlay style for the BossBar.
|
||||
*
|
||||
* @return the overlay style
|
||||
*/
|
||||
BossBar.Overlay overlay();
|
||||
|
||||
/**
|
||||
* Returns the color of the BossBar.
|
||||
*
|
||||
* @return the BossBar color
|
||||
*/
|
||||
BossBar.Color color();
|
||||
|
||||
/**
|
||||
* Returns the progress value of the BossBar.
|
||||
* The value should be between 0.0 (empty) and 1.0 (full).
|
||||
*
|
||||
* @return the progress value
|
||||
*/
|
||||
float progress();
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing a BossBarConfig.
|
||||
*
|
||||
* @return a new builder instance
|
||||
*/
|
||||
static BossBarConfig.Builder builder() {
|
||||
return new BossBarConfigImpl.BuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for constructing BossBarConfig instances.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Sets the unique ID for the BossBar configuration.
|
||||
*
|
||||
* @param id the configuration ID
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets the requirements for the BossBar.
|
||||
*
|
||||
* @param requirements an array of requirements
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder requirement(Requirement[] requirements);
|
||||
|
||||
/**
|
||||
* Sets the carousel texts for the BossBar.
|
||||
*
|
||||
* @param carouselTexts an array of carousel texts
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder carouselText(CarouselText[] carouselTexts);
|
||||
|
||||
/**
|
||||
* Sets the overlay style for the BossBar.
|
||||
*
|
||||
* @param overlay the overlay style
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder overlay(BossBar.Overlay overlay);
|
||||
|
||||
/**
|
||||
* Sets the color for the BossBar.
|
||||
*
|
||||
* @param color the BossBar color
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder color(BossBar.Color color);
|
||||
|
||||
/**
|
||||
* Sets the progress value for the BossBar.
|
||||
*
|
||||
* @param progress the progress value
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder progress(float progress);
|
||||
|
||||
/**
|
||||
* Builds and returns the configured BossBarConfig instance.
|
||||
*
|
||||
* @return the constructed BossBarConfig
|
||||
*/
|
||||
BossBarConfig build();
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.feature.bossbar;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.CarouselText;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class BossBarConfigImpl implements BossBarConfig {
|
||||
|
||||
private final String id;
|
||||
private final Requirement[] requirements;
|
||||
private final CarouselText[] carouselTexts;
|
||||
private final BossBar.Overlay overlay;
|
||||
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) {
|
||||
this.id = requireNonNull(id);
|
||||
this.requirements = requireNonNull(requirements);
|
||||
this.carouselTexts = requireNonNull(carouselTexts);
|
||||
this.overlay = requireNonNull(overlay);
|
||||
this.color = requireNonNull(color);
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Requirement[] requirements() {
|
||||
return requirements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CarouselText[] carouselTexts() {
|
||||
return carouselTexts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar.Overlay overlay() {
|
||||
return overlay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar.Color color() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float progress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private Requirement[] requirements;
|
||||
private CarouselText[] carouselTexts;
|
||||
private BossBar.Overlay overlay = DEFAULT_OVERLAY;
|
||||
private BossBar.Color color = DEFAULT_COLOR;
|
||||
private float progress = 0f;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder requirement(Requirement[] requirements) {
|
||||
this.requirements = requirements;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder carouselText(CarouselText[] carouselTexts) {
|
||||
this.carouselTexts = carouselTexts;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder overlay(BossBar.Overlay overlay) {
|
||||
this.overlay = overlay;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder color(BossBar.Color color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder progress(float progress) {
|
||||
this.progress = progress;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBarConfig build() {
|
||||
return new BossBarConfigImpl(id, requirements, carouselTexts, overlay, color, progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.feature.bossbar;
|
||||
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
|
||||
public interface BossBarManager extends Reloadable {
|
||||
|
||||
/**
|
||||
* Retrieves the BossBar configuration by its id.
|
||||
*
|
||||
* @param id the name of the BossBar configuration
|
||||
* @return the corresponding BossBarConfig, or null if not found
|
||||
*/
|
||||
BossBarConfig configById(String id);
|
||||
|
||||
/**
|
||||
* Returns all available BossBar configurations.
|
||||
*
|
||||
* @return an array of all BossBarConfig instances
|
||||
*/
|
||||
BossBarConfig[] bossBarConfigs();
|
||||
|
||||
/**
|
||||
* Called on every server tick to update the state of BossBars.
|
||||
*/
|
||||
void onTick();
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.feature.bubble;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.AdaptiveImage;
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
|
||||
public interface Bubble extends AdaptiveImage {
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the Bubble configuration.
|
||||
*
|
||||
* @return the Bubble ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Returns the configured character for the left side of the Bubble.
|
||||
*
|
||||
* @return the left-side configured character
|
||||
*/
|
||||
ConfiguredCharacter left();
|
||||
|
||||
/**
|
||||
* Returns the configured character for the right side of the Bubble.
|
||||
*
|
||||
* @return the right-side configured character
|
||||
*/
|
||||
ConfiguredCharacter right();
|
||||
|
||||
/**
|
||||
* Returns the configured character for the middle section of the Bubble.
|
||||
*
|
||||
* @return the middle configured character
|
||||
*/
|
||||
ConfiguredCharacter middle();
|
||||
|
||||
/**
|
||||
* Returns the configured character for the tail section of the Bubble.
|
||||
*
|
||||
* @return the tail configured character
|
||||
*/
|
||||
ConfiguredCharacter tail();
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing a Bubble configuration.
|
||||
*
|
||||
* @return a new builder instance
|
||||
*/
|
||||
static Builder builder() {
|
||||
return new BubbleImpl.BuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for constructing Bubble configurations.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Sets the unique ID for the Bubble configuration.
|
||||
*
|
||||
* @param id the Bubble ID
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets the configured character for the left side of the Bubble.
|
||||
*
|
||||
* @param left the left-side configured character
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder left(ConfiguredCharacter left);
|
||||
|
||||
/**
|
||||
* Sets the configured character for the right side of the Bubble.
|
||||
*
|
||||
* @param right the right-side configured character
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder right(ConfiguredCharacter right);
|
||||
|
||||
/**
|
||||
* Sets the configured character for the middle section of the Bubble.
|
||||
*
|
||||
* @param middle the middle configured character
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder middle(ConfiguredCharacter middle);
|
||||
|
||||
/**
|
||||
* Sets the configured character for the tail section of the Bubble.
|
||||
*
|
||||
* @param tail the tail configured character
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder tail(ConfiguredCharacter tail);
|
||||
|
||||
/**
|
||||
* Builds and returns the constructed Bubble instance.
|
||||
*
|
||||
* @return the constructed Bubble
|
||||
*/
|
||||
Bubble build();
|
||||
}
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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.feature.bubble;
|
||||
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
|
||||
public interface BubbleConfig {
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the Bubble configuration.
|
||||
*
|
||||
* @return the configuration ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Returns the background color of the Bubble text.
|
||||
*
|
||||
* @return the background color (ARGB) as an integer
|
||||
*/
|
||||
int backgroundColor();
|
||||
|
||||
/**
|
||||
* Returns the line width for the Bubble text.
|
||||
*
|
||||
* @return the line width
|
||||
*/
|
||||
int lineWidth();
|
||||
|
||||
/**
|
||||
* Returns the maximum number of lines for the Bubble text.
|
||||
*
|
||||
* @return the maximum number of lines
|
||||
*/
|
||||
int maxLines();
|
||||
|
||||
/**
|
||||
* Returns the bubbles used in this configuration.
|
||||
*
|
||||
* @return an array of Bubble instances
|
||||
*/
|
||||
Bubble[] bubbles();
|
||||
|
||||
/**
|
||||
* Returns the text prefix to be applied before the Bubble content.
|
||||
*
|
||||
* @return the text prefix
|
||||
*/
|
||||
String textPrefix();
|
||||
|
||||
/**
|
||||
* Returns the text suffix to be applied after the Bubble content.
|
||||
*
|
||||
* @return the text suffix
|
||||
*/
|
||||
String textSuffix();
|
||||
|
||||
/**
|
||||
* Returns the display name of the Bubble.
|
||||
*
|
||||
* @return the display name
|
||||
*/
|
||||
String displayName();
|
||||
|
||||
/**
|
||||
* Returns the scale vector for the Bubble.
|
||||
*
|
||||
* @return the scale as a Vector3
|
||||
*/
|
||||
Vector3 scale();
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing a BubbleConfig.
|
||||
*
|
||||
* @return a new builder instance
|
||||
*/
|
||||
static Builder builder() {
|
||||
return new BubbleConfigImpl.BuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for constructing BubbleConfig instances.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Sets the unique ID for the BubbleConfig.
|
||||
*
|
||||
* @param id the configuration ID
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets the display name for the BubbleConfig.
|
||||
*
|
||||
* @param displayName the display name
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder displayName(String displayName);
|
||||
|
||||
/**
|
||||
* Sets the background color for the BubbleConfig.
|
||||
*
|
||||
* @param backgroundColor the background color
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder backgroundColor(int backgroundColor);
|
||||
|
||||
/**
|
||||
* Sets the line width for the Bubble text.
|
||||
*
|
||||
* @param lineWidth the line width
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder lineWidth(int lineWidth);
|
||||
|
||||
/**
|
||||
* Sets the maximum number of lines for the Bubble text.
|
||||
*
|
||||
* @param maxLines the maximum number of lines
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder maxLines(int maxLines);
|
||||
|
||||
/**
|
||||
* Sets the bubbles used in this configuration.
|
||||
*
|
||||
* @param bubbles an array of Bubble instances
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder bubbles(Bubble[] bubbles);
|
||||
|
||||
/**
|
||||
* Sets the text prefix for the BubbleConfig.
|
||||
*
|
||||
* @param textPrefix the text prefix
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder textPrefix(String textPrefix);
|
||||
|
||||
/**
|
||||
* Sets the text suffix for the BubbleConfig.
|
||||
*
|
||||
* @param textSuffix the text suffix
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder textSuffix(String textSuffix);
|
||||
|
||||
/**
|
||||
* Sets the scale for the BubbleConfig.
|
||||
*
|
||||
* @param scale the scale as a Vector3
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder scale(Vector3 scale);
|
||||
|
||||
/**
|
||||
* Builds and returns the configured BubbleConfig instance.
|
||||
*
|
||||
* @return the constructed BubbleConfig
|
||||
*/
|
||||
BubbleConfig build();
|
||||
}
|
||||
}
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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.feature.bubble;
|
||||
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class BubbleConfigImpl implements BubbleConfig {
|
||||
|
||||
private final String id;
|
||||
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 String displayName;
|
||||
private final Vector3 scale;
|
||||
|
||||
public BubbleConfigImpl(String id, String displayName, int backgroundColor, int lineWidth, int maxLines, Bubble[] bubbles, String textPrefix, String textSuffix, Vector3 scale) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.lineWidth = lineWidth;
|
||||
this.maxLines = maxLines;
|
||||
this.id = id;
|
||||
this.bubbles = requireNonNull(bubbles);
|
||||
this.textPrefix = requireNonNull(textPrefix);
|
||||
this.textSuffix = requireNonNull(textSuffix);
|
||||
this.displayName = requireNonNull(displayName);
|
||||
this.scale = requireNonNull(scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int backgroundColor() {
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lineWidth() {
|
||||
return lineWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxLines() {
|
||||
return maxLines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bubble[] bubbles() {
|
||||
return bubbles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String textPrefix() {
|
||||
return textPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String textSuffix() {
|
||||
return textSuffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3 scale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private int backgroundColor;
|
||||
private int lineWidth;
|
||||
private int maxLines;
|
||||
private Bubble[] bubbles;
|
||||
private String textPrefix;
|
||||
private String textSuffix;
|
||||
private String id;
|
||||
private String displayName;
|
||||
private Vector3 scale;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder displayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder backgroundColor(int backgroundColor) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder lineWidth(int lineWidth) {
|
||||
this.lineWidth = lineWidth;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder maxLines(int maxLines) {
|
||||
this.maxLines = maxLines;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder bubbles(Bubble[] bubbles) {
|
||||
this.bubbles = bubbles;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder textPrefix(String textPrefix) {
|
||||
this.textPrefix = textPrefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder textSuffix(String textSuffix) {
|
||||
this.textSuffix = textSuffix;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder scale(Vector3 scale) {
|
||||
this.scale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BubbleConfig build() {
|
||||
return new BubbleConfigImpl(id, displayName, backgroundColor, lineWidth, maxLines, bubbles, textPrefix, textSuffix, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* 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.feature.bubble;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
import net.momirealms.customnameplates.api.feature.OffsetFont;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
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;
|
||||
|
||||
public BubbleImpl(String id, ConfiguredCharacter left, ConfiguredCharacter right, ConfiguredCharacter middle, ConfiguredCharacter tail) {
|
||||
this.id = id;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.middle = middle;
|
||||
this.tail = tail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter left() {
|
||||
return left;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter right() {
|
||||
return right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter middle() {
|
||||
return middle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter tail() {
|
||||
return tail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) return true;
|
||||
if (object == null || getClass() != object.getClass()) return false;
|
||||
BubbleImpl bubble = (BubbleImpl) object;
|
||||
return Objects.equals(id, bubble.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(id);
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
@Override
|
||||
public String createImagePrefix(float advance, float leftMargin, float rightMargin) {
|
||||
if (advance <= 0) return "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(left.character());
|
||||
sb.append(OffsetFont.NEG_1.character());
|
||||
int mid_amount = (int) Math.ceil((advance + leftMargin + rightMargin - (tail.advance() - 1)) / (middle.advance() - 1));
|
||||
float actualMiddleWidth = 0;
|
||||
if (mid_amount > 512) return "";
|
||||
if (mid_amount <= 0) {
|
||||
sb.append(tail.character()).append(OffsetFont.NEG_1.character());
|
||||
actualMiddleWidth = tail.advance() - 1;
|
||||
} else {
|
||||
actualMiddleWidth += (middle.advance() - 1) * mid_amount;
|
||||
actualMiddleWidth += (tail.advance() - 1);
|
||||
int tailPos = mid_amount / 2;
|
||||
for (int i = 0; i < mid_amount; i++) {
|
||||
sb.append(middle.character()).append(OffsetFont.NEG_1.character());
|
||||
if (i == tailPos) {
|
||||
sb.append(tail.character()).append(OffsetFont.NEG_1.character());
|
||||
}
|
||||
}
|
||||
}
|
||||
float exceed = actualMiddleWidth - advance;
|
||||
sb.append(right.character());
|
||||
float delta = (right.advance() + rightMargin + advance + exceed / 2);
|
||||
if (delta != 0) {
|
||||
sb.append(OffsetFont.createOffsets(-delta));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createImageSuffix(float advance, float leftMargin, float rightMargin) {
|
||||
if (advance <= 0) return "";
|
||||
int mid_amount = (int) Math.ceil((advance + leftMargin + rightMargin - (tail.advance() - 1)) / (middle.advance() - 1));
|
||||
float actualMiddleWidth = 0;
|
||||
actualMiddleWidth += (tail.advance() - 1);
|
||||
actualMiddleWidth += (middle.advance() - 1) * mid_amount;
|
||||
float exceed = actualMiddleWidth - advance;
|
||||
float delta = (right.advance() + rightMargin + exceed / 2);
|
||||
return OffsetFont.shortestPosChars(delta);
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
@Override
|
||||
public String createImage(float advance, float leftMargin, float rightMargin) {
|
||||
if (advance <= 0) return "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(left.character());
|
||||
sb.append(OffsetFont.NEG_1.character());
|
||||
int mid_amount = (int) Math.ceil((advance + leftMargin + rightMargin - (tail.advance() - 1)) / (middle.advance() - 1));
|
||||
if (mid_amount > 512) return "";
|
||||
if (mid_amount <= 0) {
|
||||
sb.append(tail.character()).append(OffsetFont.NEG_1.character());
|
||||
} else {
|
||||
int tailPos = mid_amount / 2;
|
||||
for (int i = 0; i < mid_amount; i++) {
|
||||
sb.append(middle.character()).append(OffsetFont.NEG_1.character());
|
||||
if (i == tailPos) {
|
||||
sb.append(tail.character()).append(OffsetFont.NEG_1.character());
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append(right.character());
|
||||
float delta = (right.advance() + rightMargin - (left.advance() - 1) - leftMargin);
|
||||
if (delta != 0) {
|
||||
sb.append(OffsetFont.createOffsets(-delta));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private ConfiguredCharacter left;
|
||||
private ConfiguredCharacter right;
|
||||
private ConfiguredCharacter middle;
|
||||
private ConfiguredCharacter tail;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder left(ConfiguredCharacter left) {
|
||||
this.left = left;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder right(ConfiguredCharacter right) {
|
||||
this.right = right;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder middle(ConfiguredCharacter middle) {
|
||||
this.middle = middle;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder tail(ConfiguredCharacter tail) {
|
||||
this.tail = tail;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bubble build() {
|
||||
return new BubbleImpl(id, left, right, middle, tail);
|
||||
}
|
||||
}
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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.feature.bubble;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
public interface BubbleManager extends Reloadable {
|
||||
|
||||
/**
|
||||
* Returns a collection of all available Bubble instances.
|
||||
*
|
||||
* @return a collection of Bubble instances
|
||||
*/
|
||||
Collection<Bubble> bubbles();
|
||||
|
||||
/**
|
||||
* Returns a collection of all Bubble configurations.
|
||||
*
|
||||
* @return a collection of BubbleConfig instances
|
||||
*/
|
||||
Collection<BubbleConfig> bubbleConfigs();
|
||||
|
||||
/**
|
||||
* Retrieves a Bubble by its unique ID.
|
||||
*
|
||||
* @param id the Bubble ID
|
||||
* @return the Bubble instance, or null if not found
|
||||
*/
|
||||
@Nullable
|
||||
Bubble bubbleById(String id);
|
||||
|
||||
/**
|
||||
* Retrieves a Bubble configuration by its unique ID.
|
||||
*
|
||||
* @param id the BubbleConfig ID
|
||||
* @return the BubbleConfig instance, or null if not found
|
||||
*/
|
||||
@Nullable
|
||||
BubbleConfig bubbleConfigById(String id);
|
||||
|
||||
/**
|
||||
* Checks if a player has access to a specific Bubble by its ID.
|
||||
*
|
||||
* @param player the player to check
|
||||
* @param id the Bubble ID
|
||||
* @return true if the player has the Bubble, false otherwise
|
||||
*/
|
||||
boolean hasBubble(CNPlayer player, String id);
|
||||
|
||||
/**
|
||||
* Returns a collection of available Bubbles for the player.
|
||||
*
|
||||
* @param player the player to check
|
||||
* @return a collection of available BubbleConfig instances
|
||||
*/
|
||||
Collection<BubbleConfig> availableBubbles(CNPlayer player);
|
||||
|
||||
/**
|
||||
* Returns the set of channels that are blacklisted from displaying Bubbles.
|
||||
*
|
||||
* @return a set of blacklisted channel names
|
||||
*/
|
||||
Set<String> blacklistChannels();
|
||||
|
||||
/**
|
||||
* Returns the current mode for Bubble channels.
|
||||
*
|
||||
* @return the ChannelMode in use
|
||||
*/
|
||||
ChannelMode channelMode();
|
||||
|
||||
/**
|
||||
* Returns the default Bubble ID used when no specific Bubble is set.
|
||||
*
|
||||
* @return the default Bubble ID
|
||||
*/
|
||||
String defaultBubbleId();
|
||||
|
||||
/**
|
||||
* Returns the requirements to send a Bubble.
|
||||
*
|
||||
* @return an array of send Bubble requirements
|
||||
*/
|
||||
Requirement[] sendBubbleRequirements();
|
||||
|
||||
/**
|
||||
* Returns the requirements to view a Bubble.
|
||||
*
|
||||
* @return an array of view Bubble requirements
|
||||
*/
|
||||
Requirement[] viewBubbleRequirements();
|
||||
|
||||
/**
|
||||
* Returns the vertical offset for Bubble display.
|
||||
*
|
||||
* @return the vertical offset as a double
|
||||
*/
|
||||
double verticalOffset();
|
||||
|
||||
/**
|
||||
* Returns the duration (in ticks) for which the Bubble remains visible.
|
||||
*
|
||||
* @return the stay duration in ticks
|
||||
*/
|
||||
int stayDuration();
|
||||
|
||||
/**
|
||||
* Returns the duration (in ticks) for the Bubble to appear.
|
||||
*
|
||||
* @return the appear duration in ticks
|
||||
*/
|
||||
int appearDuration();
|
||||
|
||||
/**
|
||||
* Returns the duration (in ticks) for the Bubble to disappear.
|
||||
*
|
||||
* @return the disappear duration in ticks
|
||||
*/
|
||||
int disappearDuration();
|
||||
|
||||
/**
|
||||
* Returns the view range for Bubbles.
|
||||
*
|
||||
* @return the view range as a float
|
||||
*/
|
||||
float viewRange();
|
||||
}
|
||||
+5
-2
@@ -15,8 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
package net.momirealms.customnameplates.api.feature.bubble;
|
||||
|
||||
public interface BossBarManager {
|
||||
public enum ChannelMode {
|
||||
|
||||
ALL,
|
||||
JOINED,
|
||||
CAN_JOIN
|
||||
}
|
||||
+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.api.feature.chat;
|
||||
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
|
||||
/**
|
||||
* Abstract base class for chat message providers, providing common functionality
|
||||
* for managing the plugin and chat manager.
|
||||
*/
|
||||
public abstract class AbstractChatMessageProvider implements ChatMessageProvider {
|
||||
|
||||
protected CustomNameplates plugin;
|
||||
protected ChatManager manager;
|
||||
|
||||
/**
|
||||
* Constructs a new AbstractChatMessageProvider.
|
||||
*
|
||||
* @param plugin the CustomNameplates plugin instance
|
||||
* @param manager the ChatManager instance to handle chat-related operations
|
||||
*/
|
||||
public AbstractChatMessageProvider(CustomNameplates plugin, ChatManager manager) {
|
||||
this.plugin = plugin;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the chat message provider. Intended to be overridden by subclasses if needed.
|
||||
*/
|
||||
public void register() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the chat message provider. Intended to be overridden by subclasses if needed.
|
||||
*/
|
||||
public void unregister() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.feature.chat;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.feature.ChatListener;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
|
||||
/**
|
||||
* Manages chat-related functionality, including handling custom chat providers, listeners, and chat events.
|
||||
*/
|
||||
public interface ChatManager extends Reloadable {
|
||||
|
||||
/**
|
||||
* Sets a custom chat message provider.
|
||||
*
|
||||
* @param provider the custom ChatMessageProvider to set
|
||||
* @return true if the provider was successfully set, false otherwise
|
||||
*/
|
||||
boolean setCustomChatProvider(ChatMessageProvider provider);
|
||||
|
||||
/**
|
||||
* Removes the currently set custom chat message provider.
|
||||
*
|
||||
* @return true if the provider was successfully removed, false otherwise
|
||||
*/
|
||||
boolean removeCustomChatProvider();
|
||||
|
||||
/**
|
||||
* Registers a chat listener to receive chat events.
|
||||
*
|
||||
* @param listener the ChatListener to register
|
||||
*/
|
||||
void registerListener(ChatListener listener);
|
||||
|
||||
/**
|
||||
* Unregisters a chat listener, stopping it from receiving chat events.
|
||||
*
|
||||
* @param listener the ChatListener to unregister
|
||||
*/
|
||||
void unregisterListener(ChatListener listener);
|
||||
|
||||
/**
|
||||
* Returns the current chat message provider.
|
||||
*
|
||||
* @return the currently set ChatMessageProvider, or null if none is set
|
||||
*/
|
||||
ChatMessageProvider chatProvider();
|
||||
|
||||
/**
|
||||
* Handles a chat message event for the specified player and channel.
|
||||
*
|
||||
* @param player the player who sent the message
|
||||
* @param message the chat message content
|
||||
* @param channel the chat channel
|
||||
*/
|
||||
void onChat(CNPlayer player, String message, String channel);
|
||||
}
|
||||
+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.api.feature.chat;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
|
||||
/**
|
||||
* Provides chat-related functionality, including channel membership and ignore status between players.
|
||||
*/
|
||||
public interface ChatMessageProvider {
|
||||
|
||||
/**
|
||||
* Checks if a player has joined a specific chat channel.
|
||||
*
|
||||
* @param player the player to check
|
||||
* @param channelID the ID of the chat channel
|
||||
* @return true if the player has joined the channel, false otherwise
|
||||
*/
|
||||
boolean hasJoinedChannel(CNPlayer player, String channelID);
|
||||
|
||||
/**
|
||||
* Checks if a player is allowed to join a specific chat channel.
|
||||
*
|
||||
* @param player the player to check
|
||||
* @param channelID the ID of the chat channel
|
||||
* @return true if the player can join the channel, false otherwise
|
||||
*/
|
||||
boolean canJoinChannel(CNPlayer player, String channelID);
|
||||
|
||||
/**
|
||||
* Checks if a player is ignoring another player.
|
||||
*
|
||||
* @param sender the player sending messages
|
||||
* @param receiver the player who may be ignoring the sender
|
||||
* @return true if the receiver is ignoring the sender, false otherwise
|
||||
*/
|
||||
boolean isIgnoring(CNPlayer sender, CNPlayer receiver);
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.feature.chat.emoji;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
|
||||
/**
|
||||
* Interface for providing emoji replacement functionality.
|
||||
* Allows replacing certain text patterns with corresponding emojis for a given player.
|
||||
*/
|
||||
public interface EmojiProvider {
|
||||
|
||||
/**
|
||||
* Replaces specified text patterns in the given string with emojis, based on the player context.
|
||||
*
|
||||
* @param player the player for whom the emoji replacement is being processed
|
||||
* @param text the original text to process
|
||||
* @return the text with emojis replacing certain patterns
|
||||
*/
|
||||
String replace(CNPlayer player, String text);
|
||||
}
|
||||
+3
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
* 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
|
||||
@@ -15,10 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.nameplate;
|
||||
package net.momirealms.customnameplates.api.feature.image;
|
||||
|
||||
public enum TagMode {
|
||||
TEAM,
|
||||
UNLIMITED,
|
||||
DISABLE
|
||||
public record Animation(int speed, int frames) {
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.feature.image;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface Image {
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the image configuration.
|
||||
*
|
||||
* @return the image ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Checks if the image has a shadow effect.
|
||||
*
|
||||
* @return true if the image has a shadow, false otherwise
|
||||
*/
|
||||
boolean removeShadow();
|
||||
|
||||
/**
|
||||
* Get the animation of the image
|
||||
*
|
||||
* @return the animated image
|
||||
*/
|
||||
@Nullable
|
||||
Animation animation();
|
||||
|
||||
/**
|
||||
* Returns the configured character associated with this image.
|
||||
*
|
||||
* @return the configured character
|
||||
*/
|
||||
ConfiguredCharacter character();
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing an Image configuration.
|
||||
*
|
||||
* @return a new builder instance
|
||||
*/
|
||||
static Builder builder() {
|
||||
return new ImageImpl.BuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for constructing Image configurations.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Sets the unique ID for the image configuration.
|
||||
*
|
||||
* @param id the image ID
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets whether to remove the shadow of the image
|
||||
*
|
||||
* @param remove true if to remove the shadow
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder removeShadow(boolean remove);
|
||||
|
||||
/**
|
||||
* Sets the animation of the image
|
||||
*
|
||||
* @param animation animation
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder animation(@Nullable Animation animation);
|
||||
|
||||
/**
|
||||
* Sets the configured character associated with this image.
|
||||
*
|
||||
* @param character the configured character
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder character(ConfiguredCharacter character);
|
||||
|
||||
/**
|
||||
* Builds and returns the configured Image instance.
|
||||
*
|
||||
* @return the constructed Image
|
||||
*/
|
||||
Image build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.feature.image;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ImageImpl implements Image {
|
||||
|
||||
private final String id;
|
||||
private final boolean removeShadow;
|
||||
private final ConfiguredCharacter character;
|
||||
private final Animation animation;
|
||||
|
||||
public ImageImpl(String id, boolean removeShadow, Animation animation, ConfiguredCharacter character) {
|
||||
this.id = id;
|
||||
this.removeShadow = removeShadow;
|
||||
this.character = character;
|
||||
this.animation = animation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeShadow() {
|
||||
return removeShadow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Animation animation() {
|
||||
return animation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter character() {
|
||||
return character;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) return true;
|
||||
if (object == null || getClass() != object.getClass()) return false;
|
||||
ImageImpl image = (ImageImpl) object;
|
||||
return Objects.equals(id, image.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(id);
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private boolean removeShadow;
|
||||
private ConfiguredCharacter character;
|
||||
private Animation animation;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder removeShadow(boolean removeShadow) {
|
||||
this.removeShadow = removeShadow;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder animation(@Nullable Animation animation) {
|
||||
this.animation = animation;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder character(ConfiguredCharacter character) {
|
||||
this.character = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image build() {
|
||||
return new ImageImpl(id, removeShadow, animation, character);
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
* 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
|
||||
@@ -15,18 +15,28 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.velocity.team;
|
||||
package net.momirealms.customnameplates.api.feature.image;
|
||||
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.customnameplates.common.team.TeamColor;
|
||||
import net.momirealms.customnameplates.common.team.TeamTagVisibility;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface VelocityTeamManager {
|
||||
import java.util.Collection;
|
||||
|
||||
public interface ImageManager extends Reloadable {
|
||||
|
||||
/**
|
||||
* Retrieves an Image configuration by its unique ID.
|
||||
*
|
||||
* @param id the unique ID of the image
|
||||
* @return the Image instance, or null if not found
|
||||
*/
|
||||
@Nullable
|
||||
String getTeam(Player player, Player viewer);
|
||||
Image imageById(String id);
|
||||
|
||||
void sendTeamUpdatePacket(Player receiver, String team, TeamColor color, TeamTagVisibility visibility, Component prefix, Component suffix);
|
||||
/**
|
||||
* Returns a collection of all available Image configurations.
|
||||
*
|
||||
* @return a collection of Image instances
|
||||
*/
|
||||
Collection<Image> images();
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.feature.nameplate;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.AdaptiveImage;
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
|
||||
public interface Nameplate extends AdaptiveImage {
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the nameplate configuration.
|
||||
*
|
||||
* @return the nameplate ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Returns the display name of the nameplate.
|
||||
*
|
||||
* @return the display name of the nameplate
|
||||
*/
|
||||
String displayName();
|
||||
|
||||
/**
|
||||
* Returns the configured character for the left side of the nameplate.
|
||||
*
|
||||
* @return the left-side configured character
|
||||
*/
|
||||
ConfiguredCharacter left();
|
||||
|
||||
/**
|
||||
* Returns the configured character for the middle section of the nameplate.
|
||||
*
|
||||
* @return the middle configured character
|
||||
*/
|
||||
ConfiguredCharacter middle();
|
||||
|
||||
/**
|
||||
* Returns the configured character for the right side of the nameplate.
|
||||
*
|
||||
* @return the right-side configured character
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @return a new builder instance
|
||||
*/
|
||||
static Builder builder() {
|
||||
return new NameplateImpl.BuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for constructing Nameplate configurations.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Sets the unique ID for the nameplate.
|
||||
*
|
||||
* @param id the nameplate ID
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets the display name for the nameplate.
|
||||
*
|
||||
* @param displayName the display name
|
||||
* @return the builder instance
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param left the left-side configured character
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder left(ConfiguredCharacter left);
|
||||
|
||||
/**
|
||||
* Sets the configured character for the middle section of the nameplate.
|
||||
*
|
||||
* @param middle the middle configured character
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder middle(ConfiguredCharacter middle);
|
||||
|
||||
/**
|
||||
* Sets the configured character for the right side of the nameplate.
|
||||
*
|
||||
* @param right the right-side configured character
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder right(ConfiguredCharacter right);
|
||||
|
||||
/**
|
||||
* Builds and returns the configured Nameplate instance.
|
||||
*
|
||||
* @return the constructed Nameplate
|
||||
*/
|
||||
Nameplate build();
|
||||
}
|
||||
}
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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.feature.nameplate;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
import net.momirealms.customnameplates.api.feature.OffsetFont;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class NameplateImpl implements Nameplate {
|
||||
|
||||
private final String id;
|
||||
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, int minWidth, ConfiguredCharacter left, ConfiguredCharacter middle, ConfiguredCharacter right) {
|
||||
this.id = id;
|
||||
this.displayName = displayName;
|
||||
this.minWidth = minWidth;
|
||||
this.left = left;
|
||||
this.middle = middle;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter left() {
|
||||
return left;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter middle() {
|
||||
return middle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredCharacter right() {
|
||||
return right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int minWidth() {
|
||||
return minWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) return true;
|
||||
if (object == null || getClass() != object.getClass()) return false;
|
||||
NameplateImpl nameplate = (NameplateImpl) object;
|
||||
return Objects.equals(id, nameplate.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(id);
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
@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());
|
||||
int mid_amount = (int) Math.ceil((advance + leftMargin + rightMargin) / (middle.advance() - 1));
|
||||
float exceed = mid_amount * (middle.advance() - 1) - advance - leftMargin - rightMargin;
|
||||
for (int i = 0; i < mid_amount; i++) {
|
||||
sb.append(middle.character()).append(OffsetFont.NEG_1.character());
|
||||
}
|
||||
sb.append(right.character());
|
||||
float delta = (right.advance() + rightMargin + advance + (float) Math.floor(exceed / 2));
|
||||
if (delta != 0) {
|
||||
sb.append(OffsetFont.shortestNegChars(delta));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
@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());
|
||||
int mid_amount = (int) Math.ceil((advance + leftMargin + rightMargin) / (middle.advance() - 1));
|
||||
if (mid_amount > 512) return "";
|
||||
for (int i = 0; i < mid_amount; i++) {
|
||||
sb.append(middle.character()).append(OffsetFont.NEG_1.character());
|
||||
}
|
||||
sb.append(right.character());
|
||||
float delta = (right.advance() + rightMargin - (left.advance() - 1) - leftMargin);
|
||||
if (delta != 0) {
|
||||
sb.append(OffsetFont.createOffsets(-delta));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private String displayName;
|
||||
private ConfiguredCharacter left;
|
||||
private ConfiguredCharacter middle;
|
||||
private ConfiguredCharacter right;
|
||||
private int minWidth;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
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;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder middle(ConfiguredCharacter middle) {
|
||||
this.middle = middle;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder right(ConfiguredCharacter right) {
|
||||
this.right = right;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nameplate build() {
|
||||
return new NameplateImpl(id, displayName, minWidth, left, middle, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.feature.nameplate;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface NameplateManager extends Reloadable {
|
||||
|
||||
/**
|
||||
* Retrieves a Nameplate by its unique ID.
|
||||
*
|
||||
* @param id the unique ID of the nameplate
|
||||
* @return the Nameplate instance, or null if not found
|
||||
*/
|
||||
@Nullable
|
||||
Nameplate nameplateById(String id);
|
||||
|
||||
/**
|
||||
* Returns a collection of all available nameplates.
|
||||
*
|
||||
* @return a collection of Nameplate instances
|
||||
*/
|
||||
Collection<Nameplate> nameplates();
|
||||
|
||||
/**
|
||||
* Checks if a player has access to a specific nameplate by its ID.
|
||||
*
|
||||
* @param player the player to check
|
||||
* @param id the ID of the nameplate
|
||||
* @return true if the player has access, false otherwise
|
||||
*/
|
||||
boolean hasNameplate(CNPlayer player, String id);
|
||||
|
||||
/**
|
||||
* Returns a collection of nameplates available to the player.
|
||||
*
|
||||
* @param player the player to check
|
||||
* @return a collection of available Nameplate instances
|
||||
*/
|
||||
Collection<Nameplate> availableNameplates(CNPlayer player);
|
||||
|
||||
/**
|
||||
* Returns the ID of the default nameplate to be used when no specific nameplate is set.
|
||||
*
|
||||
* @return the default nameplate ID
|
||||
*/
|
||||
String defaultNameplateId();
|
||||
|
||||
/**
|
||||
* Returns the player's name tag to be displayed on the nameplate.
|
||||
*
|
||||
* @return the player's name tag
|
||||
*/
|
||||
String playerNameTag();
|
||||
}
|
||||
+7
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
* 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
|
||||
@@ -15,19 +15,14 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.scheduler;
|
||||
package net.momirealms.customnameplates.api.feature.pack;
|
||||
|
||||
public interface CancellableTask {
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
|
||||
public interface ResourcePackManager extends Reloadable {
|
||||
|
||||
/**
|
||||
* Cancel the task
|
||||
* Generates the resource pack.
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
* Get if the task is cancelled or not
|
||||
*
|
||||
* @return cancelled or not
|
||||
*/
|
||||
boolean isCancelled();
|
||||
void generate();
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* 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.feature.tag;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.network.Tracker;
|
||||
import net.momirealms.customnameplates.api.util.SelfIncreaseEntityID;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.Vector;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class AbstractTag implements Tag {
|
||||
|
||||
protected CNPlayer owner;
|
||||
protected TagRenderer renderer;
|
||||
protected final UUID uuid = UUID.randomUUID();
|
||||
protected final int entityID = SelfIncreaseEntityID.getAndIncrease();
|
||||
|
||||
protected boolean isShown = false;
|
||||
|
||||
protected final Vector<CNPlayer> viewers = new Vector<>();
|
||||
protected CNPlayer[] viewerArray = new CNPlayer[0];
|
||||
|
||||
public AbstractTag(CNPlayer owner, TagRenderer renderer) {
|
||||
this.owner = owner;
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
protected abstract List<Object> spawnPacket(CNPlayer viewer);
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canShow() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canShow(CNPlayer viewer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
if (isShown) return;
|
||||
this.isShown = true;
|
||||
for (CNPlayer viewer : viewerArray) {
|
||||
show(viewer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(CNPlayer viewer) {
|
||||
if (!renderer.isValid()) return;
|
||||
if (!isShown()) throw new IllegalStateException("This tag is currently hidden");
|
||||
viewers.add(viewer);
|
||||
resetViewerArray();
|
||||
owner.trackPassengers(viewer, entityID);
|
||||
CustomNameplates.getInstance().getPacketSender().sendPacket(viewer, spawnPacket(viewer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
if (!isShown()) return;
|
||||
for (CNPlayer viewer : viewerArray) {
|
||||
hide(viewer);
|
||||
}
|
||||
this.isShown = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide(CNPlayer viewer) {
|
||||
if (!isShown()) return;
|
||||
boolean removed = viewers.remove(viewer);
|
||||
if (!removed) return;
|
||||
resetViewerArray();
|
||||
owner.untrackPassengers(viewer, entityID);
|
||||
Object packet = CustomNameplates.getInstance().getPlatform().removeEntityPacket(entityID);
|
||||
CustomNameplates.getInstance().getPacketSender().sendPacket(viewer, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respawn(CNPlayer viewer) {
|
||||
ArrayList<Object> packets = new ArrayList<>();
|
||||
packets.add(CustomNameplates.getInstance().getPlatform().removeEntityPacket(entityID));
|
||||
packets.addAll(spawnPacket(viewer));
|
||||
CustomNameplates.getInstance().getPacketSender().sendPacket(viewer, packets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respawn() {
|
||||
for (CNPlayer viewer : viewerArray) {
|
||||
respawn(viewer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void darkTag(boolean dark) {
|
||||
for (CNPlayer viewer : viewerArray) {
|
||||
darkTag(viewer, dark);
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
onPlayerScaleUpdate(viewer, scale);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerScaleUpdate(CNPlayer viewer, double scale) {
|
||||
Consumer<List<Object>> modifier1 = CustomNameplates.getInstance().getPlatform().createScaleModifier(scale(viewer).multiply(scale));
|
||||
Consumer<List<Object>> modifier2 = CustomNameplates.getInstance().getPlatform().createTranslationModifier(translation(viewer).multiply(scale));
|
||||
Object packet = CustomNameplates.getInstance().getPlatform().updateTextDisplayPacket(entityID, List.of(modifier1, modifier2));
|
||||
CustomNameplates.getInstance().getPacketSender().sendPacket(viewer, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTranslation() {
|
||||
for (CNPlayer player : viewerArray) {
|
||||
updateTranslation(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTranslation(CNPlayer viewer) {
|
||||
Tracker tracker = owner.getTracker(viewer);
|
||||
if (tracker != null) {
|
||||
Consumer<List<Object>> modifier = CustomNameplates.getInstance().getPlatform().createTranslationModifier(translation(viewer).multiply(tracker.getScale()));
|
||||
Object packet = CustomNameplates.getInstance().getPlatform().updateTextDisplayPacket(entityID, List.of(modifier));
|
||||
CustomNameplates.getInstance().getPacketSender().sendPacket(viewer, packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AbstractTag that = (AbstractTag) o;
|
||||
return owner == that.owner && uuid == that.uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return uuid.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int entityID() {
|
||||
return entityID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID uuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
protected void resetViewerArray() {
|
||||
this.viewerArray = viewers.toArray(new CNPlayer[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShown() {
|
||||
return isShown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShown(CNPlayer another) {
|
||||
if (!isShown) return false;
|
||||
return viewers.contains(another);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte opacity() {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* 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.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.Vector3;
|
||||
|
||||
public interface NameTagConfig {
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the name tag configuration.
|
||||
*
|
||||
* @return the name tag configuration ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Returns the requirements for the name tag owner.
|
||||
*
|
||||
* @return an array of owner requirements
|
||||
*/
|
||||
Requirement[] ownerRequirements();
|
||||
|
||||
/**
|
||||
* Returns the requirements for the name tag viewer.
|
||||
*
|
||||
* @return an array of viewer requirements
|
||||
*/
|
||||
Requirement[] viewerRequirements();
|
||||
|
||||
/**
|
||||
* Returns the carousel texts displayed on the name tag.
|
||||
*
|
||||
* @return an array of carousel texts
|
||||
*/
|
||||
CarouselText[] carouselTexts();
|
||||
|
||||
/**
|
||||
* Returns the opacity level of the name tag.
|
||||
*
|
||||
* @return the opacity value as a byte
|
||||
*/
|
||||
byte opacity();
|
||||
|
||||
/**
|
||||
* Returns the background color of the name tag.
|
||||
*
|
||||
* @return the background color as an integer
|
||||
*/
|
||||
int backgroundColor();
|
||||
|
||||
/**
|
||||
* Checks if the name tag has a shadow effect.
|
||||
*
|
||||
* @return true if the name tag has a shadow, false otherwise
|
||||
*/
|
||||
boolean hasShadow();
|
||||
|
||||
/**
|
||||
* Checks if the name tag is see-through.
|
||||
*
|
||||
* @return true if the name tag is see-through, false otherwise
|
||||
*/
|
||||
boolean isSeeThrough();
|
||||
|
||||
/**
|
||||
* Checks if the default background color is used.
|
||||
*
|
||||
* @return true if the default background color is used, false otherwise
|
||||
*/
|
||||
boolean useDefaultBackgroundColor();
|
||||
|
||||
/**
|
||||
* Checks if the name tag is affected by the crouching state of the player.
|
||||
*
|
||||
* @return true if affected by crouching, false otherwise
|
||||
*/
|
||||
boolean affectedByCrouching();
|
||||
|
||||
/**
|
||||
* Checks if the name tag is affected by scaling.
|
||||
*
|
||||
* @return true if affected by scaling, false otherwise
|
||||
*/
|
||||
boolean affectedByScaling();
|
||||
|
||||
/**
|
||||
* Checks if the name tag is affected by spectator mode.
|
||||
*
|
||||
* @return true if affected by spectator mode, false otherwise
|
||||
*/
|
||||
boolean affectedBySpectator();
|
||||
|
||||
/**
|
||||
* Returns the alignment of the name tag.
|
||||
*
|
||||
* @return the alignment of the name tag
|
||||
*/
|
||||
Alignment alignment();
|
||||
|
||||
/**
|
||||
* Returns the view range of the name tag.
|
||||
*
|
||||
* @return the view range as a float
|
||||
*/
|
||||
float viewRange();
|
||||
|
||||
/**
|
||||
* Returns the shadow radius of the name tag.
|
||||
*
|
||||
* @return the shadow radius as a float
|
||||
*/
|
||||
float shadowRadius();
|
||||
|
||||
/**
|
||||
* Returns the shadow strength of the name tag.
|
||||
*
|
||||
* @return the shadow strength as a float
|
||||
*/
|
||||
float shadowStrength();
|
||||
|
||||
/**
|
||||
* Returns the scaling vector of the name tag.
|
||||
*
|
||||
* @return the scaling vector as a Vector3
|
||||
*/
|
||||
Vector3 scale();
|
||||
|
||||
/**
|
||||
* Returns the translation vector for the name tag.
|
||||
*
|
||||
* @return the translation vector as a Vector3
|
||||
*/
|
||||
Vector3 translation();
|
||||
|
||||
/**
|
||||
* Returns the maximum line width of the name tag.
|
||||
*
|
||||
* @return the line width as an integer
|
||||
*/
|
||||
int lineWidth();
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing a NameTagConfig.
|
||||
*
|
||||
* @return a new builder instance
|
||||
*/
|
||||
static Builder builder() {
|
||||
return new NameTagConfigImpl.BuilderImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for constructing NameTagConfig instances with customizable properties.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Sets the unique ID for the NameTagConfig.
|
||||
*
|
||||
* @param id the name tag configuration ID
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets the maximum line width for the name tag.
|
||||
*
|
||||
* @param lineWidth the maximum line width
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder lineWidth(int lineWidth);
|
||||
|
||||
/**
|
||||
* Sets the requirements for the name tag owner.
|
||||
*
|
||||
* @param requirements an array of owner requirements
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder ownerRequirement(Requirement[] requirements);
|
||||
|
||||
/**
|
||||
* Sets the requirements for the name tag viewer.
|
||||
*
|
||||
* @param requirements an array of viewer requirements
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder viewerRequirement(Requirement[] requirements);
|
||||
|
||||
/**
|
||||
* Sets the carousel texts for the name tag.
|
||||
*
|
||||
* @param carouselTexts an array of carousel texts
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder carouselText(CarouselText[] carouselTexts);
|
||||
|
||||
/**
|
||||
* Sets the opacity level for the name tag.
|
||||
*
|
||||
* @param opacity the opacity value as a byte
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder opacity(byte opacity);
|
||||
|
||||
/**
|
||||
* Sets the background color for the name tag.
|
||||
*
|
||||
* @param backgroundColor the background color as an integer
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder backgroundColor(int backgroundColor);
|
||||
|
||||
/**
|
||||
* Sets whether the name tag has a shadow effect.
|
||||
*
|
||||
* @param hasShadow true if the name tag should have a shadow, false otherwise
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder hasShadow(boolean hasShadow);
|
||||
|
||||
/**
|
||||
* Sets whether the name tag is see-through.
|
||||
*
|
||||
* @param seeThrough true if the name tag is see-through, false otherwise
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder seeThrough(boolean seeThrough);
|
||||
|
||||
/**
|
||||
* Sets whether the name tag uses the default background color.
|
||||
*
|
||||
* @param useDefaultBackgroundColor true to use the default background color, false otherwise
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder useDefaultBackgroundColor(boolean useDefaultBackgroundColor);
|
||||
|
||||
/**
|
||||
* Sets the alignment of the name tag.
|
||||
*
|
||||
* @param alignment the alignment setting
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder alignment(Alignment alignment);
|
||||
|
||||
/**
|
||||
* Sets the view range for the name tag.
|
||||
*
|
||||
* @param viewRange the view range as a float
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder viewRange(float viewRange);
|
||||
|
||||
/**
|
||||
* Sets the shadow radius for the name tag.
|
||||
*
|
||||
* @param shadowRadius the shadow radius as a float
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder shadowRadius(float shadowRadius);
|
||||
|
||||
/**
|
||||
* Sets the shadow strength for the name tag.
|
||||
*
|
||||
* @param shadowStrength the shadow strength as a float
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder shadowStrength(float shadowStrength);
|
||||
|
||||
/**
|
||||
* Sets the scaling factor for the name tag.
|
||||
*
|
||||
* @param scale the scaling vector
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder scale(Vector3 scale);
|
||||
|
||||
/**
|
||||
* Sets the translation vector for the name tag.
|
||||
*
|
||||
* @param translation the translation vector
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder translation(Vector3 translation);
|
||||
|
||||
/**
|
||||
* Sets whether the name tag is affected by crouching.
|
||||
*
|
||||
* @param affectedByCrouching true if the name tag is affected by crouching, false otherwise
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder affectedByCrouching(boolean affectedByCrouching);
|
||||
|
||||
/**
|
||||
* Sets whether the name tag is affected by spectator mode.
|
||||
*
|
||||
* @param affectedBySpectator true if the name tag is affected by spectator mode, false otherwise
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder affectedBySpectator(boolean affectedBySpectator);
|
||||
|
||||
/**
|
||||
* Sets whether the name tag is affected by scaling.
|
||||
*
|
||||
* @param affectedByScale true if the name tag is affected by scaling, false otherwise
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder affectedByScaling(boolean affectedByScale);
|
||||
|
||||
/**
|
||||
* Builds and returns the configured NameTagConfig instance.
|
||||
*
|
||||
* @return the constructed NameTagConfig
|
||||
*/
|
||||
NameTagConfig build();
|
||||
}
|
||||
}
|
||||
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* 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.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.Vector3;
|
||||
|
||||
public class NameTagConfigImpl implements NameTagConfig {
|
||||
|
||||
private final String id;
|
||||
private final Requirement[] ownerRequirements;
|
||||
private final Requirement[] viewerRequirements;
|
||||
private final CarouselText[] carouselTexts;
|
||||
private final int lineWidth;
|
||||
private final byte opacity;
|
||||
private final int backgroundColor;
|
||||
private final boolean hasShadow;
|
||||
private final boolean isSeeThrough;
|
||||
private final boolean useDefaultBackgroundColor;
|
||||
private final Alignment alignment;
|
||||
private final float viewRange;
|
||||
private final float shadowRadius;
|
||||
private final float shadowStrength;
|
||||
private final Vector3 scale;
|
||||
private final Vector3 translation;
|
||||
private final boolean affectedByCrouching;
|
||||
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) {
|
||||
this.id = id;
|
||||
this.ownerRequirements = ownerRequirements;
|
||||
this.viewerRequirements = viewerRequirements;
|
||||
this.carouselTexts = carouselTexts;
|
||||
this.opacity = opacity;
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.hasShadow = hasShadow;
|
||||
this.isSeeThrough = isSeeThrough;
|
||||
this.useDefaultBackgroundColor = useDefaultBackgroundColor;
|
||||
this.alignment = alignment;
|
||||
this.viewRange = viewRange;
|
||||
this.shadowRadius = shadowRadius;
|
||||
this.shadowStrength = shadowStrength;
|
||||
this.scale = scale;
|
||||
this.translation = translation;
|
||||
this.lineWidth = lineWidth;
|
||||
this.affectedByCrouching = affectedByCrouching;
|
||||
this.affectedByScale = affectedByScale;
|
||||
this.affectedBySpectator = affectedBySpectator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Requirement[] ownerRequirements() {
|
||||
return ownerRequirements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Requirement[] viewerRequirements() {
|
||||
return viewerRequirements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CarouselText[] carouselTexts() {
|
||||
return carouselTexts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte opacity() {
|
||||
return opacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int backgroundColor() {
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasShadow() {
|
||||
return hasShadow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSeeThrough() {
|
||||
return isSeeThrough;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useDefaultBackgroundColor() {
|
||||
return useDefaultBackgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean affectedByCrouching() {
|
||||
return affectedByCrouching;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean affectedByScaling() {
|
||||
return affectedByScale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean affectedBySpectator() {
|
||||
return affectedBySpectator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Alignment alignment() {
|
||||
return alignment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float viewRange() {
|
||||
return viewRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float shadowRadius() {
|
||||
return shadowRadius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float shadowStrength() {
|
||||
return shadowStrength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3 scale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3 translation() {
|
||||
return translation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lineWidth() {
|
||||
return lineWidth;
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
private String id;
|
||||
private Requirement[] ownerRequirements;
|
||||
private Requirement[] viewerRequirements;
|
||||
private CarouselText[] carouselTexts;
|
||||
private int lineWidth;
|
||||
private byte opacity;
|
||||
private int backgroundColor;
|
||||
private boolean hasShadow;
|
||||
private boolean isSeeThrough;
|
||||
private boolean useDefaultBackgroundColor;
|
||||
private Alignment alignment;
|
||||
private float viewRange;
|
||||
private float shadowRadius;
|
||||
private float shadowStrength;
|
||||
private Vector3 scale;
|
||||
private Vector3 translation;
|
||||
private boolean affectedByCrouching;
|
||||
private boolean affectedByScale;
|
||||
private boolean affectedBySpectator;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder lineWidth(int lineWidth) {
|
||||
this.lineWidth = lineWidth;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder ownerRequirement(Requirement[] requirements) {
|
||||
this.ownerRequirements = requirements;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder viewerRequirement(Requirement[] requirements) {
|
||||
this.viewerRequirements = requirements;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder carouselText(CarouselText[] carouselTexts) {
|
||||
this.carouselTexts = carouselTexts;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder opacity(byte opacity) {
|
||||
this.opacity = opacity;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder backgroundColor(int backgroundColor) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder hasShadow(boolean hasShadow) {
|
||||
this.hasShadow = hasShadow;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder seeThrough(boolean seeThrough) {
|
||||
this.isSeeThrough = seeThrough;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder useDefaultBackgroundColor(boolean useDefaultBackgroundColor) {
|
||||
this.useDefaultBackgroundColor = useDefaultBackgroundColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder alignment(Alignment alignment) {
|
||||
this.alignment = alignment;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder viewRange(float viewRange) {
|
||||
this.viewRange = viewRange;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder shadowRadius(float shadowRadius) {
|
||||
this.shadowRadius = shadowRadius;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder shadowStrength(float shadowStrength) {
|
||||
this.shadowStrength = shadowStrength;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder scale(Vector3 scale) {
|
||||
this.scale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder translation(Vector3 translation) {
|
||||
this.translation = translation;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder affectedByCrouching(boolean affectedByCrouching) {
|
||||
this.affectedByCrouching = affectedByCrouching;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder affectedBySpectator(boolean affectedBySpectator) {
|
||||
this.affectedBySpectator = affectedBySpectator;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder affectedByScaling(boolean affectedByScale) {
|
||||
this.affectedByScale = affectedByScale;
|
||||
return this;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* 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.feature.tag;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Tag {
|
||||
|
||||
/**
|
||||
* Returns the ID of the tag.
|
||||
*
|
||||
* @return the tag ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Returns the entity ID associated with the tag.
|
||||
*
|
||||
* @return the entity ID
|
||||
*/
|
||||
int entityID();
|
||||
|
||||
/**
|
||||
* Returns the UUID of the tag.
|
||||
*
|
||||
* @return the tag UUID
|
||||
*/
|
||||
UUID uuid();
|
||||
|
||||
/**
|
||||
* Checks if the tag is affected by crouching.
|
||||
*
|
||||
* @return true if affected by crouching, false otherwise
|
||||
*/
|
||||
boolean affectedByCrouching();
|
||||
|
||||
/**
|
||||
* Checks if the tag is affected by scaling.
|
||||
*
|
||||
* @return true if affected by scaling, false otherwise
|
||||
*/
|
||||
boolean affectedByScaling();
|
||||
|
||||
boolean affectedBySpectator();
|
||||
|
||||
/**
|
||||
* Hides the tag for all viewers.
|
||||
*/
|
||||
void hide();
|
||||
|
||||
/**
|
||||
* Hides the tag for a specific viewer.
|
||||
*
|
||||
* @param viewer the player for whom the tag will be hidden
|
||||
*/
|
||||
void hide(CNPlayer viewer);
|
||||
|
||||
/**
|
||||
* Shows the tag to all viewers.
|
||||
*/
|
||||
void show();
|
||||
|
||||
/**
|
||||
* Shows the tag to a specific viewer.
|
||||
*
|
||||
* @param viewer the player for whom the tag will be shown
|
||||
*/
|
||||
void show(CNPlayer viewer);
|
||||
|
||||
/**
|
||||
* Respawns the tag for all viewers.
|
||||
*/
|
||||
void respawn();
|
||||
|
||||
/**
|
||||
* Respawns the tag for a specific viewer.
|
||||
*
|
||||
* @param viewer the player for whom the tag will be respawned
|
||||
*/
|
||||
void respawn(CNPlayer viewer);
|
||||
|
||||
/**
|
||||
* Returns the opacity of the tag.
|
||||
*
|
||||
* @return the opacity value as a byte
|
||||
*/
|
||||
byte opacity();
|
||||
|
||||
/**
|
||||
* Checks if the tag can be shown to all viewers.
|
||||
*
|
||||
* @return true if the tag can be shown, false otherwise
|
||||
*/
|
||||
boolean canShow();
|
||||
|
||||
/**
|
||||
* Checks if the tag can be shown to a specific viewer.
|
||||
*
|
||||
* @param viewer the player to check
|
||||
* @return true if the tag can be shown, false otherwise
|
||||
*/
|
||||
boolean canShow(CNPlayer viewer);
|
||||
|
||||
/**
|
||||
* Checks if the tag is currently shown to all viewers.
|
||||
*
|
||||
* @return true if the tag is shown, false otherwise
|
||||
*/
|
||||
boolean isShown();
|
||||
|
||||
/**
|
||||
* Checks if the tag is currently shown to a specific viewer.
|
||||
*
|
||||
* @param viewer the player to check
|
||||
* @return true if the tag is shown, false otherwise
|
||||
*/
|
||||
boolean isShown(CNPlayer viewer);
|
||||
|
||||
/**
|
||||
* Called every tick to update the tag's state.
|
||||
*/
|
||||
void tick();
|
||||
|
||||
/**
|
||||
* Initializes the tag.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Returns the text height of the tag for a specific viewer.
|
||||
*
|
||||
* @param viewer the player to check
|
||||
* @return the text height
|
||||
*/
|
||||
double getTextHeight(CNPlayer viewer);
|
||||
|
||||
/**
|
||||
* Sets the dark mode for the tag.
|
||||
*
|
||||
* @param dark whether the tag should be dark
|
||||
*/
|
||||
void darkTag(boolean dark);
|
||||
|
||||
/**
|
||||
* Sets the dark mode for the tag for a specific viewer.
|
||||
*
|
||||
* @param viewer the player for whom the dark mode should be applied
|
||||
* @param dark whether the tag should be dark for the specific viewer
|
||||
*/
|
||||
void darkTag(CNPlayer viewer, boolean dark);
|
||||
|
||||
/**
|
||||
* Updates the tag scale when the player's scale changes.
|
||||
*
|
||||
* @param scale the new scale value
|
||||
*/
|
||||
void onPlayerScaleUpdate(double scale);
|
||||
|
||||
/**
|
||||
* Updates the tag scale when the player's scale changes for a specific viewer.
|
||||
*
|
||||
* @param viewer the player to update
|
||||
* @param scale the new scale value
|
||||
*/
|
||||
void onPlayerScaleUpdate(CNPlayer viewer, double scale);
|
||||
|
||||
/**
|
||||
* Updates the translation of the tag.
|
||||
*/
|
||||
void updateTranslation();
|
||||
|
||||
/**
|
||||
* Updates the translation of the tag for a certain player
|
||||
*/
|
||||
void updateTranslation(CNPlayer viewer);
|
||||
|
||||
/**
|
||||
* Returns the scaling vector of the tag for a specific viewer.
|
||||
*
|
||||
* @param viewer the player to check
|
||||
* @return the scaling vector
|
||||
*/
|
||||
Vector3 scale(CNPlayer viewer);
|
||||
|
||||
/**
|
||||
* Returns the translation vector of the tag for a specific viewer.
|
||||
*
|
||||
* @param viewer the player to check
|
||||
* @return the translation vector
|
||||
*/
|
||||
Vector3 translation(CNPlayer viewer);
|
||||
|
||||
/**
|
||||
* Returns if the tag has a relative translation
|
||||
*
|
||||
* @return has or not
|
||||
*/
|
||||
boolean relativeTranslation();
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.feature.tag;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public interface TagRenderer {
|
||||
|
||||
/**
|
||||
* Returns the offset applied to the tag for positioning a "hat" or similar element above the entity's head.
|
||||
*
|
||||
* @return the hat offset value
|
||||
*/
|
||||
double hatOffset();
|
||||
|
||||
/**
|
||||
* Sets the offset applied to the tag for positioning a "hat" or similar element above the entity's head.
|
||||
*
|
||||
* @param hatOffset the new hat offset value
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
void onTick();
|
||||
|
||||
/**
|
||||
* Destroys the renderer, cleaning up any resources or tags it manages.
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
/**
|
||||
* Adds a new tag to be rendered.
|
||||
*
|
||||
* @param tag the tag to add
|
||||
*/
|
||||
void addTag(Tag tag);
|
||||
|
||||
/**
|
||||
* Returns the array of tags currently managed by this renderer.
|
||||
*
|
||||
* @return an array of Tag instances
|
||||
*/
|
||||
Tag[] tags();
|
||||
|
||||
/**
|
||||
* Removes tags that match the given predicate.
|
||||
*
|
||||
* @param predicate a predicate to test tags for removal
|
||||
* @return the number of tags removed
|
||||
*/
|
||||
int removeTagIf(Predicate<Tag> predicate);
|
||||
|
||||
/**
|
||||
* Returns the index of the specified tag in the renderer's tag list.
|
||||
*
|
||||
* @param tag the tag to check
|
||||
* @return the index of the tag, or -1 if not found
|
||||
*/
|
||||
int tagIndex(Tag tag);
|
||||
|
||||
/**
|
||||
* Adds a tag at the specified index in the renderer's tag list.
|
||||
*
|
||||
* @param tag the tag to add
|
||||
* @param index the index at which to insert the tag
|
||||
*/
|
||||
void addTag(Tag tag, int index);
|
||||
|
||||
/**
|
||||
* Removes the specified tag from the renderer's tag list.
|
||||
*
|
||||
* @param tag the tag to remove
|
||||
*/
|
||||
void removeTag(Tag tag);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.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.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class TeamView {
|
||||
|
||||
private final Map<String, Set<String>> teamMembers = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
@Nullable
|
||||
public Set<String> getTeamMembers(String team) {
|
||||
return teamMembers.get(team);
|
||||
}
|
||||
|
||||
public void addTeamMembers(String team, Collection<String> members) {
|
||||
teamMembers.computeIfAbsent(team, k -> new ObjectOpenHashSet<>(members));
|
||||
}
|
||||
|
||||
public void removeTeamMembers(String team, Collection<String> members) {
|
||||
Set<String> membersSet = teamMembers.get(team);
|
||||
if (membersSet != null) {
|
||||
membersSet.removeAll(members);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeTeam(String team) {
|
||||
this.teamMembers.remove(team);
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.feature.tag;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.common.plugin.feature.Reloadable;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface UnlimitedTagManager extends Reloadable {
|
||||
|
||||
/**
|
||||
* Called every tick to update the state of tags.
|
||||
*/
|
||||
void onTick();
|
||||
|
||||
/**
|
||||
* Checks if name tags should always be shown.
|
||||
*
|
||||
* @return true if name tags are always shown, false otherwise
|
||||
*/
|
||||
boolean isAlwaysShow();
|
||||
|
||||
/**
|
||||
* Retrieves the name tag configuration by its id.
|
||||
*
|
||||
* @param id the id of the tag configuration
|
||||
* @return the corresponding NameTagConfig
|
||||
*/
|
||||
NameTagConfig configById(String id);
|
||||
|
||||
/**
|
||||
* Returns all available name tag configurations.
|
||||
*
|
||||
* @return an array of all NameTagConfig instances
|
||||
*/
|
||||
NameTagConfig[] nameTagConfigs();
|
||||
|
||||
/**
|
||||
* Sets whether a player is in preview mode for tags.
|
||||
*
|
||||
* @param player the player to update
|
||||
* @param preview true to enable preview mode, false to disable
|
||||
*/
|
||||
void setTempPreviewing(CNPlayer player, boolean preview);
|
||||
|
||||
/**
|
||||
* Sets whether a player can always see their tags
|
||||
*
|
||||
* @param player the player to update
|
||||
* @param preview true to enable preview mode, false to disable
|
||||
*/
|
||||
void togglePreviewing(CNPlayer player, boolean preview);
|
||||
|
||||
/**
|
||||
* Returns the duration (in ticks) for which a tag preview is shown.
|
||||
*
|
||||
* @return the preview duration in ticks
|
||||
*/
|
||||
int previewDuration();
|
||||
|
||||
/**
|
||||
* Returns the TagRenderer responsible for rendering tags for a specific owner.
|
||||
*
|
||||
* @param owner the owner of the tags
|
||||
* @return the TagRenderer for the owner
|
||||
*/
|
||||
@Nullable
|
||||
TagRenderer getTagRender(CNPlayer owner);
|
||||
|
||||
/**
|
||||
* Internal method for handling when a player is added to the owner's viewer list.
|
||||
*
|
||||
* @param owner the player who owns the tags
|
||||
* @param added the player who is added to the viewer list
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
void onAddPlayer(CNPlayer owner, CNPlayer added);
|
||||
|
||||
/**
|
||||
* Internal method for handling when a player is removed from the owner's viewer list.
|
||||
*
|
||||
* @param owner the player who owns the tags
|
||||
* @param removed the player who is removed from the viewer list
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
void onRemovePlayer(CNPlayer owner, CNPlayer removed);
|
||||
|
||||
/**
|
||||
* Internal method for updating a player's crouching state.
|
||||
*
|
||||
* @param owner the player who owns the tags
|
||||
* @param viewer the player viewing the tags
|
||||
* @param isCrouching true if the player is crouching, false otherwise
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
void onPlayerDataSet(CNPlayer owner, CNPlayer viewer, boolean isCrouching);
|
||||
|
||||
/**
|
||||
* Internal method for updating a player's scale attributes.
|
||||
*
|
||||
* @param owner the player who owns the tags
|
||||
* @param viewer the player viewing the tags
|
||||
* @param scale the new scale value
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
void onPlayerAttributeSet(CNPlayer owner, CNPlayer viewer, double scale);
|
||||
|
||||
/**
|
||||
* Internal method for updating a player's game mode
|
||||
*
|
||||
* @param owner the player who owns the tags
|
||||
* @param viewer the player viewing the tags
|
||||
* @param isSpectator true if the player is a spectator, false otherwise
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
void onPlayerGameModeChange(CNPlayer owner, CNPlayer viewer, boolean isSpectator);
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* 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.helper;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
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.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Helper class for handling Adventure components and related functionalities.
|
||||
*/
|
||||
public class AdventureHelper {
|
||||
|
||||
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;
|
||||
private final Cache<Object, String> minecraftComponentToMiniMessageCache;
|
||||
private final Cache<String, String> jsonToMiniMessageCache;
|
||||
|
||||
private AdventureHelper() {
|
||||
this.miniMessage = MiniMessage.builder().build();
|
||||
this.miniMessageStrict = MiniMessage.builder().strict(true).build();
|
||||
this.gsonComponentSerializer = GsonComponentSerializer.builder().build();
|
||||
|
||||
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, r -> {
|
||||
Thread thread = Executors.defaultThreadFactory().newThread(r);
|
||||
thread.setName("nameplates-cache-scheduler");
|
||||
return thread;
|
||||
});
|
||||
executor.setRemoveOnCancelPolicy(true);
|
||||
executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
|
||||
|
||||
this.miniMessageToComponentCache =
|
||||
Caffeine.newBuilder()
|
||||
.expireAfterWrite(5, TimeUnit.MINUTES)
|
||||
.executor(executor)
|
||||
.maximumSize(1024)
|
||||
.build();
|
||||
this.miniMessageToMinecraftComponentCache =
|
||||
Caffeine.newBuilder()
|
||||
.expireAfterWrite(5, TimeUnit.MINUTES)
|
||||
.executor(executor)
|
||||
.maximumSize(1024)
|
||||
.build();
|
||||
this.minecraftComponentToMiniMessageCache =
|
||||
Caffeine.newBuilder()
|
||||
.expireAfterWrite(5, TimeUnit.MINUTES)
|
||||
.executor(executor)
|
||||
.maximumSize(256)
|
||||
.build();
|
||||
this.jsonToMiniMessageCache =
|
||||
Caffeine.newBuilder()
|
||||
.expireAfterWrite(5, TimeUnit.MINUTES)
|
||||
.executor(executor)
|
||||
.maximumSize(256)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
AdventureHelper instance = getInstance();
|
||||
instance.miniMessageToMinecraftComponentCache.cleanUp();
|
||||
instance.miniMessageToComponentCache.cleanUp();
|
||||
instance.jsonToMiniMessageCache.cleanUp();
|
||||
instance.minecraftComponentToMiniMessageCache.cleanUp();
|
||||
}
|
||||
|
||||
private static class SingletonHolder {
|
||||
private static final AdventureHelper INSTANCE = new AdventureHelper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the singleton instance of AdventureHelper.
|
||||
*
|
||||
* @return the singleton instance
|
||||
*/
|
||||
public static AdventureHelper getInstance() {
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a MiniMessage string to a Component.
|
||||
*
|
||||
* @param miniMessage the MiniMessage string
|
||||
* @return the resulting Component
|
||||
*/
|
||||
public static Component miniMessage(String miniMessage) {
|
||||
AdventureHelper instance = getInstance();
|
||||
return instance.miniMessageToComponentCache.get(miniMessage, (text) -> {
|
||||
if (legacySupport) {
|
||||
return miniMessage().deserialize(legacyToMiniMessage(text));
|
||||
} else {
|
||||
return miniMessage().deserialize(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a json string to a MiniMessage string.
|
||||
*
|
||||
* @param json the JSON string
|
||||
* @return the MiniMessage string representation
|
||||
*/
|
||||
public static String jsonToMiniMessage(String json) {
|
||||
AdventureHelper instance = getInstance();
|
||||
return instance.jsonToMiniMessageCache.get(json, (rawJson) ->
|
||||
instance.miniMessageStrict.serialize(instance.gsonComponentSerializer.deserialize(json))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a MiniMessage string to a Minecraft component object.
|
||||
*
|
||||
* @param miniMessage the MiniMessage string
|
||||
* @return the Minecraft component object
|
||||
*/
|
||||
public static Object miniMessageToMinecraftComponent(String miniMessage) {
|
||||
AdventureHelper instance = getInstance();
|
||||
return instance.miniMessageToMinecraftComponentCache.get(miniMessage, (text) -> {
|
||||
String json = instance.gsonComponentSerializer.serialize(miniMessage(text));
|
||||
return CustomNameplates.getInstance().getPlatform().jsonToMinecraftComponent(json);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a MiniMessage string with a score component to a Minecraft component object.
|
||||
*
|
||||
* @param miniMessage the MiniMessage string
|
||||
* @param name the name used in the score component
|
||||
* @param objective the objective used in the score component
|
||||
* @return the Minecraft component object
|
||||
*/
|
||||
public static Object miniMessageToMinecraftComponent(String miniMessage, String name, String objective) {
|
||||
AdventureHelper instance = getInstance();
|
||||
return instance.miniMessageToMinecraftComponentCache.get(miniMessage, (text) -> {
|
||||
String json = instance.gsonComponentSerializer.serialize(Component.score().name(name).objective(objective).build().append(miniMessage(text)));
|
||||
return CustomNameplates.getInstance().getPlatform().jsonToMinecraftComponent(json);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Minecraft component object to a MiniMessage string.
|
||||
*
|
||||
* @param component the Minecraft component object
|
||||
* @return the MiniMessage string representation
|
||||
*/
|
||||
public static String minecraftComponentToMiniMessage(Object component) {
|
||||
AdventureHelper instance = getInstance();
|
||||
return instance.minecraftComponentToMiniMessageCache.get(component, (object) -> {
|
||||
String json = CustomNameplates.getInstance().getPlatform().minecraftComponentToJson(object);
|
||||
return instance.miniMessageStrict.serialize(instance.gsonComponentSerializer.deserialize(json));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the MiniMessage instance.
|
||||
*
|
||||
* @return the MiniMessage instance
|
||||
*/
|
||||
public static MiniMessage miniMessage() {
|
||||
return getInstance().miniMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the GsonComponentSerializer instance.
|
||||
*
|
||||
* @return the GsonComponentSerializer instance
|
||||
*/
|
||||
public static GsonComponentSerializer gson() {
|
||||
return getInstance().gsonComponentSerializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Surrounds the provided text with the default nameplates font.
|
||||
*
|
||||
* @param text the text to surround
|
||||
* @return the text surrounded by the default nameplates font tag
|
||||
*/
|
||||
public static String surroundWithNameplatesFont(String text) {
|
||||
return surroundWithMiniMessageFont(text, ConfigManager.namespace() + ":" + ConfigManager.font());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes shadow from the provided text using a specific color code trick.
|
||||
*
|
||||
* @param text the text to modify
|
||||
* @return the text wrapped in a color tag to remove shadows
|
||||
*/
|
||||
public static String removeShadowTricky(String text) {
|
||||
return "<#FFFEFD>" + text + "</#FFFEFD>";
|
||||
}
|
||||
|
||||
public static String removeShadow(String text) {
|
||||
return "<#F0F0F0>" + text + "</#F0F0F0>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Surrounds text with a MiniMessage font tag.
|
||||
*
|
||||
* @param text the text to surround
|
||||
* @param font the font as a {@link Key}
|
||||
* @return the text surrounded by the MiniMessage font tag
|
||||
*/
|
||||
public static String surroundWithMiniMessageFont(String text, Key font) {
|
||||
return "<font:" + font.asString() + ">" + text + "</font>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Surrounds text with a MiniMessage font tag.
|
||||
*
|
||||
* @param text the text to surround
|
||||
* @param font the font as a {@link String}
|
||||
* @return the text surrounded by the MiniMessage font tag
|
||||
*/
|
||||
public static String surroundWithMiniMessageFont(String text, String font) {
|
||||
return "<font:" + font + ">" + text + "</font>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a character is a legacy color code.
|
||||
*
|
||||
* @param c the character to check
|
||||
* @return true if the character is a color code, false otherwise
|
||||
*/
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public static boolean isLegacyColorCode(char c) {
|
||||
return c == '§' || c == '&';
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the minimessage tags
|
||||
*
|
||||
* @param text text
|
||||
* @return the stripped texts
|
||||
*/
|
||||
public static String stripTags(String text) {
|
||||
return getInstance().miniMessage.stripTags(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a legacy color code string to a MiniMessage string.
|
||||
*
|
||||
* @param legacy the legacy color code string
|
||||
* @return the MiniMessage string representation
|
||||
*/
|
||||
public static String legacyToMiniMessage(String legacy) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
char[] chars = legacy.toCharArray();
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
if (!isLegacyColorCode(chars[i])) {
|
||||
stringBuilder.append(chars[i]);
|
||||
continue;
|
||||
}
|
||||
if (i + 1 >= chars.length) {
|
||||
stringBuilder.append(chars[i]);
|
||||
continue;
|
||||
}
|
||||
switch (chars[i+1]) {
|
||||
case '0' -> stringBuilder.append("<black>");
|
||||
case '1' -> stringBuilder.append("<dark_blue>");
|
||||
case '2' -> stringBuilder.append("<dark_green>");
|
||||
case '3' -> stringBuilder.append("<dark_aqua>");
|
||||
case '4' -> stringBuilder.append("<dark_red>");
|
||||
case '5' -> stringBuilder.append("<dark_purple>");
|
||||
case '6' -> stringBuilder.append("<gold>");
|
||||
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' -> {
|
||||
if (i + 13 >= chars.length
|
||||
|| !isLegacyColorCode(chars[i+2])
|
||||
|| !isLegacyColorCode(chars[i+4])
|
||||
|| !isLegacyColorCode(chars[i+6])
|
||||
|| !isLegacyColorCode(chars[i+8])
|
||||
|| !isLegacyColorCode(chars[i+10])
|
||||
|| !isLegacyColorCode(chars[i+12])) {
|
||||
stringBuilder.append(chars[i]);
|
||||
continue;
|
||||
}
|
||||
stringBuilder
|
||||
.append("<#")
|
||||
.append(chars[i+3])
|
||||
.append(chars[i+5])
|
||||
.append(chars[i+7])
|
||||
.append(chars[i+9])
|
||||
.append(chars[i+11])
|
||||
.append(chars[i+13])
|
||||
.append(">");
|
||||
i += 12;
|
||||
}
|
||||
default -> {
|
||||
stringBuilder.append(chars[i]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.helper;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
/**
|
||||
* Helper class for managing Gson instances.
|
||||
*/
|
||||
public class GsonHelper {
|
||||
|
||||
private final Gson gson;
|
||||
|
||||
public GsonHelper() {
|
||||
this.gson = new GsonBuilder()
|
||||
.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Gson instance.
|
||||
*
|
||||
* @return the Gson instance
|
||||
*/
|
||||
public Gson getGson() {
|
||||
return gson;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the singleton Gson instance from GsonHelper.
|
||||
*
|
||||
* @return the singleton Gson instance
|
||||
*/
|
||||
public static Gson get() {
|
||||
return SingletonHolder.INSTANCE.getGson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Static inner class for holding the singleton instance of GsonHelper.
|
||||
*/
|
||||
private static class SingletonHolder {
|
||||
private static final GsonHelper INSTANCE = new GsonHelper();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* 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.helper;
|
||||
|
||||
import net.momirealms.customnameplates.common.plugin.NameplatesPlugin;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* This class implements the VersionManager interface and is responsible for managing version-related information.
|
||||
*/
|
||||
public class VersionHelper {
|
||||
|
||||
// Method to asynchronously check for plugin updates
|
||||
public static final Function<NameplatesPlugin, CompletableFuture<Boolean>> UPDATE_CHECKER = (plugin) -> {
|
||||
CompletableFuture<Boolean> updateFuture = new CompletableFuture<>();
|
||||
plugin.getScheduler().async().execute(() -> {
|
||||
try {
|
||||
URL url = new URL("https://api.polymart.org/v1/getResourceInfoSimple/?resource_id=2723&key=version");
|
||||
URLConnection conn = url.openConnection();
|
||||
conn.setConnectTimeout(10000);
|
||||
conn.setReadTimeout(60000);
|
||||
InputStream inputStream = conn.getInputStream();
|
||||
String newest = new BufferedReader(new InputStreamReader(inputStream)).readLine();
|
||||
String current = plugin.getPluginVersion();
|
||||
inputStream.close();
|
||||
if (!compareVer(newest, current)) {
|
||||
updateFuture.complete(false);
|
||||
return;
|
||||
}
|
||||
updateFuture.complete(true);
|
||||
} catch (Exception exception) {
|
||||
plugin.getPluginLogger().warn("Error occurred when checking update.");
|
||||
updateFuture.completeExceptionally(exception);
|
||||
}
|
||||
});
|
||||
return updateFuture;
|
||||
};
|
||||
|
||||
private static float version;
|
||||
private static boolean mojmap;
|
||||
private static boolean folia;
|
||||
private static boolean mohist;
|
||||
private static boolean paper;
|
||||
|
||||
public static void init(String serverVersion) {
|
||||
String[] split = serverVersion.split("\\.");
|
||||
version = Float.parseFloat(split[1] + "." + (split.length == 3 ? split[2] : "0"));
|
||||
checkMojMap();
|
||||
checkFolia();
|
||||
checkMohist();
|
||||
checkPaper();
|
||||
boolean isModdedServer = mohist;
|
||||
paper = paper && !isModdedServer;
|
||||
}
|
||||
|
||||
public static float version() {
|
||||
return version;
|
||||
}
|
||||
|
||||
private static void checkMojMap() {
|
||||
// Check if the server is Mojmap
|
||||
try {
|
||||
Class.forName("net.minecraft.network.protocol.game.ClientboundBossEventPacket");
|
||||
mojmap = true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkFolia() {
|
||||
try {
|
||||
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
|
||||
folia = true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkMohist() {
|
||||
try {
|
||||
Class.forName("com.mohistmc.api.ServerAPI");
|
||||
mohist = true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkPaper() {
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paper.Metrics");
|
||||
paper = true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isVersionNewerThan1_21_2() {
|
||||
return version >= 21.19;
|
||||
}
|
||||
|
||||
public static boolean isVersionNewerThan1_20_5() {
|
||||
return version >= 20.49;
|
||||
}
|
||||
|
||||
public static boolean isVersionNewerThan1_20_4() {
|
||||
return version >= 20.39;
|
||||
}
|
||||
|
||||
public static boolean isVersionNewerThan1_19_4() {
|
||||
return version >= 19.39;
|
||||
}
|
||||
|
||||
public static boolean isVersionNewerThan1_20_2() {
|
||||
return version >= 20.19;
|
||||
}
|
||||
|
||||
public static boolean isVersionNewerThan1_20() {
|
||||
return version >= 20;
|
||||
}
|
||||
|
||||
public static boolean isFolia() {
|
||||
return folia;
|
||||
}
|
||||
|
||||
public static boolean isMohist() {
|
||||
return mohist;
|
||||
}
|
||||
|
||||
public static boolean isPaperOrItsForks() {
|
||||
return paper;
|
||||
}
|
||||
|
||||
public static boolean isMojmap() {
|
||||
return mojmap;
|
||||
}
|
||||
|
||||
// Method to compare two version strings
|
||||
private static boolean compareVer(String newV, String currentV) {
|
||||
if (newV == null || currentV == null || newV.isEmpty() || currentV.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
String[] newVS = newV.split("\\.");
|
||||
String[] currentVS = currentV.split("\\.");
|
||||
int maxL = Math.min(newVS.length, currentVS.length);
|
||||
for (int i = 0; i < maxL; i++) {
|
||||
try {
|
||||
String[] newPart = newVS[i].split("-");
|
||||
String[] currentPart = currentVS[i].split("-");
|
||||
int newNum = Integer.parseInt(newPart[0]);
|
||||
int currentNum = Integer.parseInt(currentPart[0]);
|
||||
if (newNum > currentNum) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
return newVS.length > currentVS.length;
|
||||
}
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.sound.Sound;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface AdventureManager {
|
||||
|
||||
/**
|
||||
* Strip all the tags from text
|
||||
*
|
||||
* @param text text
|
||||
* @return stripped
|
||||
*/
|
||||
String stripTags(String text);
|
||||
|
||||
/**
|
||||
* Get component from text
|
||||
*
|
||||
* @param text text
|
||||
* @return component
|
||||
*/
|
||||
Component getComponentFromMiniMessage(String text);
|
||||
|
||||
/**
|
||||
* Send a message to a command sender
|
||||
*
|
||||
* @param sender sender
|
||||
* @param msg message
|
||||
*/
|
||||
void sendMessage(CommandSender sender, String msg);
|
||||
|
||||
/**
|
||||
* Send a message with prefix to a command sender
|
||||
*
|
||||
* @param sender sender
|
||||
* @param msg message
|
||||
*/
|
||||
void sendMessageWithPrefix(CommandSender sender, String msg);
|
||||
|
||||
/**
|
||||
* Send a message to console
|
||||
*
|
||||
* @param msg message
|
||||
*/
|
||||
void sendConsoleMessage(String msg);
|
||||
|
||||
/**
|
||||
* Send a message to a player
|
||||
*
|
||||
* @param player player
|
||||
* @param msg message
|
||||
*/
|
||||
void sendPlayerMessage(Player player, String msg);
|
||||
|
||||
/**
|
||||
* Send a title
|
||||
*
|
||||
* @param player player
|
||||
* @param title title
|
||||
* @param subtitle subtitle
|
||||
* @param in in (ms)
|
||||
* @param duration duration (ms)
|
||||
* @param out out (ms)
|
||||
*/
|
||||
void sendTitle(Player player, String title, String subtitle, int in, int duration, int out);
|
||||
|
||||
/**
|
||||
* Send a title
|
||||
*
|
||||
* @param player player
|
||||
* @param title title
|
||||
* @param subtitle subtitle
|
||||
* @param in in (ms)
|
||||
* @param duration duration (ms)
|
||||
* @param out out (ms)
|
||||
*/
|
||||
void sendTitle(Player player, Component title, Component subtitle, int in, int duration, int out);
|
||||
|
||||
/**
|
||||
* Send an actionbar
|
||||
*
|
||||
* @param player player
|
||||
* @param msg msg
|
||||
*/
|
||||
void sendActionbar(Player player, String msg);
|
||||
|
||||
/**
|
||||
* Send an actionbar
|
||||
*
|
||||
* @param player player
|
||||
* @param component component
|
||||
*/
|
||||
void sendActionbar(Player player, Component component);
|
||||
|
||||
/**
|
||||
* Play a sound to a player
|
||||
*
|
||||
* @param player player
|
||||
* @param source sound source
|
||||
* @param key sound key
|
||||
* @param volume volume
|
||||
* @param pitch pitch
|
||||
*/
|
||||
void sendSound(Player player, Sound.Source source, Key key, float volume, float pitch);
|
||||
|
||||
/**
|
||||
* Play a sound to a player
|
||||
*
|
||||
* @param player player
|
||||
* @param sound sound
|
||||
*/
|
||||
void sendSound(Player player, Sound sound);
|
||||
|
||||
/**
|
||||
* Replace legacy color codes to MiniMessage format
|
||||
*
|
||||
* @param legacy legacy text
|
||||
* @return MiniMessage format text
|
||||
*/
|
||||
String legacyToMiniMessage(String legacy);
|
||||
|
||||
/**
|
||||
* If a char is legacy color code
|
||||
*
|
||||
* @param c char
|
||||
* @return is legacy color
|
||||
*/
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
boolean isColorCode(char c);
|
||||
|
||||
/**
|
||||
* Convert a color into decimal
|
||||
*
|
||||
* @param color color
|
||||
* @return decimal
|
||||
*/
|
||||
int colorToDecimal(ChatColor color);
|
||||
|
||||
/**
|
||||
* Get legacy format text
|
||||
*
|
||||
* @param component component
|
||||
* @return legacy format text
|
||||
*/
|
||||
String componentToLegacy(Component component);
|
||||
|
||||
/**
|
||||
* Get json by component
|
||||
*
|
||||
* @param component component
|
||||
* @return json
|
||||
*/
|
||||
String componentToJson(Component component);
|
||||
|
||||
/**
|
||||
* Get MiniMessage format text from component
|
||||
*
|
||||
* @param component component
|
||||
* @return text
|
||||
*/
|
||||
String getMiniMessageFormat(Component component);
|
||||
|
||||
/**
|
||||
* Get IChatComponent from Json
|
||||
*
|
||||
* @param json json
|
||||
* @return component
|
||||
*/
|
||||
Object getIChatComponent(String json);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.background.BackGround;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface BackGroundManager {
|
||||
|
||||
/**
|
||||
* Get a background's config by key
|
||||
*
|
||||
* @param key key
|
||||
* @return background
|
||||
*/
|
||||
@Nullable
|
||||
BackGround getBackGround(@NotNull String key);
|
||||
|
||||
/**
|
||||
* Get all the backgrounds
|
||||
*
|
||||
* @return backgrounds
|
||||
*/
|
||||
Collection<BackGround> getBackGrounds();
|
||||
|
||||
/**
|
||||
* Register a background into the plugin
|
||||
* This will fail if there already exists one with the same key
|
||||
*
|
||||
* @param key key
|
||||
* @param backGround background
|
||||
* @return success or not
|
||||
*/
|
||||
boolean registerBackGround(@NotNull String key, @NotNull BackGround backGround);
|
||||
|
||||
/**
|
||||
* Unregister a background by key
|
||||
* This will fail if the key doesn't exist
|
||||
*
|
||||
* @param key key
|
||||
* @return success or not
|
||||
*/
|
||||
boolean unregisterBackGround(@NotNull String key);
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.bubble.Bubble;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface BubbleManager {
|
||||
|
||||
/**
|
||||
* Register a bubble into map
|
||||
*
|
||||
* @param key key
|
||||
* @param bubble bubble
|
||||
* @return success or not
|
||||
*/
|
||||
boolean registerBubble(String key, Bubble bubble);
|
||||
|
||||
/**
|
||||
* Unregister a bubble from map
|
||||
*
|
||||
* @param key key
|
||||
* @return success or not
|
||||
*/
|
||||
boolean unregisterBubble(String key);
|
||||
|
||||
/**
|
||||
* Get a bubble from map
|
||||
*
|
||||
* @param bubble key
|
||||
* @return bubble
|
||||
*/
|
||||
@Nullable Bubble getBubble(String bubble);
|
||||
|
||||
/**
|
||||
* If a player has a certain bubble
|
||||
*
|
||||
* @param player player
|
||||
* @param bubble key
|
||||
* @return
|
||||
*/
|
||||
boolean hasBubble(Player player, String bubble);
|
||||
|
||||
/**
|
||||
* Get a list of the bubbles that a player has
|
||||
*
|
||||
* @param player player
|
||||
* @return bubbles' keys
|
||||
*/
|
||||
List<String> getAvailableBubbles(Player player);
|
||||
|
||||
/**
|
||||
* Get a list of the bubbles' display names that a player has
|
||||
*
|
||||
* @param player player
|
||||
* @return bubbles' display names
|
||||
*/
|
||||
List<String> getAvailableBubblesDisplayNames(Player player);
|
||||
|
||||
/**
|
||||
* Get blacklist chat channels
|
||||
*
|
||||
* @return channels
|
||||
*/
|
||||
String[] getBlacklistChannels();
|
||||
|
||||
/**
|
||||
* Get all the bubbles
|
||||
*
|
||||
* @return bubbles
|
||||
*/
|
||||
Collection<Bubble> getBubbles();
|
||||
|
||||
/**
|
||||
* Whether a bubble exists
|
||||
*/
|
||||
boolean containsBubble(String key);
|
||||
|
||||
/**
|
||||
* Equip a bubble for a player
|
||||
*
|
||||
* @param player player
|
||||
* @param bubble bubble
|
||||
* @return success or not
|
||||
*/
|
||||
boolean equipBubble(Player player, String bubble);
|
||||
|
||||
/**
|
||||
* Unequip a bubble for a player
|
||||
*
|
||||
* @param player player
|
||||
*/
|
||||
void unEquipBubble(Player player);
|
||||
|
||||
/**
|
||||
* Get the default bubble key
|
||||
*
|
||||
* @return bubble key
|
||||
*/
|
||||
String getDefaultBubble();
|
||||
|
||||
/**
|
||||
* Get all the bubbles' keys
|
||||
*
|
||||
* @return keys
|
||||
*/
|
||||
Collection<String> getBubbleKeys();
|
||||
|
||||
/**
|
||||
* Trigger chat
|
||||
*
|
||||
* @param player player
|
||||
* @param text text
|
||||
*/
|
||||
void onChat(Player player, String text);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.character.ConfiguredChar;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface ImageManager {
|
||||
|
||||
/**
|
||||
* Get an image by key
|
||||
*
|
||||
* @param key key
|
||||
* @return image
|
||||
*/
|
||||
@Nullable
|
||||
ConfiguredChar getImage(@NotNull String key);
|
||||
|
||||
/**
|
||||
* Get all the images
|
||||
*
|
||||
* @return images
|
||||
*/
|
||||
Collection<ConfiguredChar> getImages();
|
||||
|
||||
/**
|
||||
* Register am image into the plugin
|
||||
* This will fail if there already exists one with the same key
|
||||
*
|
||||
* @param key key
|
||||
* @param configuredChar image
|
||||
* @return success or not
|
||||
*/
|
||||
boolean registerImage(@NotNull String key, @NotNull ConfiguredChar configuredChar);
|
||||
|
||||
/**
|
||||
* Unregister an image by key
|
||||
* This will fail if the key doesn't exist
|
||||
*
|
||||
* @param key key
|
||||
* @return success or not
|
||||
*/
|
||||
boolean unregisterImage(@NotNull String key);
|
||||
}
|
||||
@@ -1,311 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.nameplate.CachedNameplate;
|
||||
import net.momirealms.customnameplates.api.mechanic.nameplate.Nameplate;
|
||||
import net.momirealms.customnameplates.api.mechanic.nameplate.TagMode;
|
||||
import net.momirealms.customnameplates.api.mechanic.tag.NameplatePlayer;
|
||||
import net.momirealms.customnameplates.common.team.TeamColor;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface NameplateManager {
|
||||
|
||||
/**
|
||||
* Get the default nameplate
|
||||
*/
|
||||
@NotNull
|
||||
String getDefaultNameplate();
|
||||
|
||||
/**
|
||||
* Put an entity's ID to map
|
||||
* This map is used for quickly getting the entity instance
|
||||
* Removal from the map is necessary when the entity is invalid
|
||||
* Otherwise it would cause memory leak
|
||||
*
|
||||
* @param entityID entityID
|
||||
* @param entity entity
|
||||
*/
|
||||
boolean putEntityIDToMap(int entityID, @NotNull Entity entity);
|
||||
|
||||
/**
|
||||
* Remove the entity from map
|
||||
*
|
||||
* @param entityID entityID
|
||||
* @return the removed entity
|
||||
*/
|
||||
@Nullable
|
||||
Entity removeEntityIDFromMap(int entityID);
|
||||
|
||||
/**
|
||||
* Nameplates are cached in memory so they would not be frequently updated
|
||||
* The update rate is decided by "refresh-frequency" in nameplate.yml
|
||||
*
|
||||
* @param uuid player uuid
|
||||
* @param nameplate cached nameplate
|
||||
*/
|
||||
boolean putCachedNameplateToMap(@NotNull UUID uuid, @NotNull CachedNameplate nameplate);
|
||||
|
||||
/**
|
||||
* Remove CachedNameplate from map
|
||||
*
|
||||
* @param uuid player uuid
|
||||
* @return removed CachedNameplate
|
||||
*/
|
||||
@Nullable
|
||||
CachedNameplate removeCachedNameplateFromMap(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Get player by entityID from the cache
|
||||
*
|
||||
* @param id entityID
|
||||
* @return player
|
||||
*/
|
||||
@Nullable
|
||||
Player getPlayerByEntityID(int id);
|
||||
|
||||
/**
|
||||
* Get entity by entityID from the cache
|
||||
*
|
||||
* @param id entityID
|
||||
* @return entity
|
||||
*/
|
||||
@Nullable
|
||||
Entity getEntityByEntityID(int id);
|
||||
|
||||
/**
|
||||
* Update a player's cached nameplate
|
||||
* The nameplate is affected by "prefix" and "suffix" option
|
||||
*
|
||||
* @param player player
|
||||
* @return if the nameplate is updated
|
||||
*/
|
||||
boolean updateCachedNameplate(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Update a player's cached nameplate
|
||||
* The nameplate is affected by "prefix" and "suffix" option
|
||||
*
|
||||
* @param player player
|
||||
* @return if the nameplate is updated
|
||||
*/
|
||||
boolean updateCachedNameplate(@NotNull Player player, @Nullable Nameplate nameplate);
|
||||
|
||||
/**
|
||||
* This should not be null when player's data is loaded (async process)
|
||||
*
|
||||
* @param player player
|
||||
* @return cached nameplate
|
||||
*/
|
||||
@Nullable
|
||||
CachedNameplate getCacheNameplate(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Create a name tag for a player, the tag type is decided by the mode in nameplate.yml
|
||||
* If mode is DISABLE, this method would return null
|
||||
* The tag would be put into map automatically and you can get it by getNameplatePlayer(uuid)
|
||||
*
|
||||
* @param player player
|
||||
*/
|
||||
@Nullable
|
||||
NameplatePlayer createNameTag(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Put a nameplater player to map
|
||||
*
|
||||
* @param player player
|
||||
*/
|
||||
void putNameplatePlayerToMap(@NotNull NameplatePlayer player);
|
||||
|
||||
/**
|
||||
* Get a nameplate player from map
|
||||
*
|
||||
* @param uuid uuid
|
||||
* @return nameplate player
|
||||
*/
|
||||
@Nullable
|
||||
NameplatePlayer getNameplatePlayer(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Remove nameplate player from map
|
||||
*
|
||||
* @param uuid uuid
|
||||
* @return removed nameplate player
|
||||
*/
|
||||
@Nullable
|
||||
NameplatePlayer removeNameplatePlayerFromMap(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Get the nameplate's prefix with text tags
|
||||
*
|
||||
* @param player player
|
||||
* @return prefix with text tags
|
||||
*/
|
||||
@NotNull
|
||||
String getNameplatePrefix(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Get the nameplate's suffix with text tags
|
||||
*
|
||||
* @param player player
|
||||
* @return suffix with text tags
|
||||
*/
|
||||
@NotNull
|
||||
String getNameplateSuffix(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Get the full nameplate tag
|
||||
*
|
||||
* @param player player
|
||||
* @return nameplate tag
|
||||
*/
|
||||
@NotNull
|
||||
String getFullNameTag(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Register a custom nameplate into map
|
||||
*
|
||||
* @param key key
|
||||
* @param nameplate nameplate
|
||||
* @return success or not
|
||||
*/
|
||||
boolean registerNameplate(@NotNull String key, @NotNull Nameplate nameplate);
|
||||
|
||||
/**
|
||||
* Unregister a nameplate from map
|
||||
*
|
||||
* @param key key
|
||||
* @return success or not
|
||||
*/
|
||||
boolean unregisterNameplate(@NotNull String key);
|
||||
|
||||
/**
|
||||
* Equip a nameplate for a player
|
||||
*
|
||||
* @param player player
|
||||
* @param nameplateKey key
|
||||
* @param temp whether save to storage
|
||||
* @return success or not
|
||||
*/
|
||||
boolean equipNameplate(@NotNull Player player, @NotNull String nameplateKey, boolean temp);
|
||||
|
||||
/**
|
||||
* Remove a nameplate for a player
|
||||
*
|
||||
* @param player player
|
||||
* @param temp whether save to storage
|
||||
*/
|
||||
void unEquipNameplate(Player player, boolean temp);
|
||||
|
||||
/**
|
||||
* Is team managed on proxy side
|
||||
*/
|
||||
boolean isProxyMode();
|
||||
|
||||
/**
|
||||
* Get preview duration
|
||||
*/
|
||||
int getPreviewDuration();
|
||||
|
||||
/**
|
||||
* Get the tag mode
|
||||
*/
|
||||
@NotNull
|
||||
TagMode getTagMode();
|
||||
|
||||
/**
|
||||
* Get a nameplate by key
|
||||
*
|
||||
* @param key key
|
||||
* @return nameplate
|
||||
*/
|
||||
@NotNull
|
||||
Nameplate getNameplate(@NotNull String key);
|
||||
|
||||
/**
|
||||
* Get all the nameplates
|
||||
*
|
||||
* @return nameplates
|
||||
*/
|
||||
@NotNull
|
||||
Collection<Nameplate> getNameplates();
|
||||
|
||||
/**
|
||||
* Get all the nameplates' keys
|
||||
*
|
||||
* @return keys
|
||||
*/
|
||||
@NotNull
|
||||
Collection<String> getNameplateKeys();
|
||||
|
||||
/**
|
||||
* Whether a nameplate key exists
|
||||
*/
|
||||
boolean containsNameplate(@NotNull String key);
|
||||
|
||||
/**
|
||||
* Get all the nameplates that the player has
|
||||
*
|
||||
* @param player player
|
||||
* @return nameplates' keys
|
||||
*/
|
||||
@NotNull
|
||||
List<String> getAvailableNameplates(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* If player has permission for a certain nameplate
|
||||
*/
|
||||
boolean hasNameplate(@NotNull Player player, @NotNull String nameplate);
|
||||
|
||||
/**
|
||||
* Get all the nameplates' display names that the player has
|
||||
*
|
||||
* @param player player
|
||||
* @return nameplates' display names
|
||||
*/
|
||||
@NotNull
|
||||
List<String> getAvailableNameplateDisplayNames(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Get the nameplate's team color
|
||||
*
|
||||
* @param player player
|
||||
* @return team color
|
||||
*/
|
||||
@NotNull
|
||||
TeamColor getTeamColor(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Get team tag manager
|
||||
*/
|
||||
@NotNull
|
||||
TeamTagManager getTeamTagManager();
|
||||
|
||||
/**
|
||||
* Get unlimited tag manager
|
||||
*/
|
||||
@NotNull
|
||||
UnlimitedTagManager getUnlimitedTagManager();
|
||||
}
|
||||
-148
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.placeholder.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface PlaceholderManager {
|
||||
|
||||
/**
|
||||
* Detect all the placeholders
|
||||
*
|
||||
* @param text text
|
||||
* @return placeholder
|
||||
*/
|
||||
@NotNull
|
||||
List<String> detectPlaceholders(String text);
|
||||
|
||||
/**
|
||||
* Get a static text instance
|
||||
*
|
||||
* @param key key
|
||||
* @return static text
|
||||
*/
|
||||
@Nullable
|
||||
StaticText getStaticText(String key);
|
||||
|
||||
/**
|
||||
* Get all the static texts
|
||||
*
|
||||
* @return static texts
|
||||
*/
|
||||
Collection<StaticText> getStaticTexts();
|
||||
|
||||
/**
|
||||
* Get a switch text instance
|
||||
*
|
||||
* @param key key
|
||||
* @return switch text
|
||||
*/
|
||||
@Nullable
|
||||
SwitchText getSwitchText(String key);
|
||||
|
||||
/**
|
||||
* Get all the switch texts
|
||||
*
|
||||
* @return switch texts
|
||||
*/
|
||||
Collection<SwitchText> getSwitchTexts();
|
||||
|
||||
/**
|
||||
* Get a descent text instance
|
||||
*
|
||||
* @param key key
|
||||
* @return descent text
|
||||
*/
|
||||
@Nullable
|
||||
DescentText getDescentText(String key);
|
||||
|
||||
/**
|
||||
* Get all the descent texts
|
||||
*
|
||||
* @return descent texts
|
||||
*/
|
||||
Collection<DescentText> getDescentTexts();
|
||||
|
||||
/**
|
||||
* Get a conditional text
|
||||
*
|
||||
* @param key key
|
||||
* @return conditional text
|
||||
*/
|
||||
@Nullable
|
||||
ConditionalText getConditionalText(String key);
|
||||
|
||||
/**
|
||||
* Get all the conditional texts
|
||||
*
|
||||
* @return conditional texts
|
||||
*/
|
||||
Collection<ConditionalText> getConditionalTexts();
|
||||
|
||||
/**
|
||||
* Get a nameplate text
|
||||
*
|
||||
* @param key key
|
||||
* @return nameplate text
|
||||
*/
|
||||
@Nullable
|
||||
NameplateText getNameplateText(String key);
|
||||
|
||||
/**
|
||||
* Get all the nameplate texts
|
||||
*
|
||||
* @return nameplate texts
|
||||
*/
|
||||
Collection<NameplateText> getNameplateTexts();
|
||||
|
||||
/**
|
||||
* Get a background text
|
||||
*
|
||||
* @param key key
|
||||
* @return background text
|
||||
*/
|
||||
@Nullable
|
||||
BackGroundText getBackGroundText(String key);
|
||||
|
||||
/**
|
||||
* Get all the background texts
|
||||
*
|
||||
* @return background texts
|
||||
*/
|
||||
Collection<BackGroundText> getBackGroundTexts();
|
||||
|
||||
/**
|
||||
* Get a vanilla hud
|
||||
*
|
||||
* @param key key
|
||||
* @return vanilla hud
|
||||
*/
|
||||
VanillaHud getVanillaHud(String key);
|
||||
|
||||
/**
|
||||
* Get all the vanilla huds
|
||||
*
|
||||
* @return vanilla huds
|
||||
*/
|
||||
Collection<VanillaHud> getVanillaHuds();
|
||||
}
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.momirealms.customnameplates.api.requirement.Condition;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
import net.momirealms.customnameplates.api.requirement.RequirementFactory;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface RequirementManager {
|
||||
|
||||
/**
|
||||
* Registers a custom requirement type with its corresponding factory.
|
||||
*
|
||||
* @param type The type identifier of the requirement.
|
||||
* @param requirementFactory The factory responsible for creating instances of the requirement.
|
||||
* @return True if registration was successful, false if the type is already registered.
|
||||
*/
|
||||
boolean registerRequirement(String type, RequirementFactory requirementFactory);
|
||||
|
||||
/**
|
||||
* Unregisters a custom requirement type.
|
||||
*
|
||||
* @param type The type identifier of the requirement to unregister.
|
||||
* @return True if unregistration was successful, false if the type is not registered.
|
||||
*/
|
||||
boolean unregisterRequirement(String type);
|
||||
|
||||
/**
|
||||
* Retrieves an array of requirements based on a configuration section.
|
||||
*
|
||||
* @param section The configuration section containing requirement definitions.
|
||||
* @return An array of Requirement objects based on the configuration section
|
||||
*/
|
||||
@Nullable Requirement[] getRequirements(ConfigurationSection section);
|
||||
|
||||
/**
|
||||
* Retrieves a Requirement object based on a configuration section and advanced flag.
|
||||
* <p>
|
||||
* requirement_1: <- section
|
||||
* type: xxx
|
||||
* value: xxx
|
||||
*
|
||||
* @param section The configuration section containing requirement definitions.
|
||||
* @return A Requirement object based on the configuration section, or an EmptyRequirement if the section is null or invalid.
|
||||
*/
|
||||
@NotNull Requirement getRequirement(ConfigurationSection section);
|
||||
|
||||
/**
|
||||
* Gets a requirement based on the provided type and value.
|
||||
* If a valid RequirementFactory is found for the type, it is used to create the requirement.
|
||||
* If no factory is found, a warning is logged, and an empty requirement instance is returned.
|
||||
* <p>
|
||||
* world: <- type
|
||||
* - world <- value
|
||||
*
|
||||
* @param type The type representing the requirement type.
|
||||
* @param value The value associated with the requirement.
|
||||
* @return A Requirement instance based on the type and value, or an EmptyRequirement if the type is invalid.
|
||||
*/
|
||||
@NotNull Requirement getRequirement(String type, Object value);
|
||||
|
||||
/**
|
||||
* Retrieves a RequirementFactory based on the specified requirement type.
|
||||
*
|
||||
* @param type The requirement type for which to retrieve a factory.
|
||||
* @return A RequirementFactory for the specified type, or null if no factory is found.
|
||||
*/
|
||||
@Nullable RequirementFactory getRequirementFactory(String type);
|
||||
|
||||
/**
|
||||
* Checks if an array of requirements is met for a given condition.
|
||||
*
|
||||
* @param condition The Condition object to check against the requirements.
|
||||
* @param requirements An array of Requirement instances to be evaluated.
|
||||
* @return True if all requirements are met, false otherwise. Returns true if the requirements array is null.
|
||||
*/
|
||||
static boolean isRequirementMet(Condition condition, Requirement... requirements) {
|
||||
if (requirements == null) return true;
|
||||
for (Requirement requirement : requirements) {
|
||||
if (!requirement.isConditionMet(condition)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.momirealms.customnameplates.api.data.DataStorageInterface;
|
||||
import net.momirealms.customnameplates.api.data.OnlineUser;
|
||||
import net.momirealms.customnameplates.api.data.PlayerData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface StorageManager {
|
||||
|
||||
/**
|
||||
* Get online users
|
||||
*
|
||||
* @return online users
|
||||
*/
|
||||
Collection<OnlineUser> getOnlineUsers();
|
||||
|
||||
/**
|
||||
* Get a player's data by uuid
|
||||
* The player can be an offline one
|
||||
*
|
||||
* @param uuid uuid
|
||||
* @return player data
|
||||
*/
|
||||
CompletableFuture<Optional<PlayerData>> getPlayerData(UUID uuid);
|
||||
|
||||
/**
|
||||
* Save online players' data
|
||||
*
|
||||
* @param uuid uuid
|
||||
* @return success or not
|
||||
*/
|
||||
CompletableFuture<Boolean> saveOnlinePlayerData(UUID uuid);
|
||||
|
||||
/**
|
||||
* Save specified data
|
||||
*
|
||||
* @param uuid uuid
|
||||
* @param playerData playerData
|
||||
* @return success or not
|
||||
*/
|
||||
CompletableFuture<Boolean> savePlayerData(UUID uuid, PlayerData playerData);
|
||||
|
||||
/**
|
||||
* Get an online user by uuid
|
||||
*
|
||||
* @param uuid uuid
|
||||
* @return online user
|
||||
*/
|
||||
Optional<OnlineUser> getOnlineUser(UUID uuid);
|
||||
|
||||
/**
|
||||
* Get player data from json
|
||||
*
|
||||
* @param json json
|
||||
* @return data
|
||||
*/
|
||||
@NotNull
|
||||
PlayerData fromJson(String json);
|
||||
|
||||
/**
|
||||
* Get player data from bytes
|
||||
*
|
||||
* @param data data
|
||||
* @return data
|
||||
*/
|
||||
PlayerData fromBytes(byte[] data);
|
||||
|
||||
/**
|
||||
* Convert player data to bytes
|
||||
*
|
||||
* @param playerData playerData
|
||||
* @return bytes
|
||||
*/
|
||||
byte[] toBytes(PlayerData playerData);
|
||||
|
||||
/**
|
||||
* Convert player data to json
|
||||
*
|
||||
* @param playerData playerData
|
||||
* @return json
|
||||
*/
|
||||
@NotNull
|
||||
String toJson(@NotNull PlayerData playerData);
|
||||
|
||||
DataStorageInterface getDataSource();
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.momirealms.customnameplates.common.team.TeamColor;
|
||||
import net.momirealms.customnameplates.common.team.TeamTagVisibility;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface TeamManager {
|
||||
|
||||
/**
|
||||
* Create team for a player
|
||||
*
|
||||
* @param player player
|
||||
*/
|
||||
void createTeam(Player player);
|
||||
|
||||
/**
|
||||
* Remove a team for a player
|
||||
*
|
||||
* @param player player
|
||||
*/
|
||||
void removeTeam(Player player);
|
||||
|
||||
/**
|
||||
* Update a player's team for a viewer
|
||||
*/
|
||||
void updateTeam(Player owner, Player viewer, String prefix, String suffix, TeamColor color, TeamTagVisibility visibility);
|
||||
|
||||
/**
|
||||
* Get the team player in
|
||||
*
|
||||
* @param player player
|
||||
* @param viewer viewer
|
||||
* @return team name
|
||||
*/
|
||||
String getTeamName(Player player, Player viewer);
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.tag.unlimited.*;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface UnlimitedTagManager {
|
||||
|
||||
/**
|
||||
* Create a named entity (ArmorStand) for an entity
|
||||
* To apply the changes, you should add it to the EntityTagEntity
|
||||
*
|
||||
* @param entity entity
|
||||
* @param setting setting
|
||||
* @return named entity
|
||||
*/
|
||||
@NotNull StaticTextEntity createNamedEntity(EntityTagEntity entity, StaticTextTagSetting setting);
|
||||
|
||||
/**
|
||||
* Create a named entity (ArmorStand) for a player
|
||||
* To apply the changes, you should add it the named player instance
|
||||
*
|
||||
* @param player player
|
||||
* @param setting setting
|
||||
* @return named entity
|
||||
*/
|
||||
@NotNull
|
||||
DynamicTextEntity createNamedEntity(EntityTagPlayer player, DynamicTextTagSetting setting);
|
||||
|
||||
/**
|
||||
* Create or get a tag instance
|
||||
*
|
||||
* @param entity entity
|
||||
* @return entity tag instance
|
||||
*/
|
||||
EntityTagEntity createOrGetTagForEntity(Entity entity);
|
||||
|
||||
/**
|
||||
* Create or get a tag instance
|
||||
*
|
||||
* @param player player
|
||||
* @return entity tag instance
|
||||
*/
|
||||
EntityTagPlayer createOrGetTagForPlayer(Player player);
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.CompletionStage;
|
||||
|
||||
public interface VersionManager {
|
||||
|
||||
/**
|
||||
* Is folia scheduler implemented
|
||||
*/
|
||||
boolean isFolia();
|
||||
|
||||
/**
|
||||
* Get bukkit version
|
||||
*
|
||||
* @return version
|
||||
*/
|
||||
String getServerVersion();
|
||||
|
||||
/**
|
||||
* Check update
|
||||
*
|
||||
* @return return true if plugin needs update
|
||||
*/
|
||||
CompletionStage<Boolean> checkUpdate();
|
||||
|
||||
/**
|
||||
* Get plugin version
|
||||
*
|
||||
* @return version
|
||||
*/
|
||||
@NotNull
|
||||
String getPluginVersion();
|
||||
|
||||
/**
|
||||
* Is the plugin the latest version
|
||||
*
|
||||
* @return latest or not
|
||||
*/
|
||||
boolean isLatest();
|
||||
|
||||
/**
|
||||
* Get pack format
|
||||
*
|
||||
* @return pack format
|
||||
*/
|
||||
int getPackFormat();
|
||||
|
||||
boolean isVersionNewerThan1_19();
|
||||
|
||||
boolean isVersionNewerThan1_19_R2();
|
||||
|
||||
boolean isVersionNewerThan1_19_R3();
|
||||
|
||||
boolean isVersionNewerThan1_20();
|
||||
|
||||
boolean isVersionNewerThan1_20_R2();
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.manager;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.font.FontData;
|
||||
import net.momirealms.customnameplates.common.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface WidthManager {
|
||||
|
||||
/**
|
||||
* Register a font data into the plugin
|
||||
* If there already exists one, it would fail
|
||||
*
|
||||
* @param key key
|
||||
* @param fontData data
|
||||
* @return success or not
|
||||
*/
|
||||
boolean registerFontData(@NotNull Key key, @NotNull FontData fontData);
|
||||
|
||||
/**
|
||||
* Unregister a font data from map
|
||||
*
|
||||
* @param key key
|
||||
* @return success or not
|
||||
*/
|
||||
boolean unregisterFontData(@NotNull Key key);
|
||||
|
||||
/**
|
||||
* Get font data by key
|
||||
*
|
||||
* @param key key
|
||||
* @return font data
|
||||
*/
|
||||
@Nullable
|
||||
FontData getFontData(@NotNull Key key);
|
||||
|
||||
/**
|
||||
* Get text's width (MiniMessage format text)
|
||||
*
|
||||
* @param textWithTags text
|
||||
* @return width
|
||||
*/
|
||||
int getTextWidth(@NotNull String textWithTags);
|
||||
}
|
||||
-230
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.background;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.character.ConfiguredChar;
|
||||
import net.momirealms.customnameplates.api.mechanic.font.OffsetFont;
|
||||
|
||||
public class BackGround {
|
||||
|
||||
private ConfiguredChar left, offset_1, offset_2, offset_4, offset_8, offset_16, offset_32, offset_64, offset_128, right;
|
||||
private int leftMargin, rightMargin;
|
||||
|
||||
private BackGround() {
|
||||
}
|
||||
|
||||
public BackGround(
|
||||
ConfiguredChar left,
|
||||
ConfiguredChar offset_1,
|
||||
ConfiguredChar offset_2,
|
||||
ConfiguredChar offset_4,
|
||||
ConfiguredChar offset_8,
|
||||
ConfiguredChar offset_16,
|
||||
ConfiguredChar offset_32,
|
||||
ConfiguredChar offset_64,
|
||||
ConfiguredChar offset_128,
|
||||
ConfiguredChar right,
|
||||
int leftMargin,
|
||||
int rightMargin,
|
||||
boolean removeShadow
|
||||
) {
|
||||
this.left = left;
|
||||
this.offset_1 = offset_1;
|
||||
this.offset_2 = offset_2;
|
||||
this.offset_4 = offset_4;
|
||||
this.offset_8 = offset_8;
|
||||
this.offset_16 = offset_16;
|
||||
this.offset_32 = offset_32;
|
||||
this.offset_64 = offset_64;
|
||||
this.offset_128 = offset_128;
|
||||
this.right = right;
|
||||
this.leftMargin = leftMargin;
|
||||
this.rightMargin = rightMargin;
|
||||
}
|
||||
|
||||
public ConfiguredChar getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset_1() {
|
||||
return offset_1;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset_2() {
|
||||
return offset_2;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset_4() {
|
||||
return offset_4;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset_8() {
|
||||
return offset_8;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset_16() {
|
||||
return offset_16;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset_32() {
|
||||
return offset_32;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset_64() {
|
||||
return offset_64;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset_128() {
|
||||
return offset_128;
|
||||
}
|
||||
|
||||
public ConfiguredChar getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public String getBackGroundImage(int n) {
|
||||
String offset = OffsetFont.getShortestNegChars(n + rightMargin + 2);
|
||||
n = n + leftMargin + rightMargin + 2;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append(left.getCharacter());
|
||||
while (n >= 128) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(offset_128.getCharacter());
|
||||
n -= 128;
|
||||
}
|
||||
if (n - 64 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(offset_64.getCharacter());
|
||||
n -= 64;
|
||||
}
|
||||
if (n - 32 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(offset_32.getCharacter());
|
||||
n -= 32;
|
||||
}
|
||||
if (n - 16 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(offset_16.getCharacter());
|
||||
n -= 16;
|
||||
}
|
||||
if (n - 8 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(offset_8.getCharacter());
|
||||
n -= 8;
|
||||
}
|
||||
if (n - 4 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(offset_4.getCharacter());
|
||||
n -= 4;
|
||||
}
|
||||
if (n - 2 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(offset_2.getCharacter());
|
||||
n -= 2;
|
||||
}
|
||||
if (n - 1 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(offset_1.getCharacter());
|
||||
}
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(right.getCharacter());
|
||||
stringBuilder.append(offset);
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final BackGround backGround;
|
||||
|
||||
public static Builder of() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder() {
|
||||
this.backGround = new BackGround();
|
||||
}
|
||||
|
||||
public Builder left(ConfiguredChar configuredChar) {
|
||||
backGround.left = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder right(ConfiguredChar configuredChar) {
|
||||
backGround.right = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset_1(ConfiguredChar configuredChar) {
|
||||
backGround.offset_1 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset_2(ConfiguredChar configuredChar) {
|
||||
backGround.offset_2 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset_4(ConfiguredChar configuredChar) {
|
||||
backGround.offset_4 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset_8(ConfiguredChar configuredChar) {
|
||||
backGround.offset_8 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset_16(ConfiguredChar configuredChar) {
|
||||
backGround.offset_16 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset_32(ConfiguredChar configuredChar) {
|
||||
backGround.offset_32 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset_64(ConfiguredChar configuredChar) {
|
||||
backGround.offset_64 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset_128(ConfiguredChar configuredChar) {
|
||||
backGround.offset_128 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder leftMargin(int margin) {
|
||||
backGround.leftMargin = margin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder rightMargin(int margin) {
|
||||
backGround.rightMargin = margin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BackGround build() {
|
||||
return backGround;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.bubble;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.character.ConfiguredChar;
|
||||
import net.momirealms.customnameplates.api.mechanic.font.OffsetFont;
|
||||
import net.momirealms.customnameplates.api.util.FontUtils;
|
||||
|
||||
public class Bubble {
|
||||
|
||||
private String startFormat, endFormat;
|
||||
private String displayName;
|
||||
private ConfiguredChar left, middle, right, tail;
|
||||
|
||||
private Bubble() {
|
||||
}
|
||||
|
||||
public Bubble(String startFormat, String endFormat, String displayName, ConfiguredChar left, ConfiguredChar middle, ConfiguredChar right, ConfiguredChar tail) {
|
||||
this.startFormat = startFormat;
|
||||
this.endFormat = endFormat;
|
||||
this.displayName = displayName;
|
||||
this.left = left;
|
||||
this.middle = middle;
|
||||
this.right = right;
|
||||
this.tail = tail;
|
||||
}
|
||||
|
||||
public String getPrefixWithFont(int textWidth) {
|
||||
return FontUtils.surroundNameplateFont(getPrefix(textWidth));
|
||||
}
|
||||
|
||||
public String getPrefix(int textWidth) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("<#FEFEFE>");
|
||||
stringBuilder.append(OffsetFont.getShortestNegChars(textWidth + left.getWidth() + 1));
|
||||
stringBuilder.append(left.getCharacter());
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
int mid_amount;
|
||||
if (textWidth - 1 <= tail.getWidth()) {
|
||||
mid_amount = -1;
|
||||
} else {
|
||||
mid_amount = (textWidth - 1 - tail.getWidth()) / (middle.getWidth());
|
||||
}
|
||||
if (mid_amount == -1) {
|
||||
stringBuilder.append("<#FDFEFE>").append(tail.getCharacter()).append("</#FDFEFE>").append(OffsetFont.NEG_1.getCharacter());
|
||||
} else if (mid_amount == 0) {
|
||||
stringBuilder.append("<#FDFEFE>").append(tail.getCharacter()).append("</#FDFEFE>").append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(OffsetFont.getShortestNegChars(middle.getWidth() - (textWidth - 1 - tail.getWidth()) % middle.getWidth()));
|
||||
stringBuilder.append(middle.getCharacter()).append(OffsetFont.NEG_1.getCharacter());
|
||||
} else {
|
||||
stringBuilder.append(middle.getCharacter()).append(OffsetFont.NEG_1.getCharacter());
|
||||
for (int i = 0; i < mid_amount; i++) {
|
||||
if (i == mid_amount / 2) stringBuilder.append("<#FDFEFE>").append(tail.getCharacter()).append("</#FDFEFE>").append(OffsetFont.NEG_1.getCharacter());
|
||||
else stringBuilder.append(middle.getCharacter()).append(OffsetFont.NEG_1.getCharacter());
|
||||
}
|
||||
stringBuilder.append(OffsetFont.getShortestNegChars(middle.getWidth() - (textWidth - 1 - tail.getWidth()) % middle.getWidth()));
|
||||
stringBuilder.append(middle.getCharacter()).append(OffsetFont.NEG_1.getCharacter());
|
||||
}
|
||||
stringBuilder.append("<#FDFEFE>");
|
||||
stringBuilder.append(right.getCharacter());
|
||||
stringBuilder.append("</#FDFEFE>");
|
||||
stringBuilder.append(OffsetFont.getShortestNegChars(textWidth + right.getWidth()));
|
||||
stringBuilder.append("</#FEFEFE>");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public String getSuffixWithFont(int textWidth) {
|
||||
return FontUtils.surroundNameplateFont(getSuffix(textWidth));
|
||||
}
|
||||
|
||||
public String getSuffix(int textWidth) {
|
||||
return OffsetFont.getShortestNegChars(textWidth + textWidth % 2 + 1);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final Bubble bubble;
|
||||
|
||||
public static Builder of() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder() {
|
||||
this.bubble = new Bubble();
|
||||
}
|
||||
|
||||
public Builder startFormat(String startFormat) {
|
||||
this.bubble.startFormat = startFormat;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder endFormat(String endFormat) {
|
||||
this.bubble.endFormat = endFormat;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder left(ConfiguredChar left) {
|
||||
this.bubble.left = left;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder displayName(String displayName) {
|
||||
this.bubble.displayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder middle(ConfiguredChar middle) {
|
||||
this.bubble.middle = middle;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder right(ConfiguredChar right) {
|
||||
this.bubble.right = right;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder tail(ConfiguredChar tail) {
|
||||
this.bubble.tail = tail;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Bubble build() {
|
||||
return bubble;
|
||||
}
|
||||
}
|
||||
|
||||
public String getStartFormat() {
|
||||
return startFormat;
|
||||
}
|
||||
|
||||
public String getEndFormat() {
|
||||
return endFormat;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public ConfiguredChar getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public ConfiguredChar getMiddle() {
|
||||
return middle;
|
||||
}
|
||||
|
||||
public ConfiguredChar getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public ConfiguredChar getTail() {
|
||||
return tail;
|
||||
}
|
||||
}
|
||||
-124
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.character;
|
||||
|
||||
import net.momirealms.customnameplates.api.util.LogUtils;
|
||||
|
||||
public class ConfiguredChar {
|
||||
|
||||
private char character;
|
||||
private String pngFile;
|
||||
private int height;
|
||||
private int width;
|
||||
private int ascent;
|
||||
|
||||
private ConfiguredChar() {
|
||||
|
||||
}
|
||||
|
||||
public ConfiguredChar(char character, String pngFile, int height, int width, int ascent) {
|
||||
this.character = character;
|
||||
this.pngFile = pngFile;
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
this.ascent = ascent;
|
||||
}
|
||||
|
||||
public char getCharacter() {
|
||||
return character;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public String getPngFile() {
|
||||
return pngFile;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getAscent() {
|
||||
return ascent;
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return pngFile + ".png";
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final ConfiguredChar configuredChar;
|
||||
|
||||
public static Builder of() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder() {
|
||||
this.configuredChar = new ConfiguredChar();
|
||||
}
|
||||
|
||||
public Builder character(char character) {
|
||||
configuredChar.character = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder png(String png) {
|
||||
configuredChar.pngFile = png;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder height(int height) {
|
||||
configuredChar.height = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder ascent(int ascent) {
|
||||
configuredChar.ascent = ascent;
|
||||
if (ascent >= configuredChar.height) {
|
||||
LogUtils.warn("Invalid config for " + configuredChar.pngFile);
|
||||
LogUtils.warn("Ascent " + ascent + " should be no higher than Height " + configuredChar.height);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder descent(int descent) {
|
||||
if (descent < 0) {
|
||||
LogUtils.warn("Invalid config for " + configuredChar.pngFile);
|
||||
LogUtils.warn("Descent " + descent + " should be no lower than 0");
|
||||
}
|
||||
configuredChar.ascent = configuredChar.height - descent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder width(int width) {
|
||||
configuredChar.width = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfiguredChar build() {
|
||||
return configuredChar;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.font;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class FontData {
|
||||
|
||||
private final HashMap<Integer, Integer> widthData;
|
||||
private final int defaultWidth;
|
||||
|
||||
public FontData(int defaultWidth) {
|
||||
this.widthData = new HashMap<>();
|
||||
this.defaultWidth = defaultWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a char's width
|
||||
*
|
||||
* @param codePoint code point
|
||||
* @param width width
|
||||
*/
|
||||
public void registerCharWidth(int codePoint, int width) {
|
||||
widthData.put(codePoint, width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a character's width
|
||||
*
|
||||
* @param codePoint code point
|
||||
* @return width
|
||||
*/
|
||||
public int getWidth(int codePoint) {
|
||||
return widthData.getOrDefault(codePoint, defaultWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data map
|
||||
*
|
||||
* @return map
|
||||
*/
|
||||
public HashMap<Integer, Integer> getWidthData() {
|
||||
return widthData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the data with another one
|
||||
*
|
||||
* @param fontData font data
|
||||
*/
|
||||
public void overrideWith(FontData fontData) {
|
||||
if (fontData == null) return;
|
||||
widthData.putAll(fontData.getWidthData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FontData{" +
|
||||
"widthData=" + widthData +
|
||||
", defaultWidth=" + defaultWidth +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.font;
|
||||
|
||||
public enum OffsetFont {
|
||||
|
||||
NEG_1('\uf801', -1, -3),
|
||||
NEG_2('\uf802', -2, -4),
|
||||
NEG_3('\uf803', -3, -5),
|
||||
NEG_4('\uf804', -4, -6),
|
||||
NEG_5('\uf805', -5, -7),
|
||||
NEG_6('\uf806', -6, -8),
|
||||
NEG_7('\uf807', -7, -9),
|
||||
NEG_8('\uf808', -8, -10),
|
||||
NEG_16('\uf809', -16, -18),
|
||||
NEG_32('\uf80a', -32, -34),
|
||||
NEG_64('\uf80b', -64, -66),
|
||||
NEG_128('\uf80c', -128, -130),
|
||||
POS_1('\uf811', 1, -1),
|
||||
POS_2('\uf812', 2, 1),
|
||||
POS_3('\uf813', 3, 2),
|
||||
POS_4('\uf814', 4, 3),
|
||||
POS_5('\uf815', 5, 4),
|
||||
POS_6('\uf816', 6, 5),
|
||||
POS_7('\uf817', 7, 6),
|
||||
POS_8('\uf818', 8, 7),
|
||||
POS_16('\uf819', 16, 15),
|
||||
POS_32('\uf81a', 32, 31),
|
||||
POS_64('\uf81b', 64, 63),
|
||||
POS_128('\uf81c', 128, 127);
|
||||
|
||||
private final char character;
|
||||
private final int space;
|
||||
private final int height;
|
||||
|
||||
OffsetFont(char character, int space, int height) {
|
||||
this.character = character;
|
||||
this.space = space;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public char getCharacter() {
|
||||
return this.character;
|
||||
}
|
||||
|
||||
public int getSpace() {
|
||||
return this.space;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get offset characters
|
||||
*
|
||||
* @param offset offset
|
||||
* @return chars
|
||||
*/
|
||||
public static String getOffsetChars(int offset) {
|
||||
if (offset >= 0) {
|
||||
return getShortestPosChars(offset);
|
||||
} else {
|
||||
return getShortestNegChars(-offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get negative characters
|
||||
*
|
||||
* @param n n > 0
|
||||
* @return chars
|
||||
*/
|
||||
public static String getShortestNegChars(int n) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
while (n >= 128) {
|
||||
stringBuilder.append(OffsetFont.NEG_128.getCharacter());
|
||||
n -= 128;
|
||||
}
|
||||
if (n - 64 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_64.getCharacter());
|
||||
n -= 64;
|
||||
}
|
||||
if (n - 32 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_32.getCharacter());
|
||||
n -= 32;
|
||||
}
|
||||
if (n - 16 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_16.getCharacter());
|
||||
n -= 16;
|
||||
}
|
||||
if (n - 8 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_8.getCharacter());
|
||||
n -= 8;
|
||||
}
|
||||
if (n - 7 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_7.getCharacter());
|
||||
n -= 7;
|
||||
}
|
||||
if (n - 6 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_6.getCharacter());
|
||||
n -= 6;
|
||||
}
|
||||
if (n - 5 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_5.getCharacter());
|
||||
n -= 5;
|
||||
}
|
||||
if (n - 4 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_4.getCharacter());
|
||||
n -= 4;
|
||||
}
|
||||
if (n - 3 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_3.getCharacter());
|
||||
n -= 3;
|
||||
}
|
||||
if (n - 2 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_2.getCharacter());
|
||||
n -= 2;
|
||||
}
|
||||
if (n - 1 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* get positive characters
|
||||
*
|
||||
* @param n n > 0
|
||||
* @return chars
|
||||
*/
|
||||
public static String getShortestPosChars(int n) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
while (n >= 128) {
|
||||
stringBuilder.append(OffsetFont.POS_128.getCharacter());
|
||||
n -= 128;
|
||||
}
|
||||
if (n - 64 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_64.getCharacter());
|
||||
n -= 64;
|
||||
}
|
||||
if (n - 32 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_32.getCharacter());
|
||||
n -= 32;
|
||||
}
|
||||
if (n - 16 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_16.getCharacter());
|
||||
n -= 16;
|
||||
}
|
||||
if (n - 8 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_8.getCharacter());
|
||||
n -= 8;
|
||||
}
|
||||
if (n - 7 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_7.getCharacter());
|
||||
n -= 7;
|
||||
}
|
||||
if (n - 6 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_6.getCharacter());
|
||||
n -= 6;
|
||||
}
|
||||
if (n - 5 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_5.getCharacter());
|
||||
n -= 5;
|
||||
}
|
||||
if (n - 4 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_4.getCharacter());
|
||||
n -= 4;
|
||||
}
|
||||
if (n - 3 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_3.getCharacter());
|
||||
n -= 3;
|
||||
}
|
||||
if (n - 2 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_2.getCharacter());
|
||||
n -= 2;
|
||||
}
|
||||
if (n - 1 >= 0) {
|
||||
stringBuilder.append(OffsetFont.POS_1.getCharacter());
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.misc;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.momirealms.customnameplates.api.CustomNameplatesPlugin;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ViewerText {
|
||||
|
||||
private final Player owner;
|
||||
private String processedText;
|
||||
private final ClaimedText[] placeholders;
|
||||
private final ConcurrentHashMap<UUID, String> valueMap;
|
||||
|
||||
public ViewerText(Player owner, String rawText) {
|
||||
this.processedText = rawText;
|
||||
this.valueMap = new ConcurrentHashMap<>();
|
||||
this.owner = owner;
|
||||
List<String> placeholders = CustomNameplatesPlugin.get().getPlaceholderManager().detectPlaceholders(rawText);
|
||||
this.placeholders = new ClaimedText[placeholders.size()];
|
||||
int i = 0;
|
||||
for (String placeholder : placeholders) {
|
||||
processedText = processedText.replace(placeholder, "%s");
|
||||
if (placeholder.startsWith("%viewer_")) {
|
||||
this.placeholders[i] = new ClaimedText(null, "%" + placeholder.substring("%viewer_".length()));
|
||||
} else {
|
||||
this.placeholders[i] = new ClaimedText(owner, placeholder);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateForOwner() {
|
||||
for (ClaimedText text : placeholders) {
|
||||
text.update();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean updateForViewer(Player viewer) {
|
||||
String string;
|
||||
if ("%s".equals(processedText)) {
|
||||
string = placeholders[0].getValue(viewer);
|
||||
} else if (placeholders.length != 0) {
|
||||
Object[] values = new String[placeholders.length];
|
||||
for (int i = 0; i < placeholders.length; i++) {
|
||||
values[i] = placeholders[i].getValue(viewer);
|
||||
}
|
||||
string = String.format(processedText, values);
|
||||
} else {
|
||||
string = processedText;
|
||||
}
|
||||
var uuid = viewer.getUniqueId();
|
||||
if (!valueMap.containsKey(uuid)) {
|
||||
valueMap.put(uuid, string);
|
||||
return true;
|
||||
}
|
||||
String previousValue = valueMap.get(uuid);
|
||||
if (!previousValue.equals(string)) {
|
||||
valueMap.put(uuid, string);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeViewer(Player viewer) {
|
||||
valueMap.remove(viewer.getUniqueId());
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
valueMap.clear();
|
||||
}
|
||||
|
||||
public String getProcessedText() {
|
||||
return processedText;
|
||||
}
|
||||
|
||||
public String getLatestValue(Player viewer) {
|
||||
return valueMap.get(viewer.getUniqueId());
|
||||
}
|
||||
|
||||
public Entity getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public static class ClaimedText {
|
||||
|
||||
private final String placeholder;
|
||||
private final Player owner;
|
||||
private String latestValue;
|
||||
|
||||
public ClaimedText(Player owner, String placeholder) {
|
||||
this.placeholder = placeholder;
|
||||
this.owner = owner;
|
||||
this.latestValue = null;
|
||||
this.update();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (owner == null) return;
|
||||
this.latestValue = PlaceholderAPI.setPlaceholders(owner, placeholder);
|
||||
}
|
||||
|
||||
public String getValue(Player viewer) {
|
||||
return Objects.requireNonNullElseGet(
|
||||
latestValue,
|
||||
() -> PlaceholderAPI.setPlaceholders(owner == null ? viewer : owner, placeholder)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.nameplate;
|
||||
|
||||
import net.momirealms.customnameplates.common.team.TeamColor;
|
||||
|
||||
public class CachedNameplate {
|
||||
|
||||
private TeamColor teamColor;
|
||||
private String tagPrefix;
|
||||
private String tagSuffix;
|
||||
private String namePrefix;
|
||||
private String nameSuffix;
|
||||
private String playerName;
|
||||
|
||||
public CachedNameplate() {
|
||||
this.tagPrefix = "";
|
||||
this.tagSuffix = "";
|
||||
this.namePrefix = "";
|
||||
this.nameSuffix = "";
|
||||
this.playerName = "";
|
||||
this.teamColor = TeamColor.WHITE;
|
||||
}
|
||||
|
||||
public String getTagPrefix() {
|
||||
return tagPrefix;
|
||||
}
|
||||
|
||||
public void setTagPrefix(String prefix) {
|
||||
this.tagPrefix = prefix;
|
||||
}
|
||||
|
||||
public String getTagSuffix() {
|
||||
return tagSuffix;
|
||||
}
|
||||
|
||||
public void setTagSuffix(String suffix) {
|
||||
this.tagSuffix = suffix;
|
||||
}
|
||||
|
||||
public void setNamePrefix(String namePrefix) {
|
||||
this.namePrefix = namePrefix;
|
||||
}
|
||||
|
||||
public void setNameSuffix(String nameSuffix) {
|
||||
this.nameSuffix = nameSuffix;
|
||||
}
|
||||
|
||||
public String getNamePrefix() {
|
||||
return namePrefix;
|
||||
}
|
||||
|
||||
public String getNameSuffix() {
|
||||
return nameSuffix;
|
||||
}
|
||||
|
||||
public TeamColor getTeamColor() {
|
||||
return teamColor;
|
||||
}
|
||||
|
||||
public void setTeamColor(TeamColor teamColor) {
|
||||
this.teamColor = teamColor;
|
||||
}
|
||||
|
||||
public String getPlayerName() {
|
||||
return playerName;
|
||||
}
|
||||
|
||||
public void setPlayerName(String playerName) {
|
||||
this.playerName = playerName;
|
||||
}
|
||||
}
|
||||
-187
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.nameplate;
|
||||
|
||||
import net.momirealms.customnameplates.api.mechanic.character.ConfiguredChar;
|
||||
import net.momirealms.customnameplates.api.mechanic.font.OffsetFont;
|
||||
import net.momirealms.customnameplates.api.util.FontUtils;
|
||||
import net.momirealms.customnameplates.common.team.TeamColor;
|
||||
|
||||
public class Nameplate {
|
||||
|
||||
private String displayName;
|
||||
private TeamColor teamColor;
|
||||
private String namePrefix;
|
||||
private String nameSuffix;
|
||||
private ConfiguredChar left;
|
||||
private ConfiguredChar middle;
|
||||
private ConfiguredChar right;
|
||||
|
||||
private Nameplate() {
|
||||
}
|
||||
|
||||
public Nameplate(
|
||||
String displayName,
|
||||
TeamColor teamColor,
|
||||
String namePrefix,
|
||||
String nameSuffix,
|
||||
ConfiguredChar left,
|
||||
ConfiguredChar middle,
|
||||
ConfiguredChar right
|
||||
) {
|
||||
this.displayName = displayName;
|
||||
this.teamColor = teamColor;
|
||||
this.left = left;
|
||||
this.middle = middle;
|
||||
this.right = right;
|
||||
this.namePrefix = namePrefix;
|
||||
this.nameSuffix = nameSuffix;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public TeamColor getTeamColor() {
|
||||
return teamColor;
|
||||
}
|
||||
|
||||
public ConfiguredChar getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public ConfiguredChar getMiddle() {
|
||||
return middle;
|
||||
}
|
||||
|
||||
public ConfiguredChar getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public String getNamePrefix() {
|
||||
if (teamColor == TeamColor.NONE) {
|
||||
return "";
|
||||
}
|
||||
if (teamColor == TeamColor.CUSTOM) {
|
||||
return namePrefix;
|
||||
}
|
||||
return "<" + teamColor.name() + ">";
|
||||
}
|
||||
|
||||
public String getNameSuffix() {
|
||||
if (teamColor == TeamColor.NONE) {
|
||||
return "";
|
||||
}
|
||||
if (teamColor == TeamColor.CUSTOM) {
|
||||
return nameSuffix;
|
||||
}
|
||||
return "</" + teamColor.name() + ">";
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public String getPrefixWithFont(int textWidth) {
|
||||
return FontUtils.surroundNameplateFont(getPrefix(textWidth));
|
||||
}
|
||||
|
||||
public String getPrefix(int textWidth) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("<#FEFEFE>");
|
||||
stringBuilder.append(OffsetFont.getShortestNegChars(textWidth + left.getWidth() + 1));
|
||||
stringBuilder.append(left.getCharacter());
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
int mid_amount = (textWidth+2) / (middle.getWidth());
|
||||
if (mid_amount != 0) {
|
||||
for (int i = 0; i < mid_amount; i++) {
|
||||
stringBuilder.append(middle.getCharacter());
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
}
|
||||
stringBuilder.append(OffsetFont.getShortestNegChars(middle.getWidth() - (textWidth+2) % middle.getWidth() + 1)); // +1
|
||||
}
|
||||
stringBuilder.append("</#FEFEFE>");
|
||||
stringBuilder.append("<#FDFEFE>");
|
||||
stringBuilder.append(middle.getCharacter());
|
||||
stringBuilder.append(OffsetFont.NEG_1.getCharacter());
|
||||
stringBuilder.append(right.getCharacter());
|
||||
stringBuilder.append(OffsetFont.getShortestNegChars(textWidth + right.getWidth() + 1)); // -1;
|
||||
stringBuilder.append("</#FDFEFE>");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public String getSuffixWithFont(int textWidth) {
|
||||
return FontUtils.surroundNameplateFont(getSuffix(textWidth));
|
||||
}
|
||||
|
||||
public String getSuffix(int textWidth) {
|
||||
return OffsetFont.getShortestNegChars(textWidth + textWidth % 2 + 1);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final Nameplate nameplate;
|
||||
|
||||
public Builder() {
|
||||
this.nameplate = new Nameplate();
|
||||
}
|
||||
|
||||
public static Builder of() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder displayName(String display) {
|
||||
nameplate.displayName = display;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder teamColor(TeamColor teamColor) {
|
||||
nameplate.teamColor = teamColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder namePrefix(String namePrefix) {
|
||||
nameplate.namePrefix = namePrefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder nameSuffix(String nameSuffix) {
|
||||
nameplate.nameSuffix = nameSuffix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder left(ConfiguredChar configuredChar) {
|
||||
nameplate.left = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder middle(ConfiguredChar configuredChar) {
|
||||
nameplate.middle = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder right(ConfiguredChar configuredChar) {
|
||||
nameplate.right = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Nameplate build() {
|
||||
return nameplate;
|
||||
}
|
||||
}
|
||||
}
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.placeholder;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.momirealms.customnameplates.api.mechanic.background.BackGround;
|
||||
import net.momirealms.customnameplates.api.util.FontUtils;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class BackGroundText {
|
||||
|
||||
private String text;
|
||||
private BackGround backGround;
|
||||
private boolean removeShadow;
|
||||
|
||||
private BackGroundText() {
|
||||
}
|
||||
|
||||
public BackGroundText(String text, BackGround backGround, boolean removeShadow) {
|
||||
this.text = text;
|
||||
this.backGround = backGround;
|
||||
this.removeShadow = removeShadow;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public BackGround getBackGround() {
|
||||
return backGround;
|
||||
}
|
||||
|
||||
public String getValue(OfflinePlayer player) {
|
||||
String parsed = PlaceholderAPI.setPlaceholders(player, text);
|
||||
if (parsed.equals("")) return "";
|
||||
int parsedWidth = FontUtils.getTextWidth(parsed);
|
||||
String bg = FontUtils.surroundNameplateFont(backGround.getBackGroundImage(parsedWidth));
|
||||
return (removeShadow ? "<#FFFEFD>" + bg + "</#FFFEFD>" : bg)+ parsed;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final BackGroundText text;
|
||||
|
||||
public Builder() {
|
||||
this.text = new BackGroundText();
|
||||
}
|
||||
|
||||
public static Builder of() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder text(String value) {
|
||||
text.text = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder background(BackGround backGround) {
|
||||
text.backGround = backGround;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder removeShadow(boolean remove) {
|
||||
text.removeShadow = remove;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BackGroundText build() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.placeholder;
|
||||
|
||||
public class CachedText {
|
||||
|
||||
private long refreshInterval;
|
||||
private String text;
|
||||
|
||||
private CachedText() {
|
||||
}
|
||||
|
||||
public CachedText(long refreshInterval, String text) {
|
||||
this.refreshInterval = refreshInterval;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public long getRefreshInterval() {
|
||||
return refreshInterval;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final CachedText text;
|
||||
|
||||
public Builder() {
|
||||
this.text = new CachedText();
|
||||
}
|
||||
|
||||
public static Builder of() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder refreshInterval(long time) {
|
||||
this.text.refreshInterval = time;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder text(String text) {
|
||||
this.text.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CachedText build() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.placeholder;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.momirealms.customnameplates.api.manager.RequirementManager;
|
||||
import net.momirealms.customnameplates.api.requirement.Condition;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
import net.momirealms.customnameplates.common.Pair;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionalText {
|
||||
|
||||
private List<Pair<String, Requirement[]>> textList;
|
||||
|
||||
private ConditionalText() {
|
||||
}
|
||||
|
||||
public ConditionalText(List<Pair<String, Requirement[]>> textList) {
|
||||
this.textList = textList;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public String getValue(OfflinePlayer player) {
|
||||
Condition condition = new Condition(player);
|
||||
for (Pair<String, Requirement[]> pair : textList) {
|
||||
if (RequirementManager.isRequirementMet(condition, pair.right())) {
|
||||
return PlaceholderAPI.setPlaceholders(player, pair.left());
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final ConditionalText conditionalText;
|
||||
|
||||
public static Builder of() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder() {
|
||||
this.conditionalText = new ConditionalText();
|
||||
}
|
||||
|
||||
public Builder textList(List<Pair<String, Requirement[]>> textList) {
|
||||
conditionalText.textList = textList;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConditionalText build() {
|
||||
return conditionalText;
|
||||
}
|
||||
}
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.api.mechanic.placeholder;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.momirealms.customnameplates.api.util.FontUtils;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class DescentText {
|
||||
|
||||
private int ascent;
|
||||
private String text;
|
||||
private boolean isUnicode;
|
||||
|
||||
public DescentText(int ascent, String text, boolean isUnicode) {
|
||||
this.ascent = ascent;
|
||||
this.text = text;
|
||||
this.isUnicode = isUnicode;
|
||||
}
|
||||
|
||||
private DescentText() {
|
||||
|
||||
}
|
||||
|
||||
public int getAscent() {
|
||||
return ascent;
|
||||
}
|
||||
|
||||
public boolean isUnicode() {
|
||||
return isUnicode;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public String getValue(OfflinePlayer player) {
|
||||
var parsed = PlaceholderAPI.setPlaceholders(player, text);
|
||||
return FontUtils.surroundAscentFont(parsed, ascent);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final DescentText descentText;
|
||||
|
||||
public static Builder of() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder() {
|
||||
this.descentText = new DescentText();
|
||||
}
|
||||
|
||||
public Builder ascent(int ascent) {
|
||||
descentText.ascent = ascent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder descent(int descent) {
|
||||
descentText.ascent = 8 - descent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder text(String text) {
|
||||
descentText.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder unicode(boolean unicode) {
|
||||
descentText.isUnicode = unicode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DescentText build() {
|
||||
return descentText;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 934 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user