mirror of
https://github.com/Xiao-MoMi/Custom-Nameplates.git
synced 2026-11-06 01:12:38 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
No files matched your search
@@ -23,6 +23,8 @@ dependencies {
|
||||
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 {
|
||||
|
||||
@@ -17,8 +17,15 @@
|
||||
|
||||
package net.momirealms.customnameplates.api;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenCustomHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.feature.Feature;
|
||||
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;
|
||||
@@ -35,7 +42,9 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
|
||||
protected final CustomNameplates plugin;
|
||||
protected final Object player;
|
||||
protected final Channel channel;
|
||||
|
||||
protected Object player;
|
||||
|
||||
private boolean isLoaded = false;
|
||||
|
||||
@@ -45,11 +54,13 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
private String equippedNameplate;
|
||||
private String equippedBubble;
|
||||
|
||||
private final Map<Integer, TimeStampData<String>> cachedValues = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, WeakHashMap<CNPlayer, TimeStampData<String>>> cachedRelationalValues = new ConcurrentHashMap<>();
|
||||
private final TeamView teamView = new TeamView();
|
||||
|
||||
private final Map<Requirement, TimeStampData<Boolean>> cachedRequirements = new ConcurrentHashMap<>();
|
||||
private final Map<Requirement, WeakHashMap<CNPlayer, TimeStampData<Boolean>>> cachedRelationalRequirements = new ConcurrentHashMap<>();
|
||||
private final Int2ObjectOpenHashMap<TimeStampData<String>> cachedValues = new Int2ObjectOpenHashMap<>(64);
|
||||
private final Int2ObjectOpenHashMap<WeakHashMap<CNPlayer, TimeStampData<String>>> cachedRelationalValues = new Int2ObjectOpenHashMap<>(64);
|
||||
|
||||
private final Int2ObjectOpenHashMap<TimeStampData<Boolean>> cachedRequirements = new Int2ObjectOpenHashMap<>(128);
|
||||
private final Int2ObjectOpenHashMap<WeakHashMap<CNPlayer, TimeStampData<Boolean>>> cachedRelationalRequirements = new Int2ObjectOpenHashMap<>(128);
|
||||
|
||||
private final Set<Feature> activeFeatures = new CopyOnWriteArraySet<>();
|
||||
private final Map<Placeholder, Set<Feature>> placeholder2Features = new ConcurrentHashMap<>();
|
||||
@@ -57,15 +68,15 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
|
||||
private final Map<CNPlayer, Tracker> trackers = Collections.synchronizedMap(new WeakHashMap<>());
|
||||
|
||||
protected AbstractCNPlayer(CustomNameplates plugin, Object player) {
|
||||
protected AbstractCNPlayer(CustomNameplates plugin, Channel channel) {
|
||||
this.plugin = plugin;
|
||||
this.player = player;
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Placeholder> activePlaceholdersToRefresh() {
|
||||
Placeholder[] activePlaceholders = activePlaceholders();
|
||||
List<Placeholder> placeholderWithChildren = new ArrayList<>();
|
||||
List<Placeholder> placeholderWithChildren = new ObjectArrayList<>();
|
||||
for (Placeholder placeholder : activePlaceholders) {
|
||||
childrenFirstList(placeholder, placeholderWithChildren);
|
||||
}
|
||||
@@ -73,9 +84,9 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forceUpdatePlaceholders(Set<Placeholder> placeholders, Set<CNPlayer> others) {
|
||||
public void forceUpdatePlaceholders(Set<Placeholder> placeholders, Collection<CNPlayer> others) {
|
||||
if (placeholders.isEmpty()) return;
|
||||
List<Placeholder> placeholderWithChildren = new ArrayList<>();
|
||||
List<Placeholder> placeholderWithChildren = new ObjectArrayList<>();
|
||||
for (Placeholder placeholder : placeholders) {
|
||||
childrenFirstList(placeholder, placeholderWithChildren);
|
||||
}
|
||||
@@ -166,6 +177,15 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
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());
|
||||
@@ -209,7 +229,7 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
Set<Placeholder> allPlaceholders = feature.allPlaceholders();
|
||||
feature2Placeholders.put(feature, allPlaceholders);
|
||||
for (Placeholder placeholder : allPlaceholders) {
|
||||
Set<Feature> featureSet = placeholder2Features.computeIfAbsent(placeholder, k -> new HashSet<>());
|
||||
Set<Feature> featureSet = placeholder2Features.computeIfAbsent(placeholder, k -> new ObjectOpenHashSet<>());
|
||||
featureSet.add(feature);
|
||||
}
|
||||
}
|
||||
@@ -315,7 +335,7 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
|
||||
@Override
|
||||
public Placeholder[] activePlaceholders() {
|
||||
HashSet<Placeholder> placeholders = new HashSet<>();
|
||||
Set<Placeholder> placeholders = new ObjectOpenHashSet<>();
|
||||
for (Feature feature : activeFeatures) {
|
||||
placeholders.addAll(feature.activePlaceholders());
|
||||
}
|
||||
@@ -326,7 +346,7 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
public boolean isMet(Requirement[] requirements) {
|
||||
int currentTicks = MainTask.getTicks();
|
||||
for (Requirement requirement : requirements) {
|
||||
TimeStampData<Boolean> data = cachedRequirements.get(requirement);
|
||||
TimeStampData<Boolean> data = cachedRequirements.get(requirement.countId());
|
||||
if (data != null) {
|
||||
if (data.ticks() + requirement.refreshInterval() > currentTicks) {
|
||||
if (!data.data()) {
|
||||
@@ -343,7 +363,7 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
} else {
|
||||
boolean satisfied = requirement.isSatisfied(this, this);
|
||||
data = new TimeStampData<>(satisfied, currentTicks, true);
|
||||
cachedRequirements.put(requirement, data);
|
||||
cachedRequirements.put(requirement.countId(), data);
|
||||
if (!satisfied) {
|
||||
return false;
|
||||
}
|
||||
@@ -356,7 +376,7 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
public boolean isMet(CNPlayer another, Requirement[] requirements) {
|
||||
int currentTicks = MainTask.getTicks();
|
||||
for (Requirement requirement : requirements) {
|
||||
WeakHashMap<CNPlayer, TimeStampData<Boolean>> innerMap = cachedRelationalRequirements.computeIfAbsent(requirement, k -> new WeakHashMap<>());
|
||||
WeakHashMap<CNPlayer, TimeStampData<Boolean>> innerMap = cachedRelationalRequirements.computeIfAbsent(requirement.countId(), k -> new WeakHashMap<>());
|
||||
TimeStampData<Boolean> data = innerMap.get(another);
|
||||
if (data != null) {
|
||||
if (data.ticks() + requirement.refreshInterval() > currentTicks) {
|
||||
@@ -406,8 +426,8 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CNPlayer> nearbyPlayers() {
|
||||
return new HashSet<>(trackers.keySet());
|
||||
public Collection<CNPlayer> nearbyPlayers() {
|
||||
return new ObjectArrayList<>(trackers.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -431,7 +451,7 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
|
||||
@Override
|
||||
public Set<Integer> getTrackedPassengerIds(CNPlayer another) {
|
||||
return Optional.ofNullable(trackers.get(another)).map(Tracker::getPassengerIDs).orElse(new HashSet<>());
|
||||
return Optional.ofNullable(trackers.get(another)).map(Tracker::getPassengerIDs).orElse(new ObjectOpenHashSet<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -479,6 +499,11 @@ public abstract class AbstractCNPlayer implements CNPlayer {
|
||||
.build(), plugin.getScheduler().async());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamView teamView() {
|
||||
return teamView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) return true;
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
|
||||
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.requirement.Requirement;
|
||||
@@ -26,6 +28,7 @@ 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;
|
||||
@@ -53,6 +56,13 @@ public interface CNPlayer {
|
||||
*/
|
||||
Object player();
|
||||
|
||||
/**
|
||||
* Returns the channel of the player
|
||||
*
|
||||
* @return the channel
|
||||
*/
|
||||
Channel channel();
|
||||
|
||||
/**
|
||||
* Returns the entity ID of the player.
|
||||
*
|
||||
@@ -181,7 +191,7 @@ public interface CNPlayer {
|
||||
* @param placeholders the placeholders to update
|
||||
* @param another the players related to the placeholders
|
||||
*/
|
||||
void forceUpdatePlaceholders(Set<Placeholder> placeholders, Set<CNPlayer> another);
|
||||
void forceUpdatePlaceholders(Set<Placeholder> placeholders, Collection<CNPlayer> another);
|
||||
|
||||
/**
|
||||
* Retrieves the cached data for a given placeholder.
|
||||
@@ -308,7 +318,7 @@ public interface CNPlayer {
|
||||
*
|
||||
* @return the set of nearby players
|
||||
*/
|
||||
Set<CNPlayer> nearbyPlayers();
|
||||
Collection<CNPlayer> nearbyPlayers();
|
||||
|
||||
/**
|
||||
* Adds passenger entities to the tracker for another player.
|
||||
@@ -385,4 +395,11 @@ public interface CNPlayer {
|
||||
* Save the player's current nameplate/bubble to database
|
||||
*/
|
||||
void save();
|
||||
|
||||
/**
|
||||
* Get the player's team view
|
||||
*
|
||||
* @return team view
|
||||
*/
|
||||
TeamView teamView();
|
||||
}
|
||||
@@ -67,10 +67,12 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
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;
|
||||
@@ -100,6 +102,7 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
protected boolean packItemsAdder;
|
||||
protected boolean packItemsAdderLegacy;
|
||||
protected boolean packOraxen;
|
||||
protected boolean packCreativeCentral;
|
||||
|
||||
protected boolean chatUnsafe;
|
||||
protected boolean chatTR;
|
||||
@@ -177,6 +180,7 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
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");
|
||||
|
||||
chatUnsafe = config.getBoolean("other-settings.unsafe-chat-event", false);
|
||||
chatEss = config.getBoolean("integrations.chat.Essentials", false);
|
||||
@@ -216,6 +220,8 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
defaultConditionRefreshInterval = config.getInt("other-settings.ddefault-condition-refresh-interval", 1);
|
||||
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
|
||||
@@ -267,6 +273,10 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
return instance.initialChar;
|
||||
}
|
||||
|
||||
public static boolean hideTeamNames() {
|
||||
return instance.hideTeamNames;
|
||||
}
|
||||
|
||||
public static boolean actionbarModule() {
|
||||
return instance.actionbarModule;
|
||||
}
|
||||
@@ -279,6 +289,10 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
return instance.catchOtherActionBar;
|
||||
}
|
||||
|
||||
public static boolean displaySystemChat() {
|
||||
return instance.displaySystemChat;
|
||||
}
|
||||
|
||||
public static boolean packItemsAdder() {
|
||||
return instance.packItemsAdder;
|
||||
}
|
||||
@@ -291,6 +305,8 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
return instance.packOraxen;
|
||||
}
|
||||
|
||||
public static boolean packCreativeCentral() { return instance.packCreativeCentral; }
|
||||
|
||||
public static boolean hideScoreBoardNumber() {
|
||||
return instance.hideScoreBoardNumber;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
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;
|
||||
@@ -38,10 +40,7 @@ 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.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
@@ -69,7 +68,7 @@ public abstract class CustomNameplates implements NameplatesPlugin {
|
||||
protected MainTask mainTask;
|
||||
protected SchedulerTask scheduledMainTask;
|
||||
protected ConcurrentHashMap<UUID, CNPlayer> onlinePlayerMap = new ConcurrentHashMap<>();
|
||||
protected HashMap<Integer, CNPlayer> entityIDFastLookup = new HashMap<>();
|
||||
protected Int2ObjectOpenHashMap<CNPlayer> entityIDFastLookup = new Int2ObjectOpenHashMap<>();
|
||||
protected AdvanceManager advanceManager;
|
||||
protected BackgroundManager backgroundManager;
|
||||
protected EventManager eventManager;
|
||||
@@ -288,7 +287,7 @@ public abstract class CustomNameplates implements NameplatesPlugin {
|
||||
* @return a collection of {@link CNPlayer} instances
|
||||
*/
|
||||
public Collection<CNPlayer> getOnlinePlayers() {
|
||||
return new HashSet<>(onlinePlayerMap.values());
|
||||
return new ObjectArrayList<>(onlinePlayerMap.values());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package net.momirealms.customnameplates.api;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@@ -29,7 +31,7 @@ public class MainTask implements Runnable {
|
||||
|
||||
private static final Map<Integer, Integer> TIME_1 = new ConcurrentHashMap<>(2048);
|
||||
private static final Map<Integer, Integer> TIME_2 = new ConcurrentHashMap<>(2048);
|
||||
private static final Set<Integer> requestedSharedPlaceholders = Collections.synchronizedSet(new HashSet<>());
|
||||
private static final Set<Integer> requestedSharedPlaceholders = Collections.synchronizedSet(new ObjectOpenHashSet<>());
|
||||
private int timer;
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
|
||||
@@ -20,7 +20,7 @@ package net.momirealms.customnameplates.api.feature;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
|
||||
/**
|
||||
* Listener for handling player change worlds
|
||||
* Listener for handling player actions
|
||||
*/
|
||||
public interface PlayerListener {
|
||||
|
||||
|
||||
+7
-5
@@ -17,6 +17,8 @@
|
||||
|
||||
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.*;
|
||||
@@ -27,8 +29,8 @@ import java.util.function.Function;
|
||||
public class PreParsedDynamicText {
|
||||
|
||||
private final String text;
|
||||
private final List<Function<CNPlayer, Function<CNPlayer, String>>> textFunctions = new ArrayList<>();
|
||||
private final Set<Placeholder> set = new HashSet<>();
|
||||
private final List<Function<CNPlayer, Function<CNPlayer, String>>> textFunctions = new ObjectArrayList<>();
|
||||
private final Set<Placeholder> set = new ObjectOpenHashSet<>();
|
||||
private boolean init = false;
|
||||
|
||||
public PreParsedDynamicText(String text) {
|
||||
@@ -86,12 +88,12 @@ public class PreParsedDynamicText {
|
||||
String remaining = original0.substring(lastIndex);
|
||||
textFunctions.add((owner) -> (viewer) -> remaining);
|
||||
}
|
||||
// To optimize the tree height, call new HashSet twice here
|
||||
set.addAll(new HashSet<>(placeholders));
|
||||
// To optimize the tree height
|
||||
set.addAll(new ObjectArrayList<>(placeholders));
|
||||
}
|
||||
|
||||
public DynamicText fastCreate(CNPlayer player) {
|
||||
List<Function<CNPlayer, String>> functions = new ArrayList<>();
|
||||
List<Function<CNPlayer, String>> functions = new ObjectArrayList<>();
|
||||
for (Function<CNPlayer, Function<CNPlayer, String>> textFunction : textFunctions) {
|
||||
functions.add(textFunction.apply(player));
|
||||
}
|
||||
|
||||
+4
-3
@@ -18,6 +18,7 @@
|
||||
package net.momirealms.customnameplates.api.feature.advance;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -28,11 +29,11 @@ import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class CharacterFontAdvanceDataImpl implements CharacterFontAdvanceData {
|
||||
|
||||
private final HashMap<Integer, Float> data;
|
||||
private final Map<Integer, Float> data;
|
||||
private final String id;
|
||||
private final Function<Map<String, Object>, List<JsonObject>> fontProviderFunction;
|
||||
|
||||
public CharacterFontAdvanceDataImpl(String id, HashMap<Integer, Float> data, Function<Map<String, Object>, List<JsonObject>> fontProviderFunction) {
|
||||
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);
|
||||
@@ -65,7 +66,7 @@ public class CharacterFontAdvanceDataImpl implements CharacterFontAdvanceData {
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private final HashMap<Integer, Float> data = new HashMap<>();
|
||||
private final Int2FloatOpenHashMap data = new Int2FloatOpenHashMap();
|
||||
private String id;
|
||||
private Function<Map<String, Object>, List<JsonObject>> fontProviderFunction = (stringObjectMap -> null);
|
||||
|
||||
|
||||
+6
-6
@@ -17,18 +17,18 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.feature.advance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class ConfigurableFontAdvanceDataImpl implements ConfigurableFontAdvanceData {
|
||||
|
||||
private final float defaultAdvance;
|
||||
private final HashMap<Integer, Float> data = new HashMap<>();
|
||||
private final List<CharacterFontAdvanceData> parents = new ArrayList<>();
|
||||
private final Map<Integer, Float> data = new Int2FloatOpenHashMap();
|
||||
private final List<CharacterFontAdvanceData> parents = new ObjectArrayList<>();
|
||||
private final String id;
|
||||
|
||||
public ConfigurableFontAdvanceDataImpl(String id, float defaultAdvance, HashMap<Integer, Float> customData, List<CharacterFontAdvanceData> parentFonts) {
|
||||
|
||||
+38
-35
@@ -119,47 +119,48 @@ public class BackgroundImpl implements Background {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createImagePrefix(float n, float leftMargin, float rightMargin) {
|
||||
String offset1 = OffsetFont.shortestNegChars(n + rightMargin + right.advance());
|
||||
n = leftMargin + n + rightMargin;
|
||||
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 (n >= 128) {
|
||||
while (advance >= 128) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_128.character());
|
||||
n -= 128;
|
||||
advance -= 128;
|
||||
}
|
||||
if (n - 64 >= 0) {
|
||||
if (advance - 64 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_64.character());
|
||||
n -= 64;
|
||||
advance -= 64;
|
||||
}
|
||||
if (n - 32 >= 0) {
|
||||
if (advance - 32 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_32.character());
|
||||
n -= 32;
|
||||
advance -= 32;
|
||||
}
|
||||
if (n - 16 >= 0) {
|
||||
if (advance - 16 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_16.character());
|
||||
n -= 16;
|
||||
advance -= 16;
|
||||
}
|
||||
if (n - 8 >= 0) {
|
||||
if (advance - 8 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_8.character());
|
||||
n -= 8;
|
||||
advance -= 8;
|
||||
}
|
||||
if (n - 4 >= 0) {
|
||||
if (advance - 4 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_4.character());
|
||||
n -= 4;
|
||||
advance -= 4;
|
||||
}
|
||||
if (n - 2 >= 0) {
|
||||
if (advance - 2 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_2.character());
|
||||
n -= 2;
|
||||
advance -= 2;
|
||||
}
|
||||
if (n - 1 >= 0) {
|
||||
if (advance - 1 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_1.character());
|
||||
}
|
||||
@@ -171,50 +172,52 @@ public class BackgroundImpl implements Background {
|
||||
|
||||
@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 n, float leftMargin, float rightMargin) {
|
||||
n = n + leftMargin + rightMargin + 2;
|
||||
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 (n >= 128) {
|
||||
while (advance >= 128) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_128.character());
|
||||
n -= 128;
|
||||
advance -= 128;
|
||||
}
|
||||
if (n - 64 >= 0) {
|
||||
if (advance - 64 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_64.character());
|
||||
n -= 64;
|
||||
advance -= 64;
|
||||
}
|
||||
if (n - 32 >= 0) {
|
||||
if (advance - 32 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_32.character());
|
||||
n -= 32;
|
||||
advance -= 32;
|
||||
}
|
||||
if (n - 16 >= 0) {
|
||||
if (advance - 16 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_16.character());
|
||||
n -= 16;
|
||||
advance -= 16;
|
||||
}
|
||||
if (n - 8 >= 0) {
|
||||
if (advance - 8 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_8.character());
|
||||
n -= 8;
|
||||
advance -= 8;
|
||||
}
|
||||
if (n - 4 >= 0) {
|
||||
if (advance - 4 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_4.character());
|
||||
n -= 4;
|
||||
advance -= 4;
|
||||
}
|
||||
if (n - 2 >= 0) {
|
||||
if (advance - 2 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_2.character());
|
||||
n -= 2;
|
||||
advance -= 2;
|
||||
}
|
||||
if (n - 1 >= 0) {
|
||||
if (advance - 1 >= 0) {
|
||||
stringBuilder.append(OffsetFont.NEG_1.character());
|
||||
stringBuilder.append(width_1.character());
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ public class BubbleImpl implements Bubble {
|
||||
@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());
|
||||
@@ -110,6 +111,7 @@ public class BubbleImpl implements Bubble {
|
||||
|
||||
@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);
|
||||
@@ -122,6 +124,7 @@ public class BubbleImpl implements Bubble {
|
||||
@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());
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public record Animation(int speed, int frames) {
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
package net.momirealms.customnameplates.api.feature.image;
|
||||
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface Image {
|
||||
|
||||
@@ -33,15 +34,15 @@ public interface Image {
|
||||
*
|
||||
* @return true if the image has a shadow, false otherwise
|
||||
*/
|
||||
boolean hasShadow();
|
||||
boolean removeShadow();
|
||||
|
||||
/**
|
||||
* Returns the opacity level of the image.
|
||||
* The value should typically range from 0 (fully transparent) to 255 (fully opaque).
|
||||
* Get the animation of the image
|
||||
*
|
||||
* @return the opacity value of the image
|
||||
* @return the animated image
|
||||
*/
|
||||
int opacity();
|
||||
@Nullable
|
||||
Animation animation();
|
||||
|
||||
/**
|
||||
* Returns the configured character associated with this image.
|
||||
@@ -73,20 +74,20 @@ public interface Image {
|
||||
Builder id(String id);
|
||||
|
||||
/**
|
||||
* Sets whether the image has a shadow effect.
|
||||
* Sets whether to remove the shadow of the image
|
||||
*
|
||||
* @param has true if the image should have a shadow, false otherwise
|
||||
* @param remove true if to remove the shadow
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder hasShadow(boolean has);
|
||||
Builder removeShadow(boolean remove);
|
||||
|
||||
/**
|
||||
* Sets the opacity level of the image.
|
||||
* Sets the animation of the image
|
||||
*
|
||||
* @param opacity the opacity value, typically from 0 to 255
|
||||
* @param animation animation
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder opacity(int opacity);
|
||||
Builder animation(@Nullable Animation animation);
|
||||
|
||||
/**
|
||||
* Sets the configured character associated with this image.
|
||||
|
||||
+17
-16
@@ -18,21 +18,22 @@
|
||||
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 hasShadow;
|
||||
private final int opacity;
|
||||
private final boolean removeShadow;
|
||||
private final ConfiguredCharacter character;
|
||||
private final Animation animation;
|
||||
|
||||
public ImageImpl(String id, boolean hasShadow, int opacity, ConfiguredCharacter character) {
|
||||
public ImageImpl(String id, boolean removeShadow, Animation animation, ConfiguredCharacter character) {
|
||||
this.id = id;
|
||||
this.hasShadow = hasShadow;
|
||||
this.opacity = opacity;
|
||||
this.removeShadow = removeShadow;
|
||||
this.character = character;
|
||||
this.animation = animation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,13 +42,13 @@ public class ImageImpl implements Image {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasShadow() {
|
||||
return hasShadow;
|
||||
public boolean removeShadow() {
|
||||
return removeShadow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int opacity() {
|
||||
return opacity;
|
||||
public @Nullable Animation animation() {
|
||||
return animation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,9 +72,9 @@ public class ImageImpl implements Image {
|
||||
public static class BuilderImpl implements Builder {
|
||||
|
||||
private String id;
|
||||
private boolean hasShadow;
|
||||
private int opacity;
|
||||
private boolean removeShadow;
|
||||
private ConfiguredCharacter character;
|
||||
private Animation animation;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
@@ -82,14 +83,14 @@ public class ImageImpl implements Image {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder hasShadow(boolean has) {
|
||||
this.hasShadow = has;
|
||||
public Builder removeShadow(boolean removeShadow) {
|
||||
this.removeShadow = removeShadow;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder opacity(int opacity) {
|
||||
this.opacity = opacity;
|
||||
public Builder animation(@Nullable Animation animation) {
|
||||
this.animation = animation;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -101,7 +102,7 @@ public class ImageImpl implements Image {
|
||||
|
||||
@Override
|
||||
public Image build() {
|
||||
return new ImageImpl(id, hasShadow, opacity, character);
|
||||
return new ImageImpl(id, removeShadow, animation, character);
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -57,6 +57,13 @@ public interface Nameplate extends AdaptiveImage {
|
||||
*/
|
||||
ConfiguredCharacter right();
|
||||
|
||||
/**
|
||||
* Gets the min width of the nameplate
|
||||
*
|
||||
* @return the min width of the nameplate
|
||||
*/
|
||||
int minWidth();
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing a Nameplate configuration.
|
||||
*
|
||||
@@ -87,6 +94,14 @@ public interface Nameplate extends AdaptiveImage {
|
||||
*/
|
||||
Builder displayName(String displayName);
|
||||
|
||||
/**
|
||||
* Sets the min width for the nameplate
|
||||
*
|
||||
* @param minWidth min width
|
||||
* @return the builder instance
|
||||
*/
|
||||
Builder minWidth(int minWidth);
|
||||
|
||||
/**
|
||||
* Sets the configured character for the left side of the nameplate.
|
||||
*
|
||||
|
||||
+22
-2
@@ -29,10 +29,12 @@ public class NameplateImpl implements Nameplate {
|
||||
private final ConfiguredCharacter left;
|
||||
private final ConfiguredCharacter middle;
|
||||
private final ConfiguredCharacter right;
|
||||
private final int minWidth;
|
||||
|
||||
public NameplateImpl(String id, String displayName, ConfiguredCharacter left, ConfiguredCharacter middle, ConfiguredCharacter right) {
|
||||
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;
|
||||
@@ -63,6 +65,11 @@ public class NameplateImpl implements Nameplate {
|
||||
return right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int minWidth() {
|
||||
return minWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) return true;
|
||||
@@ -79,6 +86,8 @@ public class NameplateImpl implements Nameplate {
|
||||
@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());
|
||||
@@ -97,6 +106,8 @@ public class NameplateImpl implements Nameplate {
|
||||
|
||||
@Override
|
||||
public String createImageSuffix(float advance, float leftMargin, float rightMargin) {
|
||||
if (advance <= 0) return "";
|
||||
advance = Math.max(minWidth, advance);
|
||||
int mid_amount = (int) Math.ceil((advance + leftMargin + rightMargin) / (middle.advance() - 1));
|
||||
float exceed = mid_amount * (middle.advance() - 1) - advance - leftMargin - rightMargin;
|
||||
return OffsetFont.shortestPosChars((float) Math.ceil(exceed / 2) + rightMargin + right.advance());
|
||||
@@ -105,6 +116,8 @@ public class NameplateImpl implements Nameplate {
|
||||
@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());
|
||||
@@ -128,6 +141,7 @@ public class NameplateImpl implements Nameplate {
|
||||
private ConfiguredCharacter left;
|
||||
private ConfiguredCharacter middle;
|
||||
private ConfiguredCharacter right;
|
||||
private int minWidth;
|
||||
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
@@ -141,6 +155,12 @@ public class NameplateImpl implements Nameplate {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder minWidth(int minWidth) {
|
||||
this.minWidth = minWidth;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder left(ConfiguredCharacter left) {
|
||||
this.left = left;
|
||||
@@ -161,7 +181,7 @@ public class NameplateImpl implements Nameplate {
|
||||
|
||||
@Override
|
||||
public Nameplate build() {
|
||||
return new NameplateImpl(id, displayName, left, middle, right);
|
||||
return new NameplateImpl(id, displayName, minWidth, left, middle, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.*;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -299,7 +299,7 @@ public class AdventureHelper {
|
||||
case 'd' -> stringBuilder.append("<light_purple>");
|
||||
case 'e' -> stringBuilder.append("<yellow>");
|
||||
case 'f' -> stringBuilder.append("<white>");
|
||||
case 'r' -> stringBuilder.append("<r><!i>");
|
||||
case 'r' -> stringBuilder.append("<reset>");
|
||||
case 'l' -> stringBuilder.append("<b>");
|
||||
case 'm' -> stringBuilder.append("<st>");
|
||||
case 'o' -> stringBuilder.append("<i>");
|
||||
|
||||
@@ -90,6 +90,10 @@ public class VersionHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isVersionNewerThan1_21_2() {
|
||||
return version >= 21.19;
|
||||
}
|
||||
|
||||
public static boolean isVersionNewerThan1_20_5() {
|
||||
return version >= 20.49;
|
||||
}
|
||||
|
||||
+16
-15
@@ -20,19 +20,33 @@ package net.momirealms.customnameplates.api.network;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
* Interface for injecting and managing Netty pipeline handlers for players.
|
||||
*/
|
||||
public interface PipelineInjector {
|
||||
|
||||
@ApiStatus.Internal
|
||||
void setUser(Channel channel, CNPlayer user);
|
||||
|
||||
@ApiStatus.Internal
|
||||
CNPlayer getUser(Channel channel);
|
||||
|
||||
@ApiStatus.Internal
|
||||
CNPlayer removeUser(Channel channel);
|
||||
|
||||
@ApiStatus.Internal
|
||||
CNPlayer getUser(Object player);
|
||||
|
||||
/**
|
||||
* Retrieves the Netty channel associated with the specified player.
|
||||
*
|
||||
* @param player the player whose channel is being retrieved
|
||||
* @return the Netty channel associated with the player
|
||||
*/
|
||||
Channel getChannel(CNPlayer player);
|
||||
@ApiStatus.Internal
|
||||
Channel getChannel(Object player);
|
||||
|
||||
/**
|
||||
* Creates a custom ChannelDuplexHandler for the specified player, used to intercept and modify network traffic.
|
||||
@@ -40,19 +54,6 @@ public interface PipelineInjector {
|
||||
* @param player the player for whom the handler is being created
|
||||
* @return a ChannelDuplexHandler for the player
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
ChannelDuplexHandler createHandler(CNPlayer player);
|
||||
|
||||
/**
|
||||
* Injects a custom handler into the player's network channel, allowing interception and modification of packets.
|
||||
*
|
||||
* @param player the player whose channel will be injected
|
||||
*/
|
||||
void inject(CNPlayer player);
|
||||
|
||||
/**
|
||||
* Removes the custom handler from the player's network channel.
|
||||
*
|
||||
* @param player the player whose channel will have the handler removed
|
||||
*/
|
||||
void uninject(CNPlayer player);
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.network;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -80,7 +81,7 @@ public class Tracker {
|
||||
}
|
||||
|
||||
public Set<Integer> getPassengerIDs() {
|
||||
return new HashSet<>(passengerIDs);
|
||||
return new ObjectOpenHashSet<>(passengerIDs);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
|
||||
+21
-2
@@ -17,6 +17,9 @@
|
||||
|
||||
package net.momirealms.customnameplates.api.placeholder;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
@@ -27,8 +30,8 @@ public abstract class AbstractPlaceholder implements Placeholder {
|
||||
protected int countId = PlaceholderCounter.getAndIncrease();
|
||||
protected int refreshInterval;
|
||||
protected PlaceholderManager manager;
|
||||
protected Set<Placeholder> children = new HashSet<>();
|
||||
protected Set<Placeholder> parents = new HashSet<>();
|
||||
protected Set<Placeholder> children = new ObjectOpenHashSet<>();
|
||||
protected Set<Placeholder> parents = new ObjectOpenHashSet<>();
|
||||
|
||||
protected AbstractPlaceholder(PlaceholderManager manager, String id, int refreshInterval) {
|
||||
if (refreshInterval == 0) {
|
||||
@@ -54,21 +57,37 @@ public abstract class AbstractPlaceholder implements Placeholder {
|
||||
|
||||
@Override
|
||||
public void addChild(Placeholder placeholder) {
|
||||
if (placeholder == this) {
|
||||
CustomNameplates.getInstance().getPluginLogger().warn(String.format("There may be something wrong with your configuration. Placeholder relationship level loops. Placeholder %s becomes its own child Placeholder", id));
|
||||
return;
|
||||
}
|
||||
children.add(placeholder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChildren(Set<Placeholder> placeholders) {
|
||||
if (placeholders.contains(this)) {
|
||||
CustomNameplates.getInstance().getPluginLogger().warn(String.format("There may be something wrong with your configuration. Placeholder relationship level loops. Placeholder %s becomes its own child Placeholder", id));
|
||||
return;
|
||||
}
|
||||
children.addAll(placeholders);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addParent(Placeholder placeholder) {
|
||||
if (placeholder == this) {
|
||||
CustomNameplates.getInstance().getPluginLogger().warn(String.format("There may be something wrong with your configuration. Placeholder relationship level loops. Placeholder %s becomes its own parent Placeholder", id));
|
||||
return;
|
||||
}
|
||||
parents.add(placeholder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addParents(Set<Placeholder> placeholders) {
|
||||
if (placeholders.contains(this)) {
|
||||
CustomNameplates.getInstance().getPluginLogger().warn(String.format("There may be something wrong with your configuration. Placeholder relationship level loops. Placeholder %s becomes its own parent Placeholder", id));
|
||||
return;
|
||||
}
|
||||
parents.addAll(placeholders);
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -18,6 +18,7 @@
|
||||
package net.momirealms.customnameplates.api.requirement;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
|
||||
/**
|
||||
* A requirement that is always satisfied, representing an "empty" or default requirement.
|
||||
@@ -57,6 +58,11 @@ public class EmptyRequirement implements Requirement {
|
||||
return "empty";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countId() {
|
||||
return CustomNameplates.getInstance().getRequirementManager().countId(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns -1, indicating that this requirement does not have a refresh interval.
|
||||
*
|
||||
|
||||
@@ -40,6 +40,13 @@ public interface Requirement {
|
||||
*/
|
||||
String type();
|
||||
|
||||
/**
|
||||
* Returns the int id for faster lookup
|
||||
*
|
||||
* @return count id
|
||||
*/
|
||||
int countId();
|
||||
|
||||
/**
|
||||
* Returns the refresh interval of the requirement.
|
||||
*
|
||||
|
||||
+8
@@ -87,4 +87,12 @@ public interface RequirementManager extends Reloadable {
|
||||
*/
|
||||
@NotNull
|
||||
Requirement parseSimpleRequirement(@NotNull String type, @NotNull Object value);
|
||||
|
||||
/**
|
||||
* Gets the count id for the requirement for faster lookup
|
||||
*
|
||||
* @param requirement requirement
|
||||
* @return the id
|
||||
*/
|
||||
int countId(Requirement requirement);
|
||||
}
|
||||
@@ -26,4 +26,6 @@ dependencies {
|
||||
// TTF
|
||||
compileOnly("org.lwjgl:lwjgl-freetype:${rootProject.properties["lwjgl_version"]}")
|
||||
compileOnly("org.lwjgl:lwjgl:${rootProject.properties["lwjgl_version"]}")
|
||||
// Fast util
|
||||
compileOnly("it.unimi.dsi:fastutil:${rootProject.properties["fastutil_version"]}")
|
||||
}
|
||||
+8
@@ -100,10 +100,18 @@ public class ActionBarManagerImpl implements ActionBarManager, JoinQuitListener
|
||||
public void handleActionBarPacket(CNPlayer player, String miniMessage) {
|
||||
ActionBarSender sender = senders.get(player.uuid());
|
||||
if (sender != null) {
|
||||
if (miniMessage.length() >= 1024) return;
|
||||
sender.externalActionBar(miniMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public void temporarilyHideCustomActionBar(CNPlayer player) {
|
||||
ActionBarSender sender = senders.get(player.uuid());
|
||||
if (sender != null) {
|
||||
sender.temporarilyHide();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getExternalActionBar(CNPlayer player) {
|
||||
ActionBarSender sender = senders.get(player.uuid());
|
||||
|
||||
+14
-2
@@ -17,6 +17,7 @@
|
||||
|
||||
package net.momirealms.customnameplates.backend.feature.actionbar;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
@@ -49,6 +50,7 @@ public class ActionBarSender implements Feature {
|
||||
|
||||
private String externalActionBar;
|
||||
private long externalExpireTime;
|
||||
private long temporaryHiddenTime;
|
||||
|
||||
private String latestContent;
|
||||
|
||||
@@ -156,9 +158,10 @@ public class ActionBarSender implements Feature {
|
||||
}
|
||||
|
||||
public void sendLatestActionBar() {
|
||||
if (isTemporarilyHidden()) return;
|
||||
if (latestContent != null) {
|
||||
updateLastUpdateTime();
|
||||
Object packet = CustomNameplates.getInstance().getPlatform().setActionBarTextPacket(AdventureHelper.miniMessageToMinecraftComponent(latestContent, "np", "ab"));
|
||||
Object packet = CustomNameplates.getInstance().getPlatform().setActionBarTextPacket(AdventureHelper.miniMessageToMinecraftComponent(latestContent, "nameplates", "actionbar"));
|
||||
CustomNameplates.getInstance().getPacketSender().sendPacket(owner, packet);
|
||||
}
|
||||
}
|
||||
@@ -175,7 +178,7 @@ public class ActionBarSender implements Feature {
|
||||
|
||||
@Override
|
||||
public Set<Placeholder> allPlaceholders() {
|
||||
HashSet<Placeholder> placeholders = new HashSet<>();
|
||||
Set<Placeholder> placeholders = new ObjectOpenHashSet<>();
|
||||
for (ActionBarConfig config : manager.actionBarConfigs()) {
|
||||
for (CarouselText text : config.carouselTexts()) {
|
||||
placeholders.addAll(text.preParsedDynamicText().placeholders());
|
||||
@@ -214,4 +217,13 @@ public class ActionBarSender implements Feature {
|
||||
this.externalActionBar = externalActionBar;
|
||||
this.externalExpireTime = System.currentTimeMillis() + ConfigManager.otherActionBarStayTime();
|
||||
}
|
||||
|
||||
public void temporarilyHide() {
|
||||
this.temporaryHiddenTime = System.currentTimeMillis() + 3000;
|
||||
}
|
||||
|
||||
public boolean isTemporarilyHidden() {
|
||||
if (!ConfigManager.displaySystemChat()) return false;
|
||||
return temporaryHiddenTime > System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
+5
-8
@@ -25,6 +25,8 @@ import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
@@ -292,8 +294,8 @@ public class AdvanceManagerImpl implements AdvanceManager {
|
||||
private final HashMap<String, BiConsumer<String, Section>> templateConfigConsumersMap = new HashMap<>();
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
private final HashMap<String, CharacterFontAdvanceData> charFontWidthDataMap = new HashMap<>();
|
||||
private final HashMap<String, ConfigurableFontAdvanceData> configFontWidthDataMap = new HashMap<>();
|
||||
private final Object2ObjectOpenHashMap<String, CharacterFontAdvanceData> charFontWidthDataMap = new Object2ObjectOpenHashMap<>();
|
||||
private final Object2ObjectOpenHashMap<String, ConfigurableFontAdvanceData> configFontWidthDataMap = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
private final Cache<String, Float> textWidthCache;
|
||||
|
||||
@@ -787,11 +789,6 @@ public class AdvanceManagerImpl implements AdvanceManager {
|
||||
plugin.getPluginLogger().warn(ttf.getAbsolutePath() + " is not a .ttf");
|
||||
return;
|
||||
}
|
||||
if (true) {
|
||||
plugin.getPluginLogger().info("We're currently unable to obtain TTF advance");
|
||||
plugin.getPluginLogger().info("If you have Java knowledge and are interested in this, consider contributing if you have any progress.");
|
||||
return;
|
||||
}
|
||||
try (InputStream inputStream = new FileInputStream(ttf)) {
|
||||
ByteBuffer byteBuffer = null;
|
||||
FT_Face fT_Face = null;
|
||||
@@ -1225,7 +1222,7 @@ public class AdvanceManagerImpl implements AdvanceManager {
|
||||
public List<Tuple<String, Key, Boolean>> miniMessageToIterable(String text) {
|
||||
if (AdventureHelper.legacySupport) text = AdventureHelper.legacyToMiniMessage(text);
|
||||
ElementNode node = (ElementNode) AdventureHelper.miniMessage().deserializeToTree(text);
|
||||
ArrayList<Tuple<String, Key, Boolean>> iterableTexts = new ArrayList<>();
|
||||
List<Tuple<String, Key, Boolean>> iterableTexts = new ObjectArrayList<>();
|
||||
nodeToIterableTexts(node, iterableTexts, MINECRAFT_DEFAULT_FONT, false);
|
||||
return iterableTexts;
|
||||
}
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@
|
||||
package net.momirealms.customnameplates.backend.feature.background;
|
||||
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
@@ -57,7 +58,7 @@ public class BackgroundManagerImpl implements BackgroundManager {
|
||||
|
||||
@Override
|
||||
public Collection<Background> getBackgrounds() {
|
||||
return new HashSet<>(backgrounds.values());
|
||||
return new ObjectArrayList<>(backgrounds.values());
|
||||
}
|
||||
|
||||
private void loadConfigs() {
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@
|
||||
|
||||
package net.momirealms.customnameplates.backend.feature.bossbar;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.feature.CarouselText;
|
||||
@@ -163,7 +164,7 @@ public class BossBarSender implements Feature, BossBar {
|
||||
|
||||
@Override
|
||||
public Set<Placeholder> allPlaceholders() {
|
||||
HashSet<Placeholder> placeholders = new HashSet<>();
|
||||
Set<Placeholder> placeholders = new ObjectOpenHashSet<>();
|
||||
for (CarouselText text : config.carouselTexts()) {
|
||||
placeholders.addAll(text.preParsedDynamicText().placeholders());
|
||||
}
|
||||
|
||||
+8
-5
@@ -27,6 +27,8 @@ 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 it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
@@ -51,7 +53,7 @@ import java.util.concurrent.TimeUnit;
|
||||
public class BubbleManagerImpl implements BubbleManager, ChatListener {
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
private final Map<String, Bubble> bubbles = new HashMap<>();
|
||||
private final Map<String, Bubble> bubbles = new Object2ObjectOpenHashMap<>();
|
||||
private Requirement[] sendBubbleRequirements;
|
||||
private Requirement[] viewBubbleRequirements;
|
||||
private String defaultBubbleId;
|
||||
@@ -62,7 +64,7 @@ public class BubbleManagerImpl implements BubbleManager, ChatListener {
|
||||
private float viewRange;
|
||||
private Set<String> blacklistChannels;
|
||||
private ChannelMode channelMode;
|
||||
private final HashMap<String, BubbleConfig> bubbleConfigs = new HashMap<>();
|
||||
private final Map<String, BubbleConfig> bubbleConfigs = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
public BubbleManagerImpl(CustomNameplates plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -94,12 +96,12 @@ public class BubbleManagerImpl implements BubbleManager, ChatListener {
|
||||
|
||||
@Override
|
||||
public Collection<Bubble> bubbles() {
|
||||
return new HashSet<>(bubbles.values());
|
||||
return new ObjectArrayList<>(bubbles.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<BubbleConfig> bubbleConfigs() {
|
||||
return new HashSet<>(bubbleConfigs.values());
|
||||
return new ObjectArrayList<>(bubbleConfigs.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -231,7 +233,7 @@ public class BubbleManagerImpl implements BubbleManager, ChatListener {
|
||||
.displayName(inner.getString("display-name", key))
|
||||
.lineWidth(inner.getInt("line-width", 100))
|
||||
.backgroundColor(ConfigUtils.argb(inner.getString("background-color", "0,0,0,0")))
|
||||
.textPrefix(inner.getString("text-prefix", ""))
|
||||
.textPrefix(inner.getString("text-prefix", "").replace("{namespace}", ConfigManager.namespace()))
|
||||
.textSuffix(inner.getString("text-suffix", ""))
|
||||
.scale(ConfigUtils.vector3(inner.getString("scale", "1,1,1")))
|
||||
.build());
|
||||
@@ -305,6 +307,7 @@ public class BubbleManagerImpl implements BubbleManager, ChatListener {
|
||||
String fullText = config.textPrefix() + AdventureHelper.stripTags(message.replace("\\", "\\\\")) + config.textSuffix();
|
||||
int lines = plugin.getAdvanceManager().getLines(fullText, config.lineWidth());
|
||||
if (lines > config.maxLines()) return;
|
||||
if (lines <= 0) return;
|
||||
int space = (int) plugin.getAdvanceManager().getLineAdvance(" ");
|
||||
String fakeSpace = AdventureHelper.surroundWithNameplatesFont(OffsetFont.createOffsets(space));
|
||||
fullText = fullText.replace(" ", fakeSpace);
|
||||
|
||||
+8
-3
@@ -18,9 +18,11 @@
|
||||
package net.momirealms.customnameplates.backend.feature.image;
|
||||
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.feature.ConfiguredCharacter;
|
||||
import net.momirealms.customnameplates.api.feature.image.Animation;
|
||||
import net.momirealms.customnameplates.api.feature.image.Image;
|
||||
import net.momirealms.customnameplates.api.feature.image.ImageManager;
|
||||
import net.momirealms.customnameplates.api.util.ConfigUtils;
|
||||
@@ -59,7 +61,7 @@ public class ImageManagerImpl implements ImageManager {
|
||||
|
||||
@Override
|
||||
public Collection<Image> images() {
|
||||
return new HashSet<>(images.values());
|
||||
return new ObjectArrayList<>(images.values());
|
||||
}
|
||||
|
||||
private void loadConfigs() {
|
||||
@@ -73,8 +75,11 @@ public class ImageManagerImpl implements ImageManager {
|
||||
String id = configFile.getName().substring(0, configFile.getName().lastIndexOf("."));
|
||||
Image image = Image.builder()
|
||||
.id(id)
|
||||
.hasShadow(!config.getBoolean("shadow.remove", false))
|
||||
.opacity(config.getInt("shadow.opacity", 254))
|
||||
.animation(config.contains("animation") ? new Animation(
|
||||
config.getInt("animation.speed", 64),
|
||||
config.getInt("animation.frames", 1)
|
||||
) : null)
|
||||
.removeShadow(!config.getBoolean("shadow", true))
|
||||
.character(ConfiguredCharacter.create(
|
||||
ConfigUtils.getFileInTheSameFolder(configFile, config.getString("image") + ".png"),
|
||||
config.getInt("ascent", 8),
|
||||
|
||||
+3
-1
@@ -18,6 +18,7 @@
|
||||
package net.momirealms.customnameplates.backend.feature.nameplate;
|
||||
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
@@ -61,7 +62,7 @@ public class NameplateManagerImpl implements NameplateManager {
|
||||
|
||||
@Override
|
||||
public Collection<Nameplate> nameplates() {
|
||||
return new HashSet<>(nameplates.values());
|
||||
return new ObjectArrayList<>(nameplates.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,6 +116,7 @@ public class NameplateManagerImpl implements NameplateManager {
|
||||
Nameplate nameplate = Nameplate.builder()
|
||||
.id(id)
|
||||
.displayName(config.getString("display-name", id))
|
||||
.minWidth(config.getInt("min-width", 0))
|
||||
.left(ConfiguredCharacter.create(
|
||||
ConfigUtils.getFileInTheSameFolder(configFile, config.getString("left.image") + ".png"),
|
||||
config.getInt("left.ascent", 12),
|
||||
|
||||
+76
-8
@@ -29,6 +29,7 @@ import net.momirealms.customnameplates.api.feature.OffsetFont;
|
||||
import net.momirealms.customnameplates.api.feature.advance.CharacterFontAdvanceData;
|
||||
import net.momirealms.customnameplates.api.feature.background.Background;
|
||||
import net.momirealms.customnameplates.api.feature.bubble.Bubble;
|
||||
import net.momirealms.customnameplates.api.feature.image.Animation;
|
||||
import net.momirealms.customnameplates.api.feature.image.Image;
|
||||
import net.momirealms.customnameplates.api.feature.nameplate.Nameplate;
|
||||
import net.momirealms.customnameplates.api.feature.pack.ResourcePackManager;
|
||||
@@ -70,10 +71,18 @@ public class ResourcePackManagerImpl implements ResourcePackManager {
|
||||
this.saveLegacyUnicodes();
|
||||
|
||||
if (ConfigManager.enableShader()) {
|
||||
if (!VersionHelper.isVersionNewerThan1_20_5()) {
|
||||
this.generateShaders("ResourcePack" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, false);
|
||||
this.generateShaders("ResourcePack" + File.separator + "overlay_1_20_5" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
|
||||
} else {
|
||||
if (VersionHelper.isVersionNewerThan1_21_2()) {
|
||||
this.generateShaders("ResourcePack" + File.separator + "overlay_1_21_2" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
|
||||
try {
|
||||
FileUtils.copyDirectory(
|
||||
new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "overlay_1_21_2"),
|
||||
new File(plugin.getDataFolder(), "ResourcePack")
|
||||
);
|
||||
FileUtils.deleteDirectory(new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "overlay_1_21_2"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else if (VersionHelper.isVersionNewerThan1_20_5()) {
|
||||
this.generateShaders("ResourcePack" + File.separator + "overlay_1_20_5" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
|
||||
try {
|
||||
FileUtils.copyDirectory(
|
||||
@@ -84,6 +93,11 @@ public class ResourcePackManagerImpl implements ResourcePackManager {
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.generateShaders("ResourcePack" + File.separator + "overlay_1_21_2" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
|
||||
} else {
|
||||
this.generateShaders("ResourcePack" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, false);
|
||||
this.generateShaders("ResourcePack" + File.separator + "overlay_1_20_5" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
|
||||
this.generateShaders("ResourcePack" + File.separator + "overlay_1_21_2" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +188,11 @@ public class ResourcePackManagerImpl implements ResourcePackManager {
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
private void setPackFormat() {
|
||||
if (VersionHelper.isVersionNewerThan1_20_5()) {
|
||||
if (VersionHelper.isVersionNewerThan1_21_2()) {
|
||||
plugin.getConfigManager().saveResource("ResourcePack" + File.separator + "pack_1_21_2.mcmeta");
|
||||
File file = new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "pack_1_21_2.mcmeta");
|
||||
file.renameTo(new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "pack.mcmeta"));
|
||||
} else if (VersionHelper.isVersionNewerThan1_20_5()) {
|
||||
plugin.getConfigManager().saveResource("ResourcePack" + File.separator + "pack_1_20_5.mcmeta");
|
||||
File file = new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "pack_1_20_5.mcmeta");
|
||||
file.renameTo(new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "pack.mcmeta"));
|
||||
@@ -218,6 +236,13 @@ public class ResourcePackManagerImpl implements ResourcePackManager {
|
||||
plugin.getPluginLogger().warn("Failed to copy files to Oraxen", e);
|
||||
}
|
||||
}
|
||||
if(ConfigManager.packCreativeCentral()) {
|
||||
try {
|
||||
FileUtils.copyDirectory(new File(resourcePackFolder, "assets"), new File(pluginsFolder, "creative-central" + File.separator + "resources" + File.separator + "assets"));
|
||||
} catch (IOException e){
|
||||
plugin.getPluginLogger().warn("Failed to copy files to Creative-Central", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<JsonObject> getBubbles(File texturesFolder) {
|
||||
@@ -297,11 +322,53 @@ public class ResourcePackManagerImpl implements ResourcePackManager {
|
||||
jo.add("chars", ja);
|
||||
list.add(jo);
|
||||
try {
|
||||
File targetFile = new File(texturesFolder,
|
||||
ConfigManager.imagePath().replace("\\", File.separator) + character.imageFile().getName());
|
||||
FileUtils.copyFile(
|
||||
new File(plugin.getDataFolder(),
|
||||
"contents" + File.separator + "images" + File.separator + character.imageFile().getName()),
|
||||
new File(texturesFolder,
|
||||
ConfigManager.imagePath().replace("\\", File.separator) + character.imageFile().getName()));
|
||||
"contents" + File.separator + "images" + File.separator + character.imageFile().getName()), targetFile);
|
||||
if (image.removeShadow() || image.animation() != null) {
|
||||
BufferedImage bufferedImage = ImageIO.read(targetFile);
|
||||
if (image.removeShadow()) {
|
||||
for (int y = 0; y < bufferedImage.getHeight(); y++) {
|
||||
for (int x = 0; x < bufferedImage.getWidth(); x++) {
|
||||
int argb = bufferedImage.getRGB(x, y);
|
||||
int alpha = (argb >> 24) & 0xff;
|
||||
if (alpha != 0) {
|
||||
int rgb = argb & 0x00ffffff;
|
||||
int newArgb = (254 << 24) | rgb;
|
||||
bufferedImage.setRGB(x, y, newArgb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Animation animation = image.animation();
|
||||
if (animation != null) {
|
||||
int height = bufferedImage.getHeight();
|
||||
int extra = height % animation.frames();
|
||||
if (extra > 0) {
|
||||
plugin.getPluginLogger().warn("Image height is not a multiple of frame rate: " + image.id());
|
||||
continue;
|
||||
}
|
||||
int eachFrameHeight = height / animation.frames();
|
||||
int width = bufferedImage.getWidth();
|
||||
int speed = Math.min(Math.max(animation.speed(), 1), 255);
|
||||
|
||||
int alpha = 1;
|
||||
int red = speed;
|
||||
int green = width;
|
||||
int blue = eachFrameHeight;
|
||||
int argb = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
||||
|
||||
for (int i = 0; i < animation.frames(); i++) {
|
||||
int y = i * eachFrameHeight;
|
||||
bufferedImage.setRGB(0, y, argb);
|
||||
}
|
||||
}
|
||||
|
||||
ImageIO.write(bufferedImage, "png", targetFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -559,6 +626,7 @@ public class ResourcePackManagerImpl implements ResourcePackManager {
|
||||
" vertexColor = ((.6 + .6 * cos(6. * (gl_Position.x + GameTime * 1000.) + vec4(0, 23, 21, 1))) + vec4(0., 0., 0., 1.)) * texelFetch(Sampler2, UV2 / 16, 0);\n" +
|
||||
" gl_Position = ProjMat * ModelViewMat * vertex;\n" +
|
||||
" } else ";
|
||||
|
||||
public static final String Hide_ScoreBoard_Numbers =
|
||||
"\n" +
|
||||
" if (Position.z == 0.0\n" +
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@
|
||||
|
||||
package net.momirealms.customnameplates.backend.feature.tag;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.feature.CarouselText;
|
||||
@@ -195,7 +196,7 @@ public class NameTag extends AbstractTag implements RelationalFeature {
|
||||
|
||||
@Override
|
||||
public Set<Placeholder> allPlaceholders() {
|
||||
HashSet<Placeholder> placeholders = new HashSet<>();
|
||||
Set<Placeholder> placeholders = new ObjectOpenHashSet<>();
|
||||
for (CarouselText text : config.carouselTexts()) {
|
||||
placeholders.addAll(text.preParsedDynamicText().placeholders());
|
||||
}
|
||||
|
||||
+7
-5
@@ -17,6 +17,7 @@
|
||||
|
||||
package net.momirealms.customnameplates.backend.feature.tag;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.feature.Feature;
|
||||
@@ -69,14 +70,15 @@ public class TagRendererImpl implements TagRenderer {
|
||||
|
||||
@Override
|
||||
public void onTick() {
|
||||
HashSet<CNPlayer> playersToUpdatePassengers = new HashSet<>();
|
||||
HashSet<CNPlayer> tagTranslationUpdates = new HashSet<>();
|
||||
Set<CNPlayer> playersToUpdatePassengers = new ObjectOpenHashSet<>();
|
||||
Set<CNPlayer> tagTranslationUpdates = new ObjectOpenHashSet<>();
|
||||
|
||||
Collection<CNPlayer> nearbyPlayers = owner.nearbyPlayers();
|
||||
for (Tag tag : tagArray) {
|
||||
boolean canShow = tag.canShow();
|
||||
if (canShow) {
|
||||
if (tag.isShown()) {
|
||||
for (CNPlayer nearby : owner.nearbyPlayers()) {
|
||||
for (CNPlayer nearby : nearbyPlayers) {
|
||||
if (tag.isShown(nearby)) {
|
||||
if (!tag.canShow(nearby)) {
|
||||
tag.hide(nearby);
|
||||
@@ -97,7 +99,7 @@ public class TagRendererImpl implements TagRenderer {
|
||||
tag.init();
|
||||
tag.tick();
|
||||
tag.show();
|
||||
for (CNPlayer nearby : owner.nearbyPlayers()) {
|
||||
for (CNPlayer nearby : nearbyPlayers) {
|
||||
if (tag.canShow(nearby) && !tag.isShown(nearby)) {
|
||||
tag.show(nearby);
|
||||
playersToUpdatePassengers.add(nearby);
|
||||
@@ -110,7 +112,7 @@ public class TagRendererImpl implements TagRenderer {
|
||||
if (tag.isShown()) {
|
||||
tag.hide();
|
||||
if (!tag.relativeTranslation())
|
||||
tagTranslationUpdates.addAll(owner.nearbyPlayers());
|
||||
tagTranslationUpdates.addAll(nearbyPlayers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -105,12 +105,12 @@ public class UnlimitedTagManagerImpl implements UnlimitedTagManager, JoinQuitLis
|
||||
|
||||
@Override
|
||||
public void onChangeWorld(CNPlayer player) {
|
||||
plugin.getScheduler().async().execute(() -> {
|
||||
plugin.getScheduler().asyncLater(() -> {
|
||||
if (player.isOnline() && (player.isTempPreviewing() || player.isToggleablePreviewing())) {
|
||||
onRemovePlayer(player, player);
|
||||
onAddPlayer(player, player);
|
||||
}
|
||||
});
|
||||
}, VersionHelper.isFolia() ? 500 : 50, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,7 +120,7 @@ public class UnlimitedTagManagerImpl implements UnlimitedTagManager, JoinQuitLis
|
||||
onRemovePlayer(player, player);
|
||||
onAddPlayer(player, player);
|
||||
}
|
||||
}, 50, TimeUnit.MILLISECONDS);
|
||||
}, VersionHelper.isFolia() ? 500 : 50, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,7 +130,7 @@ public class UnlimitedTagManagerImpl implements UnlimitedTagManager, JoinQuitLis
|
||||
onRemovePlayer(player, player);
|
||||
onAddPlayer(player, player);
|
||||
}
|
||||
}, 50, TimeUnit.MILLISECONDS);
|
||||
}, VersionHelper.isFolia() ? 500 : 50, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -148,6 +148,8 @@ public class UnlimitedTagManagerImpl implements UnlimitedTagManager, JoinQuitLis
|
||||
}
|
||||
if (isAlwaysShow()) {
|
||||
setTempPreviewing(player, isAlwaysShow());
|
||||
} else if (player.isLoaded() && player.isTempPreviewing()) {
|
||||
setTempPreviewing(player, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-10
@@ -19,6 +19,10 @@ package net.momirealms.customnameplates.backend.placeholder;
|
||||
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
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.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
@@ -51,7 +55,7 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
private final HashMap<String, Integer> refreshIntervals = new HashMap<>();
|
||||
private final HashMap<Integer, Integer> fasterRefreshIntervals = new HashMap<>();
|
||||
private final Int2IntOpenHashMap fasterRefreshIntervals = new Int2IntOpenHashMap();
|
||||
private final Map<String, Placeholder> registeredPlaceholders = new HashMap<>();
|
||||
private final HashMap<Placeholder, List<PreParsedDynamicText>> childrenText = new HashMap<>();
|
||||
private final HashMap<String, Placeholder> nestedPlaceholders = new HashMap<>();
|
||||
@@ -201,7 +205,7 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
this.registerPlayerPlaceholder("%np_gradient_" + i + "%", (player) -> {
|
||||
int currentTicks = MainTask.getTicks();
|
||||
double progress = currentTicks * 0.01 * speed;
|
||||
return String.format("%.2f", -1 + (progress % 2.0001));
|
||||
return String.format(Locale.US, "%.2f", -1 + (progress % 2.0001));
|
||||
});
|
||||
}
|
||||
for (int i = 1; i <= 20; i++) {
|
||||
@@ -209,9 +213,11 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
this.registerSharedPlaceholder("%shared_np_gradient_" + i + "%", () -> {
|
||||
int currentTicks = MainTask.getTicks();
|
||||
double progress = currentTicks * 0.01 * speed;
|
||||
return String.format("%.2f", -1 + (progress % 2.0001));
|
||||
return String.format(Locale.US, "%.2f", -1 + (progress % 2.0001));
|
||||
});
|
||||
}
|
||||
this.registerPlayerPlaceholder("%np_is_showing%", (player) -> String.valueOf(player.isToggleablePreviewing()));
|
||||
this.registerPlayerPlaceholder("%np_is_previewing%", (player) -> String.valueOf(player.isTempPreviewing()));
|
||||
this.registerPlayerPlaceholder("%np_time%", (player) -> {
|
||||
long time = player.playerTime() % 24_000;
|
||||
String ap = time >= 6000 && time < 18000 ? " PM" : " AM";
|
||||
@@ -573,9 +579,9 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
public void refreshPlaceholders() {
|
||||
for (CNPlayer player : plugin.getOnlinePlayers()) {
|
||||
if (!player.isOnline()) continue;
|
||||
Set<Feature> featuresToNotifyUpdates = new HashSet<>();
|
||||
Map<Feature, List<CNPlayer>> relationalFeaturesToNotifyUpdates = new HashMap<>();
|
||||
List<RelationalPlaceholder> delayedPlaceholdersToUpdate = new ArrayList<>();
|
||||
Set<Feature> featuresToNotifyUpdates = new ObjectOpenHashSet<>();
|
||||
Map<Feature, List<CNPlayer>> relationalFeaturesToNotifyUpdates = new Object2ObjectOpenHashMap<>();
|
||||
List<RelationalPlaceholder> delayedPlaceholdersToUpdate = new ObjectArrayList<>();
|
||||
for (Placeholder placeholder : player.activePlaceholdersToRefresh()) {
|
||||
if (placeholder instanceof PlayerPlaceholder playerPlaceholder) {
|
||||
TimeStampData<String> previous = player.getValue(placeholder);
|
||||
@@ -650,7 +656,7 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
for (Feature feature : player.activeFeatures(placeholder)) {
|
||||
// Filter features that will not be updated for all players
|
||||
if (!featuresToNotifyUpdates.contains(feature)) {
|
||||
List<CNPlayer> players = relationalFeaturesToNotifyUpdates.computeIfAbsent(feature, k -> new ArrayList<>());
|
||||
List<CNPlayer> players = relationalFeaturesToNotifyUpdates.computeIfAbsent(feature, k -> new ObjectArrayList<>());
|
||||
players.add(nearby);
|
||||
}
|
||||
}
|
||||
@@ -661,7 +667,7 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
for (Feature feature : player.activeFeatures(placeholder)) {
|
||||
// Filter features that will not be updated for all players
|
||||
if (!featuresToNotifyUpdates.contains(feature)) {
|
||||
List<CNPlayer> players = relationalFeaturesToNotifyUpdates.computeIfAbsent(feature, k -> new ArrayList<>());
|
||||
List<CNPlayer> players = relationalFeaturesToNotifyUpdates.computeIfAbsent(feature, k -> new ObjectArrayList<>());
|
||||
players.add(nearby);
|
||||
}
|
||||
}
|
||||
@@ -675,7 +681,7 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
for (Feature feature : player.activeFeatures(placeholder)) {
|
||||
// Filter features that will not be updated for all players
|
||||
if (!featuresToNotifyUpdates.contains(feature)) {
|
||||
List<CNPlayer> players = relationalFeaturesToNotifyUpdates.computeIfAbsent(feature, k -> new ArrayList<>());
|
||||
List<CNPlayer> players = relationalFeaturesToNotifyUpdates.computeIfAbsent(feature, k -> new ObjectArrayList<>());
|
||||
players.add(nearby);
|
||||
}
|
||||
}
|
||||
@@ -771,7 +777,7 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
if (firstPercent == 0 && text.charAt(text.length() - 1) == '%' && text.indexOf('%', 1) == text.length() - 1) {
|
||||
return Collections.singletonList(text);
|
||||
}
|
||||
List<String> placeholders = new ArrayList<>();
|
||||
List<String> placeholders = new ObjectArrayList<>();
|
||||
Matcher m = PATTERN.matcher(text);
|
||||
while (m.find()) {
|
||||
placeholders.add(m.group());
|
||||
|
||||
+13
@@ -17,16 +17,29 @@
|
||||
|
||||
package net.momirealms.customnameplates.backend.requirement;
|
||||
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.requirement.Requirement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class AbstractRequirement implements Requirement {
|
||||
|
||||
protected final int refreshInterval;
|
||||
@Nullable
|
||||
protected Integer countId;
|
||||
|
||||
public AbstractRequirement(int refreshInterval) {
|
||||
this.refreshInterval = refreshInterval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countId() {
|
||||
// lazy init
|
||||
if (countId == null) {
|
||||
countId = CustomNameplates.getInstance().getRequirementManager().countId(this);
|
||||
}
|
||||
return countId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int refreshInterval() {
|
||||
return refreshInterval;
|
||||
|
||||
+25
-1
@@ -18,6 +18,8 @@
|
||||
package net.momirealms.customnameplates.backend.requirement;
|
||||
|
||||
import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.feature.PreParsedDynamicText;
|
||||
@@ -26,6 +28,7 @@ import net.momirealms.customnameplates.api.requirement.RequirementFactory;
|
||||
import net.momirealms.customnameplates.api.requirement.RequirementManager;
|
||||
import net.momirealms.customnameplates.api.util.ConfigUtils;
|
||||
import net.momirealms.customnameplates.backend.requirement.builtin.*;
|
||||
import net.momirealms.customnameplates.common.util.ListUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -34,7 +37,9 @@ import java.util.*;
|
||||
public abstract class AbstractRequirementManager implements RequirementManager {
|
||||
|
||||
protected final CustomNameplates plugin;
|
||||
private final HashMap<String, RequirementFactory> requirementFactoryMap = new HashMap<>();
|
||||
private final Object2ObjectOpenHashMap<String, RequirementFactory> requirementFactoryMap = new Object2ObjectOpenHashMap<>(128);
|
||||
private int countId = 0;
|
||||
private final Map<Requirement, Integer> registeredRequirements = new Object2IntOpenHashMap<>(128);
|
||||
|
||||
public AbstractRequirementManager(CustomNameplates plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -42,6 +47,21 @@ public abstract class AbstractRequirementManager implements RequirementManager {
|
||||
this.registerPlatformRequirements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
this.countId = 0;
|
||||
this.registeredRequirements.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countId(Requirement requirement) {
|
||||
if (requirement == null) return -1;
|
||||
if (this.registeredRequirements.containsKey(requirement)) return this.registeredRequirements.get(requirement);
|
||||
this.countId++;
|
||||
this.registeredRequirements.put(requirement, countId);
|
||||
return this.countId;
|
||||
}
|
||||
|
||||
private void registerInternalRequirements() {
|
||||
this.registerRequirement((args, interval) -> {
|
||||
Section section = ConfigUtils.safeCast(args, Section.class);
|
||||
@@ -178,6 +198,10 @@ public abstract class AbstractRequirementManager implements RequirementManager {
|
||||
boolean has = (boolean) args;
|
||||
return new HasBubbleRequirement(interval, has);
|
||||
}, "has-bubble");
|
||||
this.registerRequirement((args, interval) -> new NameplateRequirement(interval, new HashSet<>(ListUtils.toList(args))), "nameplate");
|
||||
this.registerRequirement((args, interval) -> new NotNameplateRequirement(interval, new HashSet<>(ListUtils.toList(args))), "!nameplate");
|
||||
this.registerRequirement((args, interval) -> new BubbleRequirement(interval, new HashSet<>(ListUtils.toList(args))), "bubble");
|
||||
this.registerRequirement((args, interval) -> new NotBubbleRequirement(interval, new HashSet<>(ListUtils.toList(args))), "!bubble");
|
||||
}
|
||||
|
||||
protected abstract void registerPlatformRequirements();
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.backend.requirement.builtin;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.backend.requirement.AbstractRequirement;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class BubbleRequirement extends AbstractRequirement {
|
||||
|
||||
private final Set<String> bubbles;
|
||||
|
||||
public BubbleRequirement(int refreshInterval, Set<String> bubbles) {
|
||||
super(refreshInterval);
|
||||
this.bubbles = bubbles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSatisfied(CNPlayer p1, CNPlayer p2) {
|
||||
if (!ConfigManager.bubbleModule()) return false;
|
||||
String bubble = p1.equippedBubble();
|
||||
if (bubble.equals("none")) bubble = CustomNameplates.getInstance().getBubbleManager().defaultBubbleId();
|
||||
return bubbles.contains(bubble);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return "bubble";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof BubbleRequirement that)) return false;
|
||||
return bubbles.equals(that.bubbles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(bubbles);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.backend.requirement.builtin;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.backend.requirement.AbstractRequirement;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class NameplateRequirement extends AbstractRequirement {
|
||||
|
||||
private final Set<String> nameplates;
|
||||
|
||||
public NameplateRequirement(int refreshInterval, Set<String> nameplates) {
|
||||
super(refreshInterval);
|
||||
this.nameplates = nameplates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSatisfied(CNPlayer p1, CNPlayer p2) {
|
||||
if (!ConfigManager.nameplateModule()) return false;
|
||||
String nameplate = p1.equippedNameplate();
|
||||
if (nameplate.equals("none")) nameplate = CustomNameplates.getInstance().getNameplateManager().defaultNameplateId();
|
||||
return nameplates.contains(nameplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return "nameplate";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof NameplateRequirement that)) return false;
|
||||
return nameplates.equals(that.nameplates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(nameplates);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.backend.requirement.builtin;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.backend.requirement.AbstractRequirement;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class NotBubbleRequirement extends AbstractRequirement {
|
||||
|
||||
private final Set<String> bubbles;
|
||||
|
||||
public NotBubbleRequirement(int refreshInterval, Set<String> bubbles) {
|
||||
super(refreshInterval);
|
||||
this.bubbles = bubbles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSatisfied(CNPlayer p1, CNPlayer p2) {
|
||||
if (!ConfigManager.bubbleModule()) return false;
|
||||
String bubble = p1.equippedBubble();
|
||||
if (bubble.equals("none")) bubble = CustomNameplates.getInstance().getBubbleManager().defaultBubbleId();
|
||||
return !bubbles.contains(bubble);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return "!bubble";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof NotBubbleRequirement that)) return false;
|
||||
return bubbles.equals(that.bubbles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(bubbles);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.backend.requirement.builtin;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.backend.requirement.AbstractRequirement;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class NotNameplateRequirement extends AbstractRequirement {
|
||||
|
||||
private final Set<String> nameplates;
|
||||
|
||||
public NotNameplateRequirement(int refreshInterval, Set<String> nameplates) {
|
||||
super(refreshInterval);
|
||||
this.nameplates = nameplates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSatisfied(CNPlayer p1, CNPlayer p2) {
|
||||
if (!ConfigManager.nameplateModule()) return false;
|
||||
String nameplate = p1.equippedNameplate();
|
||||
if (nameplate.equals("none")) nameplate = CustomNameplates.getInstance().getNameplateManager().defaultNameplateId();
|
||||
return !nameplates.contains(nameplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return "!nameplate";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof NotNameplateRequirement that)) return false;
|
||||
return nameplates.equals(that.nameplates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(nameplates);
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -37,8 +37,9 @@ public abstract class PlaceholdersRequirement extends AbstractRequirement {
|
||||
|
||||
@Override
|
||||
public boolean isSatisfied(CNPlayer p1, CNPlayer p2) {
|
||||
p1.forceUpdatePlaceholders(t1.placeholders(), Set.of(p2));
|
||||
p1.forceUpdatePlaceholders(t2.placeholders(), Set.of(p2));
|
||||
Set<CNPlayer> set = Set.of(p2);
|
||||
p1.forceUpdatePlaceholders(t1.placeholders(), set);
|
||||
p1.forceUpdatePlaceholders(t2.placeholders(), set);
|
||||
String a1 = t1.fastCreate(p1).render(p2);
|
||||
String a2 = t2.fastCreate(p1).render(p2);
|
||||
return checkArgument(a1, a2);
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#version 150
|
||||
#moj_import<fog.glsl>
|
||||
#moj_import <fog.glsl>
|
||||
|
||||
uniform sampler2D Sampler0;
|
||||
uniform vec4 ColorModulator;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#version 150
|
||||
#moj_import<fog.glsl>
|
||||
#moj_import <fog.glsl>
|
||||
|
||||
uniform sampler2D Sampler0;
|
||||
uniform vec4 ColorModulator;
|
||||
|
||||
-5
@@ -1,9 +1,4 @@
|
||||
{
|
||||
"blend": {
|
||||
"func": "add",
|
||||
"srcrgb": "srcalpha",
|
||||
"dstrgb": "1-srcalpha"
|
||||
},
|
||||
"vertex": "rendertype_text",
|
||||
"fragment": "rendertype_text",
|
||||
"attributes": [
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
#version 150
|
||||
#moj_import <minecraft:fog.glsl>
|
||||
|
||||
uniform sampler2D Sampler0;
|
||||
uniform vec4 ColorModulator;
|
||||
uniform float FogStart,FogEnd;
|
||||
uniform vec4 FogColor;
|
||||
uniform float GameTime;
|
||||
|
||||
in float vertexDistance;
|
||||
in vec4 vertexColor;
|
||||
in vec2 texCoord0;
|
||||
in float depthLevel;
|
||||
%SHADER_0%
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec4 texColor = texture(Sampler0, texCoord0);
|
||||
vec4 color = texColor * vertexColor * ColorModulator;%SHADER_1%
|
||||
if (color.a < 0.1) {
|
||||
discard;
|
||||
}
|
||||
if (depthLevel == 114514.0) {
|
||||
discard;
|
||||
}
|
||||
if (texColor.a == 254.0/255.0) {
|
||||
if (depthLevel == 1000.0
|
||||
|| depthLevel == 2200
|
||||
|| depthLevel == 50
|
||||
|| depthLevel == 2650
|
||||
|| depthLevel == 200
|
||||
|| depthLevel == 400
|
||||
|| depthLevel == 2800
|
||||
|| depthLevel == 2400
|
||||
) {
|
||||
discard;
|
||||
} else {
|
||||
color = vec4(texColor.rgb, 1.0) * vertexColor * ColorModulator;
|
||||
}
|
||||
}
|
||||
fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"vertex": "minecraft:core/rendertype_text",
|
||||
"fragment": "minecraft:core/rendertype_text",
|
||||
"attributes": [
|
||||
"Position",
|
||||
"Color",
|
||||
"UV0",
|
||||
"UV2"
|
||||
],
|
||||
"samplers": [
|
||||
{ "name": "Sampler0" },
|
||||
{ "name": "Sampler2" }
|
||||
],
|
||||
"uniforms": [
|
||||
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||
{ "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
|
||||
{ "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] },
|
||||
{ "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] },
|
||||
{ "name": "GameTime", "type": "float", "count": 1, "values": [ 1.0 ] },
|
||||
{ "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }
|
||||
]
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
#version 150
|
||||
#moj_import <minecraft:fog.glsl>
|
||||
|
||||
in vec3 Position;
|
||||
in vec4 Color;
|
||||
in vec2 UV0;
|
||||
in ivec2 UV2;
|
||||
|
||||
uniform sampler2D Sampler2;
|
||||
uniform mat4 ModelViewMat;
|
||||
uniform mat4 ProjMat;
|
||||
uniform float GameTime;
|
||||
uniform int FogShape;
|
||||
uniform vec2 ScreenSize;
|
||||
|
||||
out float vertexDistance;
|
||||
out vec4 vertexColor;
|
||||
out vec2 texCoord0;
|
||||
out float depthLevel;
|
||||
%SHADER_0%
|
||||
void main() {
|
||||
vec4 vertex = vec4(Position, 1.0);
|
||||
vertexDistance = fog_distance(Position, FogShape);
|
||||
depthLevel = Position.z;
|
||||
texCoord0 = UV0;
|
||||
%SHADER_1%%SHADER_2%%SHADER_3%
|
||||
}
|
||||
@@ -1,21 +1,28 @@
|
||||
{
|
||||
"pack":{
|
||||
"pack_format": 8,
|
||||
"description":"CustomNameplates",
|
||||
"supported_formats": {
|
||||
"min_inclusive": 8,
|
||||
"max_inclusive": 34
|
||||
"pack": {
|
||||
"pack_format": 13,
|
||||
"description": "CustomNameplates",
|
||||
"supported_formats": {
|
||||
"min_inclusive": 13,
|
||||
"max_inclusive": 43
|
||||
}
|
||||
},
|
||||
"overlays": {
|
||||
"entries": [
|
||||
{
|
||||
"formats": {
|
||||
"min_inclusive": 32,
|
||||
"max_inclusive": 34
|
||||
},
|
||||
"directory": "overlay_1_20_5"
|
||||
},
|
||||
{
|
||||
"formats": {
|
||||
"min_inclusive": 42,
|
||||
"max_inclusive": 43
|
||||
},
|
||||
"directory": "overlay_1_21_2"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overlays": {
|
||||
"entries": [
|
||||
{
|
||||
"formats": {
|
||||
"min_inclusive": 32,
|
||||
"max_inclusive": 34
|
||||
},
|
||||
"directory": "overlay_1_20_5"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,28 @@
|
||||
{
|
||||
"pack":{
|
||||
"pack_format": 32,
|
||||
"description":"CustomNameplates",
|
||||
"supported_formats": {
|
||||
"min_inclusive": 32,
|
||||
"max_inclusive": 34
|
||||
"pack": {
|
||||
"pack_format": 32,
|
||||
"description": "CustomNameplates",
|
||||
"supported_formats": {
|
||||
"min_inclusive": 32,
|
||||
"max_inclusive": 42
|
||||
}
|
||||
},
|
||||
"overlays": {
|
||||
"entries": [
|
||||
{
|
||||
"formats": {
|
||||
"min_inclusive": 32,
|
||||
"max_inclusive": 34
|
||||
},
|
||||
"directory": "overlay_1_20_5"
|
||||
},
|
||||
{
|
||||
"formats": {
|
||||
"min_inclusive": 42,
|
||||
"max_inclusive": 43
|
||||
},
|
||||
"directory": "overlay_1_21_2"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"pack": {
|
||||
"pack_format": 42,
|
||||
"description": "CustomNameplates",
|
||||
"supported_formats": {
|
||||
"min_inclusive": 42,
|
||||
"max_inclusive": 43
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ integrations:
|
||||
ItemsAdder: false # Integration with ItemsAdder
|
||||
ItemsAdder-old-method: false # Old method for ItemsAdder
|
||||
Oraxen: false # Integration with Oraxen
|
||||
Creative-Central: false # Integration with Creative-Central
|
||||
chat:
|
||||
TrChat: false # Integration with TrChat
|
||||
VentureChat: false # Integration with VentureChat
|
||||
@@ -62,6 +63,8 @@ other-settings:
|
||||
send-delay: 20 # Set actionbar/bossbar send delay (ticks)
|
||||
catch-other-plugin-actionbar: true # Capture actionbars from other plugins
|
||||
other-actionbar-stay-time: 3000 # How long does other actionsbars stay (ms)
|
||||
display-system-actionbar: true # Should the plugin display system actionbar and temporarily hide the custom actionbar?
|
||||
hide-team-names: true # Hide the team name sent by other plugins or vanilla team system
|
||||
unsafe-chat-event: false # Listen for canceled(unsafe) chat events from unknown plugins
|
||||
default-condition-refresh-interval: 1 # Set default condition refresh interval
|
||||
default-placeholder-refresh-interval: 1 # Set default placeholder refresh interval
|
||||
@@ -164,13 +167,14 @@ other-settings:
|
||||
unicode:
|
||||
file: unicode_page_%02x.png # Default Unicode characters
|
||||
sizes: glyph_sizes.bin # Glyph size configuration
|
||||
ttf:
|
||||
example:
|
||||
generate: false # Should this TTF file be included in the generated pack
|
||||
file: example.ttf # Define the TTF file to load the font from
|
||||
size: 10.0 # Set font size
|
||||
oversample: 8.0 # Oversample rate for TTF rendering
|
||||
skip: [] # Skipped characters in list format
|
||||
ttf: {}
|
||||
# ttf:
|
||||
# example:
|
||||
# generate: false # Should this TTF file be included in the generated pack
|
||||
# file: example.ttf # Define the TTF file to load the font from
|
||||
# size: 10.0 # Set font size
|
||||
# oversample: 8.0 # Oversample rate for TTF rendering
|
||||
# skip: [] # Skipped characters in list format
|
||||
shift-fonts:
|
||||
shift_0:
|
||||
- space
|
||||
|
||||
@@ -26,5 +26,5 @@ bubble-settings:
|
||||
3: chat_3
|
||||
line-width: 150
|
||||
background-color: 0,0,0,0
|
||||
text-prefix: "<black><font:nameplates:shift_0>"
|
||||
text-prefix: "<black><font:{namespace}:shift_0>" # {namespace} would be replaced by the namespace set in config.yml
|
||||
text-suffix: "</font></black>"
|
||||
@@ -2,21 +2,22 @@
|
||||
conditional-text:
|
||||
actionbar:
|
||||
priority_1:
|
||||
text: '%np_background_other_actionbar%'
|
||||
text: '%np_background_other_actionbar%' # hides the money hud when a player rides something or dives in water
|
||||
conditions:
|
||||
'||':
|
||||
is-passenger: true
|
||||
'!=':
|
||||
value1: '%player_remaining_air%'
|
||||
value2: "300"
|
||||
'!gamemode': survival
|
||||
priority_2:
|
||||
text: '%np_static_money_hud%%np_offset_-179%%np_static_other_actionbar%'
|
||||
text: '%np_static_money_hud%%np_offset_-179%%np_static_other_actionbar%' # displays the money hud + other plugin's actionbar message
|
||||
conditions:
|
||||
'!equals':
|
||||
value1: '%np_actionbar%'
|
||||
value2: ""
|
||||
priority_3:
|
||||
text: '%np_static_money_hud%'
|
||||
text: '%np_static_money_hud%' # displays the money hud only
|
||||
weather:
|
||||
priority_1:
|
||||
text: 'Sunny'
|
||||
|
||||
@@ -9,7 +9,20 @@ nameplate:
|
||||
player-name: '%np_shift_player_name%'
|
||||
suffix: '%np_switch_nameplate_color_suffix%'
|
||||
unlimited:
|
||||
tag_1:
|
||||
tag_normal:
|
||||
text: '%np_tag-text%'
|
||||
translation: 0,0.2,0
|
||||
viewer-conditions: { }
|
||||
owner-conditions:
|
||||
has-nameplate: false
|
||||
potion-effect: "INVISIBILITY<0"
|
||||
self-disguised: false
|
||||
affected-by-crouching: true
|
||||
affected-by-scale-attribute: true
|
||||
affected-by-spectator: true
|
||||
line-width: 1024
|
||||
background-color: 64,0,0,0
|
||||
tag_image_part:
|
||||
text: '%np_tag-image%'
|
||||
translation: 0,0.2,0
|
||||
viewer-conditions: { }
|
||||
@@ -22,7 +35,7 @@ unlimited:
|
||||
affected-by-spectator: true
|
||||
line-width: 1024
|
||||
background-color: 0,0,0,0
|
||||
tag_2:
|
||||
tag_text_part:
|
||||
text: '%np_tag-text%'
|
||||
translation: 0.01,0.2,0.01
|
||||
viewer-conditions: { }
|
||||
@@ -34,17 +47,4 @@ unlimited:
|
||||
affected-by-scale-attribute: true
|
||||
affected-by-spectator: true
|
||||
line-width: 1024
|
||||
background-color: 0,0,0,0
|
||||
tag_3:
|
||||
text: '%np_tag-text%'
|
||||
translation: 0,0.2,0
|
||||
viewer-conditions: { }
|
||||
owner-conditions:
|
||||
has-nameplate: false
|
||||
potion-effect: "INVISIBILITY<0"
|
||||
self-disguised: false
|
||||
affected-by-crouching: true
|
||||
affected-by-scale-attribute: true
|
||||
affected-by-spectator: true
|
||||
line-width: 1024
|
||||
background-color: 64,0,0,0
|
||||
background-color: 0,0,0,0
|
||||
@@ -1,3 +1,4 @@
|
||||
image: bell
|
||||
height: 10
|
||||
ascent: 4
|
||||
ascent: 4
|
||||
shadow: false
|
||||
@@ -1,3 +1,4 @@
|
||||
image: bubble
|
||||
height: 10
|
||||
ascent: 4
|
||||
ascent: 4
|
||||
shadow: false
|
||||
@@ -1,3 +1,4 @@
|
||||
image: clock
|
||||
height: 10
|
||||
ascent: 4
|
||||
ascent: 4
|
||||
shadow: false
|
||||
@@ -1,3 +1,4 @@
|
||||
image: coin
|
||||
height: 10
|
||||
ascent: -14
|
||||
ascent: -14
|
||||
shadow: false
|
||||
@@ -1,3 +1,4 @@
|
||||
image: compass
|
||||
height: 10
|
||||
ascent: 4
|
||||
ascent: 4
|
||||
shadow: false
|
||||
@@ -1,3 +1,4 @@
|
||||
image: stamina_0
|
||||
height: 9
|
||||
ascent: -16
|
||||
ascent: -16
|
||||
shadow: false
|
||||
@@ -1,3 +1,4 @@
|
||||
image: stamina_1
|
||||
height: 9
|
||||
ascent: -16
|
||||
ascent: -16
|
||||
shadow: false
|
||||
@@ -1,3 +1,4 @@
|
||||
image: stamina_2
|
||||
height: 9
|
||||
ascent: -16
|
||||
ascent: -16
|
||||
shadow: false
|
||||
@@ -1,3 +1,4 @@
|
||||
image: weather
|
||||
height: 10
|
||||
ascent: 4
|
||||
ascent: 4
|
||||
shadow: false
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package net.momirealms.customnameplates.bukkit;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import net.momirealms.customnameplates.api.AbstractCNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
@@ -29,6 +30,8 @@ import org.bukkit.attribute.AttributeInstance;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@@ -38,82 +41,91 @@ public class BukkitCNPlayer extends AbstractCNPlayer {
|
||||
|
||||
private static final Attribute scaleAttribute = Registry.ATTRIBUTE.get(NamespacedKey.minecraft("generic.scale"));
|
||||
|
||||
private final Player player;
|
||||
private Reference<Player> player;
|
||||
|
||||
public BukkitCNPlayer(CustomNameplates plugin, Player player) {
|
||||
super(plugin, player);
|
||||
this.player = player;
|
||||
public BukkitCNPlayer(CustomNameplates plugin, Channel channel) {
|
||||
super(plugin, channel);
|
||||
}
|
||||
|
||||
public void setPlayer(Player player) {
|
||||
super.setPlayer(player);
|
||||
this.player = new WeakReference<>(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player player() {
|
||||
return player.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return player.getName();
|
||||
return player().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID uuid() {
|
||||
return player.getUniqueId();
|
||||
return player().getUniqueId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int entityID() {
|
||||
return player.getEntityId();
|
||||
return player().getEntityId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3 position() {
|
||||
Location location = player.getLocation();
|
||||
Location location = player().getLocation();
|
||||
return new Vector3(location.x(), location.y(), location.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String world() {
|
||||
return player.getWorld().getName();
|
||||
return player().getWorld().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double scale() {
|
||||
if (scaleAttribute == null) return 1;
|
||||
return Optional.ofNullable(player.getAttribute(scaleAttribute)).map(AttributeInstance::getValue).orElse(1d);
|
||||
return Optional.ofNullable(player().getAttribute(scaleAttribute)).map(AttributeInstance::getValue).orElse(1d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCrouching() {
|
||||
return player.isSneaking();
|
||||
return player().isSneaking();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
return player.hasPermission(permission);
|
||||
return player().hasPermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long playerTime() {
|
||||
return player.getPlayerTime();
|
||||
return player().getPlayerTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnline() {
|
||||
return player.isOnline();
|
||||
return player().isOnline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpectator() {
|
||||
return player.getGameMode() == GameMode.SPECTATOR;
|
||||
return player().getGameMode() == GameMode.SPECTATOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> passengers() {
|
||||
return player.getPassengers().stream().map(Entity::getEntityId).collect(Collectors.toSet());
|
||||
return player().getPassengers().stream().map(Entity::getEntityId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlying() {
|
||||
return player.isFlying();
|
||||
return player().isFlying();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remainingAir() {
|
||||
return player.getRemainingAir();
|
||||
return player().getRemainingAir();
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class BukkitChatManager extends AbstractChatManager {
|
||||
}
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("Oraxen")) {
|
||||
try {
|
||||
this.emojiProviders.add(new OraxenEmojiProvider());
|
||||
this.emojiProviders.add(new OraxenEmojiProvider(Bukkit.getPluginManager().getPlugin("Oraxen").getDescription().getVersion().startsWith("1") ? 1 : 2));
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
+92
-22
@@ -24,6 +24,7 @@ import net.momirealms.customnameplates.api.feature.JoinQuitListener;
|
||||
import net.momirealms.customnameplates.api.feature.PlayerListener;
|
||||
import net.momirealms.customnameplates.api.helper.AdventureHelper;
|
||||
import net.momirealms.customnameplates.api.helper.VersionHelper;
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
import net.momirealms.customnameplates.backend.feature.actionbar.ActionBarManagerImpl;
|
||||
import net.momirealms.customnameplates.backend.feature.advance.AdvanceManagerImpl;
|
||||
import net.momirealms.customnameplates.backend.feature.background.BackgroundManagerImpl;
|
||||
@@ -37,9 +38,12 @@ import net.momirealms.customnameplates.backend.placeholder.PlaceholderManagerImp
|
||||
import net.momirealms.customnameplates.backend.storage.StorageManagerImpl;
|
||||
import net.momirealms.customnameplates.bukkit.command.BukkitCommandManager;
|
||||
import net.momirealms.customnameplates.bukkit.compatibility.NameplatesExpansion;
|
||||
import net.momirealms.customnameplates.bukkit.compatibility.NameplatesExtraExpansion;
|
||||
import net.momirealms.customnameplates.bukkit.compatibility.cosmetic.MagicCosmeticsHook;
|
||||
import net.momirealms.customnameplates.bukkit.compatibility.region.WorldGuardRegion;
|
||||
import net.momirealms.customnameplates.bukkit.requirement.BukkitRequirementManager;
|
||||
import net.momirealms.customnameplates.bukkit.scheduler.BukkitSchedulerAdapter;
|
||||
import net.momirealms.customnameplates.bukkit.util.SimpleLocation;
|
||||
import net.momirealms.customnameplates.common.dependency.Dependency;
|
||||
import net.momirealms.customnameplates.common.dependency.DependencyManagerImpl;
|
||||
import net.momirealms.customnameplates.common.event.EventManager;
|
||||
@@ -50,9 +54,11 @@ import net.momirealms.customnameplates.common.plugin.logging.JavaPluginLogger;
|
||||
import net.momirealms.customnameplates.common.plugin.logging.PluginLogger;
|
||||
import net.momirealms.customnameplates.common.plugin.scheduler.AbstractJavaScheduler;
|
||||
import net.momirealms.customnameplates.common.plugin.scheduler.SchedulerAdapter;
|
||||
import net.momirealms.customnameplates.common.plugin.scheduler.SchedulerTask;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
@@ -63,6 +69,7 @@ import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BukkitCustomNameplates extends CustomNameplates implements Listener {
|
||||
@@ -75,12 +82,16 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
|
||||
|
||||
private BukkitSenderFactory senderFactory;
|
||||
private BukkitCommandManager commandManager;
|
||||
private BukkitNetworkManager networkManager;
|
||||
|
||||
private final JavaPlugin bootstrap;
|
||||
|
||||
private final List<JoinQuitListener> joinQuitListeners = new ArrayList<>();
|
||||
private final List<PlayerListener> playerListeners = new ArrayList<>();
|
||||
|
||||
private final ConcurrentHashMap<String, SimpleLocation> foliaLocationTracker = new ConcurrentHashMap<>();
|
||||
private SchedulerTask foliaTrackerTask;
|
||||
|
||||
private boolean loaded = false;
|
||||
|
||||
private String buildByBit = "%%__BUILTBYBIT__%%";
|
||||
@@ -133,10 +144,17 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
|
||||
return;
|
||||
}
|
||||
|
||||
BukkitNetworkManager networkManager = new BukkitNetworkManager(this);
|
||||
this.mainTask = new MainTask(this);
|
||||
|
||||
this.networkManager = new BukkitNetworkManager(this);
|
||||
this.packetSender = networkManager;
|
||||
this.pipelineInjector = networkManager;
|
||||
try {
|
||||
this.networkManager.init();
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
this.commandManager = new BukkitCommandManager(this);
|
||||
this.senderFactory = new BukkitSenderFactory(this);
|
||||
this.platform = new BukkitPlatform(this);
|
||||
@@ -179,6 +197,7 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
|
||||
}
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
|
||||
new NameplatesExpansion(this).register();
|
||||
new NameplatesExtraExpansion(this).register();
|
||||
}
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("MagicCosmetics")) {
|
||||
try {
|
||||
@@ -186,6 +205,12 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("WorldGuard")) {
|
||||
try {
|
||||
WorldGuardRegion.register();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
boolean downloadFromPolymart = polymart.equals("1");
|
||||
boolean downloadFromBBB = buildByBit.equals("true");
|
||||
@@ -209,13 +234,43 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (VersionHelper.isFolia()) {
|
||||
this.foliaTrackerTask = getScheduler().asyncRepeating(() -> {
|
||||
for (CNPlayer player : getOnlinePlayers()) {
|
||||
String name = player.name();
|
||||
SimpleLocation previousLocation = this.foliaLocationTracker.get(name);
|
||||
if (previousLocation != null) {
|
||||
String currentWorld = player.world();
|
||||
if (!currentWorld.equals(previousLocation.world())) {
|
||||
previousLocation.world(currentWorld);
|
||||
previousLocation.position(player.position());
|
||||
for (PlayerListener listener : this.playerListeners) {
|
||||
listener.onChangeWorld(player);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Vector3 previousPos = previousLocation.position();
|
||||
Vector3 currentPos = player.position();
|
||||
previousLocation.world(currentWorld);
|
||||
previousLocation.position(currentPos);
|
||||
double distance = Math.sqrt(Math.pow((currentPos.x() - previousPos.x()), 2) + Math.pow((currentPos.y() - previousPos.y()), 2) + Math.pow(currentPos.z() - previousPos.z(), 2));
|
||||
if (distance > 64) {
|
||||
for (PlayerListener listener : this.playerListeners) {
|
||||
listener.onTeleport(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 200, 200, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
if (!this.loaded) return;
|
||||
if (this.scheduledMainTask != null) this.scheduledMainTask.cancel();
|
||||
|
||||
if (foliaTrackerTask != null) foliaTrackerTask.cancel();
|
||||
if (configManager != null) this.configManager.disable();
|
||||
if (actionBarManager != null) this.actionBarManager.disable();
|
||||
if (bossBarManager != null) this.bossBarManager.disable();
|
||||
@@ -229,13 +284,16 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
|
||||
if (nameplateManager != null) this.nameplateManager.disable();
|
||||
if (imageManager != null) this.imageManager.disable();
|
||||
if (chatManager != null) this.chatManager.disable();
|
||||
|
||||
if (commandManager != null) this.commandManager.unregisterFeatures();
|
||||
this.joinQuitListeners.clear();
|
||||
this.playerListeners.clear();
|
||||
this.networkManager.shutdown();
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
AdventureHelper.clearCache();
|
||||
|
||||
this.onlinePlayerMap.clear();
|
||||
this.entityIDFastLookup.clear();
|
||||
this.scheduler.shutdownScheduler();
|
||||
this.scheduler.shutdownExecutor();
|
||||
this.loaded = false;
|
||||
}
|
||||
|
||||
@@ -251,6 +309,8 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
|
||||
for (CNPlayer player : getOnlinePlayers()) {
|
||||
((AbstractCNPlayer) player).reload();
|
||||
}
|
||||
// clear requirement ids
|
||||
this.requirementManager.reload();
|
||||
// load basics
|
||||
this.configManager.reload();
|
||||
this.storageManager.reload();
|
||||
@@ -263,8 +323,6 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
|
||||
this.advanceManager.reload();
|
||||
// set up placeholders
|
||||
this.placeholderManager.reload();
|
||||
// set up requirements
|
||||
this.requirementManager.reload();
|
||||
// use the placeholders
|
||||
this.actionBarManager.reload();
|
||||
this.bossBarManager.reload();
|
||||
@@ -327,38 +385,50 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
CNPlayer cnPlayer = new BukkitCNPlayer(this, event.getPlayer());
|
||||
CNPlayer previous = onlinePlayerMap.put(cnPlayer.uuid(), cnPlayer);
|
||||
if (previous != null) {
|
||||
getPluginLogger().severe("Player " + event.getPlayer().getName() + " is duplicated");
|
||||
Player player = event.getPlayer();
|
||||
handleJoin(player);
|
||||
}
|
||||
|
||||
public void handleJoin(Player player) {
|
||||
CNPlayer user = pipelineInjector.getUser(player);
|
||||
if (user == null) {
|
||||
getPluginLogger().severe("Player " + player.getName() + " has not been injected yet");
|
||||
return;
|
||||
}
|
||||
|
||||
entityIDFastLookup.put(cnPlayer.entityID(), cnPlayer);
|
||||
pipelineInjector.inject(cnPlayer);
|
||||
|
||||
((BukkitCNPlayer) user).setPlayer(player);
|
||||
CNPlayer previous = onlinePlayerMap.put(player.getUniqueId(), user);
|
||||
if (previous != null) {
|
||||
getPluginLogger().severe("Player " + player.getName() + " is duplicated");
|
||||
}
|
||||
entityIDFastLookup.put(user.entityID(), user);
|
||||
for (JoinQuitListener listener : joinQuitListeners) {
|
||||
listener.onPlayerJoin(cnPlayer);
|
||||
listener.onPlayerJoin(user);
|
||||
}
|
||||
if (VersionHelper.isFolia()) {
|
||||
foliaLocationTracker.put(player.getName(), new SimpleLocation(user.world(), user.position()));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
CNPlayer cnPlayer = onlinePlayerMap.remove(event.getPlayer().getUniqueId());
|
||||
Player player = event.getPlayer();
|
||||
CNPlayer cnPlayer = onlinePlayerMap.remove(player.getUniqueId());
|
||||
if (cnPlayer == null) {
|
||||
getPluginLogger().severe("Player " + event.getPlayer().getName() + " is not recorded by CustomNameplates");
|
||||
getPluginLogger().severe("Player " + player.getName() + " is not recorded by CustomNameplates");
|
||||
return;
|
||||
}
|
||||
|
||||
entityIDFastLookup.remove(cnPlayer.entityID());
|
||||
pipelineInjector.uninject(cnPlayer);
|
||||
|
||||
for (JoinQuitListener listener : joinQuitListeners) {
|
||||
listener.onPlayerQuit(cnPlayer);
|
||||
}
|
||||
entityIDFastLookup.remove(cnPlayer.entityID());
|
||||
if (VersionHelper.isFolia()) {
|
||||
foliaLocationTracker.remove(player.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onChangeWorld(PlayerChangedWorldEvent event) {
|
||||
if (VersionHelper.isFolia()) return;
|
||||
CNPlayer cnPlayer = getPlayer(event.getPlayer().getUniqueId());
|
||||
if (cnPlayer != null) {
|
||||
for (PlayerListener listener : playerListeners) {
|
||||
|
||||
+209
-32
@@ -18,25 +18,41 @@
|
||||
package net.momirealms.customnameplates.bukkit;
|
||||
|
||||
import io.netty.channel.*;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.helper.VersionHelper;
|
||||
import net.momirealms.customnameplates.api.network.PacketEvent;
|
||||
import net.momirealms.customnameplates.api.network.PacketSender;
|
||||
import net.momirealms.customnameplates.api.network.PipelineInjector;
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
import net.momirealms.customnameplates.bukkit.util.ListMonitor;
|
||||
import net.momirealms.customnameplates.bukkit.util.Reflections;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class BukkitNetworkManager implements PacketSender, PipelineInjector {
|
||||
|
||||
private final BiConsumer<CNPlayer, List<Object>> packetsConsumer;
|
||||
private final CustomNameplates plugin;
|
||||
private final BiConsumer<CNPlayer, Object> packetConsumer;
|
||||
private final BukkitCustomNameplates plugin;
|
||||
private static final String NAMEPLATES_CONNECTION_HANDLER_NAME = "nameplates_connection_handler";
|
||||
private static final String NAMEPLATES_SERVER_CHANNEL_HANDLER_NAME = "nameplates_server_channel_handler";
|
||||
private static final String NAMEPLATES_PACKET_HANDLER_NAME = "nameplates_packet_handler";
|
||||
private final ConcurrentHashMap<Object, CNPlayer> users = new ConcurrentHashMap<>();
|
||||
private final HashSet<Channel> injectedChannels = new HashSet<>();
|
||||
private boolean active;
|
||||
private boolean init;
|
||||
|
||||
public BukkitNetworkManager(CustomNameplates plugin) {
|
||||
public BukkitNetworkManager(BukkitCustomNameplates plugin) {
|
||||
this.plugin = plugin;
|
||||
this.packetsConsumer = ((player, objects) -> {
|
||||
try {
|
||||
@@ -46,17 +62,121 @@ public class BukkitNetworkManager implements PacketSender, PipelineInjector {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
if (!VersionHelper.isFolia()) {
|
||||
packetConsumer = (player, packet) -> {
|
||||
try {
|
||||
Reflections.method$SendPacket.invoke(
|
||||
Reflections.field$PlayerConnection.get(
|
||||
Reflections.method$CraftPlayer$getHandle.invoke(player.player())), packet);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
packetConsumer = (player, packet) -> {
|
||||
Vector3 vector3 = player.position();
|
||||
Location location = new Location(Bukkit.getWorld(player.world()), vector3.x(), vector3.y(), vector3.z());
|
||||
plugin.getScheduler().executeSync(() -> {
|
||||
try {
|
||||
Reflections.method$SendPacket.invoke(
|
||||
Reflections.field$PlayerConnection.get(
|
||||
Reflections.method$CraftPlayer$getHandle.invoke(player.player())), packet);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}, location);
|
||||
};
|
||||
}
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
for (Channel channel : injectedChannels) {
|
||||
uninjectServerChannel(channel);
|
||||
}
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
handleDisconnection(getChannel(player));
|
||||
}
|
||||
injectedChannels.clear();
|
||||
active = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUser(Channel channel, CNPlayer user) {
|
||||
ChannelPipeline pipeline = channel.pipeline();
|
||||
users.put(pipeline, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CNPlayer getUser(Channel channel) {
|
||||
ChannelPipeline pipeline = channel.pipeline();
|
||||
return users.get(pipeline);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CNPlayer removeUser(Channel channel) {
|
||||
ChannelPipeline pipeline = channel.pipeline();
|
||||
return users.remove(pipeline);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CNPlayer getUser(Object player) {
|
||||
return getUser(getChannel(player));
|
||||
}
|
||||
|
||||
public void init() throws ReflectiveOperationException {
|
||||
if (init) return;
|
||||
Object server = Reflections.method$MinecraftServer$getServer.invoke(null);
|
||||
Object serverConnection = Reflections.field$MinecraftServer$connection.get(server);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ChannelFuture> channels = (List<ChannelFuture>) Reflections.field$ServerConnectionListener$channels.get(serverConnection);
|
||||
ListMonitor<ChannelFuture> monitor = new ListMonitor<>(channels, (future) -> {
|
||||
if (!active) return;
|
||||
Channel channel = future.channel();
|
||||
injectServerChannel(channel);
|
||||
injectedChannels.add(channel);
|
||||
}, (object) -> {});
|
||||
Reflections.field$ServerConnectionListener$channels.set(serverConnection, monitor);
|
||||
init = true;
|
||||
}
|
||||
|
||||
private void injectServerChannel(Channel serverChannel) {
|
||||
ChannelPipeline pipeline = serverChannel.pipeline();
|
||||
ChannelHandler connectionHandler = pipeline.get(NAMEPLATES_CONNECTION_HANDLER_NAME);
|
||||
if (connectionHandler != null) {
|
||||
pipeline.remove(NAMEPLATES_CONNECTION_HANDLER_NAME);
|
||||
}
|
||||
if (pipeline.get("SpigotNettyServerChannelHandler#0") != null) {
|
||||
pipeline.addAfter("SpigotNettyServerChannelHandler#0", NAMEPLATES_CONNECTION_HANDLER_NAME, new ServerChannelHandler());
|
||||
} else if (pipeline.get("floodgate-init") != null) {
|
||||
pipeline.addAfter("floodgate-init", NAMEPLATES_CONNECTION_HANDLER_NAME, new ServerChannelHandler());
|
||||
} else if (pipeline.get("MinecraftPipeline#0") != null) {
|
||||
pipeline.addAfter("MinecraftPipeline#0", NAMEPLATES_CONNECTION_HANDLER_NAME, new ServerChannelHandler());
|
||||
} else {
|
||||
pipeline.addFirst(NAMEPLATES_CONNECTION_HANDLER_NAME, new ServerChannelHandler());
|
||||
}
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
Channel channel = getChannel(player);
|
||||
CNPlayer user = getUser(player);
|
||||
if (user == null) {
|
||||
BukkitCNPlayer cnPlayer = new BukkitCNPlayer(plugin, channel);
|
||||
cnPlayer.setPlayer(player);
|
||||
injectChannel(channel, ConnectionState.PLAY);
|
||||
plugin.handleJoin(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void uninjectServerChannel(Channel channel) {
|
||||
if (channel.pipeline().get(NAMEPLATES_CONNECTION_HANDLER_NAME) != null) {
|
||||
channel.pipeline().remove(NAMEPLATES_CONNECTION_HANDLER_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(@NotNull CNPlayer player, Object packet) {
|
||||
try {
|
||||
Reflections.method$SendPacket.invoke(
|
||||
Reflections.field$PlayerConnection.get(
|
||||
Reflections.method$CraftPlayer$getHandle.invoke(player.player())), packet);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
packetConsumer.accept(player, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,12 +186,12 @@ public class BukkitNetworkManager implements PacketSender, PipelineInjector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel getChannel(CNPlayer player) {
|
||||
public Channel getChannel(Object player) {
|
||||
try {
|
||||
return (Channel) Reflections.field$Channel.get(
|
||||
Reflections.field$NetworkManager.get(
|
||||
Reflections.field$PlayerConnection.get(
|
||||
Reflections.method$CraftPlayer$getHandle.invoke(player.player())
|
||||
Reflections.method$CraftPlayer$getHandle.invoke(player)
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -85,29 +205,81 @@ public class BukkitNetworkManager implements PacketSender, PipelineInjector {
|
||||
return new CNChannelHandler(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(CNPlayer player) {
|
||||
Channel channel = getChannel(player);
|
||||
try {
|
||||
ChannelPipeline pipeline = channel.pipeline();
|
||||
for (Map.Entry<String, ChannelHandler> entry : pipeline.toMap().entrySet()) {
|
||||
if (Reflections.clazz$NetworkManager.isAssignableFrom(entry.getValue().getClass())) {
|
||||
pipeline.addBefore(entry.getKey(), "nameplates_packet_handler", createHandler(player));
|
||||
break;
|
||||
}
|
||||
public enum ConnectionState {
|
||||
HANDSHAKING, STATUS, LOGIN, PLAY, CONFIGURATION;
|
||||
}
|
||||
|
||||
public void handleDisconnection(Channel channel) {
|
||||
CNPlayer user = removeUser(channel);
|
||||
if (user == null) return;
|
||||
channel.eventLoop().submit(() -> {
|
||||
if (channel.pipeline().get(NAMEPLATES_PACKET_HANDLER_NAME) != null) {
|
||||
channel.pipeline().remove(NAMEPLATES_PACKET_HANDLER_NAME);
|
||||
}
|
||||
} catch (NoSuchElementException | IllegalArgumentException e) {
|
||||
throw new RuntimeException(e);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public void injectChannel(Channel channel, ConnectionState connectionState) {
|
||||
if (isFakeChannel(channel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CNPlayer user = new BukkitCNPlayer(plugin, channel);
|
||||
if (channel.pipeline().get("splitter") == null) {
|
||||
channel.close();
|
||||
return;
|
||||
}
|
||||
|
||||
ChannelPipeline pipeline = channel.pipeline();
|
||||
if (pipeline.get(NAMEPLATES_PACKET_HANDLER_NAME) != null) {
|
||||
pipeline.remove(NAMEPLATES_PACKET_HANDLER_NAME);
|
||||
}
|
||||
for (Map.Entry<String, ChannelHandler> entry : pipeline.toMap().entrySet()) {
|
||||
if (Reflections.clazz$NetworkManager.isAssignableFrom(entry.getValue().getClass())) {
|
||||
pipeline.addBefore(entry.getKey(), NAMEPLATES_PACKET_HANDLER_NAME, createHandler(user));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
channel.closeFuture().addListener((ChannelFutureListener) future -> handleDisconnection(user.channel()));
|
||||
setUser(channel, user);
|
||||
}
|
||||
|
||||
public class ServerChannelHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@Override
|
||||
public void channelRead(@NotNull ChannelHandlerContext context, @NotNull Object c) throws Exception {
|
||||
Channel channel = (Channel) c;
|
||||
channel.pipeline().addLast(NAMEPLATES_SERVER_CHANNEL_HANDLER_NAME, new PreChannelInitializer());
|
||||
super.channelRead(context, c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninject(CNPlayer player) {
|
||||
Channel channel = getChannel(player);
|
||||
channel.eventLoop().submit(() -> {
|
||||
channel.pipeline().remove("nameplates_packet_handler");
|
||||
return null;
|
||||
});
|
||||
public class PreChannelInitializer extends ChannelInboundHandlerAdapter {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(io.netty.channel.ChannelInitializer.class);
|
||||
|
||||
@Override
|
||||
public void channelRegistered(ChannelHandlerContext context) {
|
||||
try {
|
||||
injectChannel(context.channel(), ConnectionState.HANDSHAKING);
|
||||
} catch (Throwable t) {
|
||||
exceptionCaught(context, t);
|
||||
} finally {
|
||||
ChannelPipeline pipeline = context.pipeline();
|
||||
if (pipeline.context(this) != null) {
|
||||
pipeline.remove(this);
|
||||
}
|
||||
}
|
||||
context.pipeline().fireChannelRegistered();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext context, Throwable t) {
|
||||
PreChannelInitializer.logger.warn("Failed to inject channel: " + context.channel(), t);
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
public class CNChannelHandler extends ChannelDuplexHandler {
|
||||
@@ -136,4 +308,9 @@ public class BukkitNetworkManager implements PacketSender, PipelineInjector {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isFakeChannel(Object channel) {
|
||||
return channel.getClass().getSimpleName().equals("FakeChannel")
|
||||
|| channel.getClass().getSimpleName().equals("SpoofedChannel");
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ import net.momirealms.customnameplates.bukkit.util.BiomeUtils;
|
||||
import net.momirealms.customnameplates.bukkit.util.EntityData;
|
||||
import net.momirealms.customnameplates.bukkit.util.Reflections;
|
||||
import net.momirealms.customnameplates.common.util.TriConsumer;
|
||||
import net.momirealms.customnameplates.common.util.UUIDUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
@@ -44,9 +45,12 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class BukkitPlatform implements Platform {
|
||||
|
||||
private static final Pattern LANG_PATTERN = Pattern.compile("<lang:[a-zA-Z0-9._/]+>");
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
private final boolean placeholderAPI;
|
||||
private final boolean geyser;
|
||||
@@ -86,6 +90,11 @@ public class BukkitPlatform implements Platform {
|
||||
}
|
||||
|
||||
static {
|
||||
// ThrowableFunction<Object, String> scoreContentNameFunction = VersionHelper.isVersionNewerThan1_21_2() ? (o -> {
|
||||
// @SuppressWarnings("unchecked")
|
||||
// Optional<String> optional = (Optional<String>) Reflections.method$Either$right.invoke(o);
|
||||
// return optional.orElse(null);
|
||||
// }) : (o -> (String) o);
|
||||
registerPacketConsumer((player, event, packet) -> {
|
||||
if (!ConfigManager.actionbarModule()) return;
|
||||
if (!ConfigManager.catchOtherActionBar()) return;
|
||||
@@ -93,9 +102,9 @@ public class BukkitPlatform implements Platform {
|
||||
Object component = Reflections.field$ClientboundSetActionBarTextPacket$text.get(packet);
|
||||
Object contents = Reflections.method$Component$getContents.invoke(component);
|
||||
if (Reflections.clazz$ScoreContents.isAssignableFrom(contents.getClass())) {
|
||||
String name = (String) Reflections.field$ScoreContents$name.get(contents);
|
||||
//String name = scoreContentNameFunction.apply(Reflections.field$ScoreContents$name.get(contents));
|
||||
String objective = (String) Reflections.field$ScoreContents$objective.get(contents);
|
||||
if (name.equals("np") && objective.equals("ab")) return;
|
||||
if ("actionbar".equals(objective)) return;
|
||||
}
|
||||
CustomNameplates.getInstance().getScheduler().async().execute(() -> {
|
||||
((ActionBarManagerImpl) CustomNameplates.getInstance().getActionBarManager()).handleActionBarPacket(player, AdventureHelper.minecraftComponentToMiniMessage(component));
|
||||
@@ -114,17 +123,29 @@ public class BukkitPlatform implements Platform {
|
||||
if (actionBar) {
|
||||
CustomNameplates.getInstance().getScheduler().async().execute(() -> {
|
||||
try {
|
||||
String miniMessage;
|
||||
if (VersionHelper.isVersionNewerThan1_20_4()) {
|
||||
// 1.20.4+
|
||||
Object component = Reflections.field$ClientboundSystemChatPacket$component.get(packet);
|
||||
if (component == null) return;
|
||||
((ActionBarManagerImpl) CustomNameplates.getInstance().getActionBarManager()).handleActionBarPacket(player, AdventureHelper.minecraftComponentToMiniMessage(component));
|
||||
miniMessage = AdventureHelper.minecraftComponentToMiniMessage(component);
|
||||
} else {
|
||||
// 1.20.4-
|
||||
String json = (String) Reflections.field$ClientboundSystemChatPacket$text.get(packet);
|
||||
if (json == null) return;
|
||||
((ActionBarManagerImpl) CustomNameplates.getInstance().getActionBarManager()).handleActionBarPacket(player, AdventureHelper.jsonToMiniMessage(json));
|
||||
miniMessage = AdventureHelper.jsonToMiniMessage(json);
|
||||
}
|
||||
if (LANG_PATTERN.matcher(miniMessage).find()) {
|
||||
if (ConfigManager.displaySystemChat()) {
|
||||
((ActionBarManagerImpl) CustomNameplates.getInstance().getActionBarManager()).temporarilyHideCustomActionBar(player);
|
||||
Object com = AdventureHelper.miniMessageToMinecraftComponent(miniMessage, "nameplates", "actionbar");
|
||||
Object pkt = CustomNameplates.getInstance().getPlatform().setActionBarTextPacket(com);
|
||||
CustomNameplates.getInstance().getPacketSender().sendPacket(player, pkt);
|
||||
}
|
||||
event.cancelled(true);
|
||||
return;
|
||||
}
|
||||
((ActionBarManagerImpl) CustomNameplates.getInstance().getActionBarManager()).handleActionBarPacket(player, miniMessage);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -183,22 +204,61 @@ public class BukkitPlatform implements Platform {
|
||||
}
|
||||
}, "PacketPlayOutEntityDestroy", "ClientboundRemoveEntitiesPacket");
|
||||
|
||||
// for skin plugin compatibility
|
||||
registerPacketConsumer((player, event, packet) -> {
|
||||
try {
|
||||
UUID pUUID = player.uuid();
|
||||
@SuppressWarnings("unchecked")
|
||||
List<UUID> uuids = (List<UUID>) Reflections.field$ClientboundPlayerInfoRemovePacket$profileIds.get(packet);
|
||||
for (UUID uuid : uuids) {
|
||||
if (uuid.equals(pUUID)) {
|
||||
CNPlayer removed = CustomNameplates.getInstance().getPlayer(uuid);
|
||||
if (removed != null) {
|
||||
removed.removePlayerFromTracker(player);
|
||||
CustomNameplates.getInstance().getUnlimitedTagManager().onRemovePlayer(removed, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CustomNameplates.getInstance().getPluginLogger().severe("Failed to handle ClientboundPlayerInfoRemovePacket", e);
|
||||
}
|
||||
}, "ClientboundPlayerInfoRemovePacket");
|
||||
|
||||
registerPacketConsumer((player, event, packet) -> {
|
||||
try {
|
||||
EnumSet<?> enums = (EnumSet<?>) Reflections.field$ClientboundPlayerInfoUpdatePacket$actions.get(packet);
|
||||
if (enums == null) return;
|
||||
if (!enums.contains(Reflections.enum$ClientboundPlayerInfoUpdatePacket$Action$UPDATE_GAME_MODE)) return;
|
||||
List<Object> entries = (List<Object>) Reflections.field$ClientboundPlayerInfoUpdatePacket$entries.get(packet);
|
||||
for (Object entry : entries) {
|
||||
UUID uuid = (UUID) Reflections.field$ClientboundPlayerInfoUpdatePacket$Entry$profileId.get(entry);
|
||||
if (uuid == null) continue;
|
||||
Object gameType = Reflections.field$ClientboundPlayerInfoUpdatePacket$Entry$gameMode.get(entry);
|
||||
if (gameType == null) continue;
|
||||
int mode = (int) Reflections.method$GameType$getId.invoke(gameType);
|
||||
boolean isSpectator = mode == 3;
|
||||
CNPlayer another = CustomNameplates.getInstance().getPlayer(uuid);
|
||||
if (another != null) {
|
||||
CustomNameplates.getInstance().getUnlimitedTagManager().onPlayerGameModeChange(another, player, isSpectator);
|
||||
UUID pUUID = player.uuid();
|
||||
boolean add_player = enums.contains(Reflections.enum$ClientboundPlayerInfoUpdatePacket$Action$ADD_PLAYER);
|
||||
boolean update_gamemode = enums.contains(Reflections.enum$ClientboundPlayerInfoUpdatePacket$Action$UPDATE_GAME_MODE);
|
||||
if (add_player || update_gamemode) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> entries = (List<Object>) Reflections.field$ClientboundPlayerInfoUpdatePacket$entries.get(packet);
|
||||
for (Object entry : entries) {
|
||||
UUID uuid = (UUID) Reflections.field$ClientboundPlayerInfoUpdatePacket$Entry$profileId.get(entry);
|
||||
if (uuid == null) continue;
|
||||
|
||||
// for skin plugin compatibility
|
||||
if (add_player && uuid.equals(pUUID)) {
|
||||
if (player.isTempPreviewing() || player.isToggleablePreviewing() || CustomNameplates.getInstance().getUnlimitedTagManager().isAlwaysShow()) {
|
||||
Tracker tracker = player.addPlayerToTracker(player);
|
||||
tracker.setScale(player.scale());
|
||||
tracker.setCrouching(player.isCrouching());
|
||||
tracker.setSpectator(player.isSpectator());
|
||||
CustomNameplates.getInstance().getUnlimitedTagManager().onAddPlayer(player, player);
|
||||
}
|
||||
}
|
||||
|
||||
CNPlayer another = CustomNameplates.getInstance().getPlayer(uuid);
|
||||
if (update_gamemode) {
|
||||
Object gameType = Reflections.field$ClientboundPlayerInfoUpdatePacket$Entry$gameMode.get(entry);
|
||||
if (gameType == null) continue;
|
||||
int mode = (int) Reflections.method$GameType$getId.invoke(gameType);
|
||||
boolean isSpectator = mode == 3;
|
||||
if (another != null) {
|
||||
CustomNameplates.getInstance().getUnlimitedTagManager().onPlayerGameModeChange(another, player, isSpectator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
@@ -280,6 +340,84 @@ public class BukkitPlatform implements Platform {
|
||||
CustomNameplates.getInstance().getPluginLogger().severe("Failed to handle ClientboundSetEntityDataPacket", e);
|
||||
}
|
||||
}, "ClientboundSetEntityDataPacket", "PacketPlayOutEntityMetadata");
|
||||
|
||||
// not a perfect solution but would work in most cases
|
||||
registerPacketConsumer((player, event, packet) -> {
|
||||
if (!ConfigManager.nametagModule()) return;
|
||||
if (!ConfigManager.hideTeamNames()) return;
|
||||
try {
|
||||
int method = (int) Reflections.field$ClientboundSetPlayerTeamPacket$method.get(packet);
|
||||
String teamName = (String) Reflections.field$ClientboundSetPlayerTeamPacket$name.get(packet);
|
||||
switch (method) {
|
||||
// create
|
||||
case 0 -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<String> entities = (Collection<String>) Reflections.field$ClientboundSetPlayerTeamPacket$players.get(packet);
|
||||
player.teamView().addTeamMembers(teamName, entities);
|
||||
// additional check for those teams with only one member
|
||||
if (entities.size() <= 1) {
|
||||
for (String entity : entities) {
|
||||
// is a player
|
||||
if (!UUIDUtils.isUUID(entity)) {
|
||||
Player p = Bukkit.getPlayer(entity);
|
||||
// it's a fake player
|
||||
if (p == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<Object> optionalParameters = (Optional<Object>) Reflections.field$ClientboundSetPlayerTeamPacket$parameters.get(packet);
|
||||
if (optionalParameters.isPresent()) {
|
||||
Object parameters = optionalParameters.get();
|
||||
Reflections.field$ClientboundSetPlayerTeamPacket$Parameters$nametagVisibility.set(parameters, "never");
|
||||
}
|
||||
}
|
||||
// remove
|
||||
case 1 -> {
|
||||
player.teamView().removeTeam(teamName);
|
||||
}
|
||||
// update
|
||||
case 2 -> {
|
||||
Set<String> members = player.teamView().getTeamMembers(teamName);
|
||||
if (members == null) return;
|
||||
if (members.size() <= 1) {
|
||||
for (String entity : members) {
|
||||
// is a player
|
||||
if (!UUIDUtils.isUUID(entity)) {
|
||||
Player p = Bukkit.getPlayer(entity);
|
||||
// it's a fake player
|
||||
if (p == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<Object> optionalParameters = (Optional<Object>) Reflections.field$ClientboundSetPlayerTeamPacket$parameters.get(packet);
|
||||
if (optionalParameters.isPresent()) {
|
||||
Object parameters = optionalParameters.get();
|
||||
Reflections.field$ClientboundSetPlayerTeamPacket$Parameters$nametagVisibility.set(parameters, "never");
|
||||
}
|
||||
}
|
||||
// add members
|
||||
case 3 -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<String> entities = (Collection<String>) Reflections.field$ClientboundSetPlayerTeamPacket$players.get(packet);
|
||||
player.teamView().addTeamMembers(teamName, entities);
|
||||
}
|
||||
// remove members
|
||||
case 4 -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<String> entities = (Collection<String>) Reflections.field$ClientboundSetPlayerTeamPacket$players.get(packet);
|
||||
player.teamView().removeTeamMembers(teamName, entities);
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CustomNameplates.getInstance().getPluginLogger().severe("Failed to handle ClientboundSetPlayerTeamPacket", e);
|
||||
}
|
||||
}, "ClientboundSetPlayerTeamPacket", "PacketPlayOutScoreboardTeam");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -512,25 +650,29 @@ public class BukkitPlatform implements Platform {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onPacketSend(CNPlayer player, PacketEvent event) {
|
||||
try {
|
||||
Object packet = event.getPacket();
|
||||
if (Reflections.clazz$ClientboundBundlePacket.isInstance(packet)) {
|
||||
Iterable<Object> packets = (Iterable<Object>) Reflections.field$BundlePacket$packets.get(packet);
|
||||
for (Object p : packets) {
|
||||
handlePacket(player, event, p);
|
||||
}
|
||||
} else {
|
||||
handlePacket(player, event, packet);
|
||||
}
|
||||
onPacketSend(player, event, packet);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePacket(CNPlayer player, PacketEvent event, Object packet) throws ReflectiveOperationException {
|
||||
@SuppressWarnings("unchecked")
|
||||
private void onPacketSend(CNPlayer player, PacketEvent event, Object packet) throws ReflectiveOperationException {
|
||||
if (Reflections.clazz$ClientboundBundlePacket.isInstance(packet)) {
|
||||
Iterable<Object> packets = (Iterable<Object>) Reflections.field$BundlePacket$packets.get(packet);
|
||||
for (Object p : packets) {
|
||||
onPacketSend(player, event, p);
|
||||
}
|
||||
} else {
|
||||
handlePacket(player, event, packet);
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePacket(CNPlayer player, PacketEvent event, Object packet) {
|
||||
Optional.ofNullable(packetFunctions.get(packet.getClass().getSimpleName()))
|
||||
.ifPresent(function -> function.accept(player, event, packet));
|
||||
}
|
||||
|
||||
+2
@@ -19,6 +19,7 @@ package net.momirealms.customnameplates.bukkit.command.feature;
|
||||
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.ConfigManager;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.feature.JoinQuitListener;
|
||||
import net.momirealms.customnameplates.bukkit.BukkitCustomNameplates;
|
||||
import net.momirealms.customnameplates.bukkit.command.BukkitCommandFeature;
|
||||
@@ -45,6 +46,7 @@ public class NameplatesPreviewCommand extends BukkitCommandFeature<CommandSender
|
||||
.senderType(Player.class)
|
||||
.handler(context -> {
|
||||
if (!ConfigManager.nametagModule()) return;
|
||||
if (CustomNameplates.getInstance().getUnlimitedTagManager().isAlwaysShow()) return;
|
||||
CNPlayer player = plugin.getPlayer(context.sender().getUniqueId());
|
||||
if (player == null) {
|
||||
throw new RuntimeException("Player should not be null");
|
||||
|
||||
+8
@@ -52,6 +52,14 @@ public class BukkitRequirementManager extends AbstractRequirementManager {
|
||||
this.registerGameMode();
|
||||
this.registerBedrock();
|
||||
this.registerDisguise();
|
||||
this.registerPassenger();
|
||||
}
|
||||
|
||||
private void registerPassenger() {
|
||||
this.registerRequirement((args, interval) -> {
|
||||
boolean is = (boolean) args;
|
||||
return new PassengerRequirement(interval, is);
|
||||
}, "is-passenger");
|
||||
}
|
||||
|
||||
private void registerDisguise() {
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.bukkit.requirement.builtin;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.backend.requirement.AbstractRequirement;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PassengerRequirement extends AbstractRequirement {
|
||||
|
||||
private final boolean is;
|
||||
|
||||
public PassengerRequirement(int refreshInterval, boolean is) {
|
||||
super(refreshInterval);
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSatisfied(CNPlayer p1, CNPlayer p2) {
|
||||
return ((Player) p1.player()).isInsideVehicle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return "is-passenger";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof PassengerRequirement that)) return false;
|
||||
return is == that.is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(is);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.bukkit.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ListMonitor<T> implements List<T> {
|
||||
|
||||
private final List<T> list;
|
||||
private final Consumer<T> addConsumer;
|
||||
private final Consumer<Object> removeConsumer;
|
||||
|
||||
public ListMonitor(List<T> list, Consumer<T> addConsumer, Consumer<Object> removeConsumer) {
|
||||
for (T key : list) {
|
||||
addConsumer.accept(key);
|
||||
}
|
||||
this.list = list;
|
||||
this.addConsumer = addConsumer;
|
||||
this.removeConsumer = removeConsumer;
|
||||
}
|
||||
|
||||
public List<T> list() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public Consumer<T> addConsumer() {
|
||||
return addConsumer;
|
||||
}
|
||||
|
||||
public Consumer<Object> removeConsumer() {
|
||||
return removeConsumer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean add(T t) {
|
||||
addConsumer.accept(t);
|
||||
return list.add(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean addAll(@NotNull Collection<? extends T> c) {
|
||||
for (T element : c) {
|
||||
addConsumer.accept(element);
|
||||
}
|
||||
return list.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean addAll(int index, @NotNull Collection<? extends T> c) {
|
||||
for (T element : c) {
|
||||
addConsumer.accept(element);
|
||||
}
|
||||
return list.addAll(index, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(int index, T element) {
|
||||
addConsumer.accept(element);
|
||||
list.add(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean remove(Object o) {
|
||||
removeConsumer.accept(o);
|
||||
return list.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAll(@NotNull Collection<?> collection) {
|
||||
for (Object o : collection) {
|
||||
removeConsumer.accept(o);
|
||||
}
|
||||
return list.removeAll(collection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void clear() {
|
||||
for (T element : list) {
|
||||
removeConsumer.accept(element);
|
||||
}
|
||||
list.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmpty() {
|
||||
return list.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean contains(Object o) {
|
||||
return list.contains(o);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public synchronized Iterator<T> iterator() {
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public synchronized Object[] toArray() {
|
||||
return list.toArray();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public synchronized <E> E[] toArray(@NotNull E[] a) {
|
||||
return list.toArray(a);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public synchronized List<T> subList(int fromIndex, int toIndex) {
|
||||
return list.subList(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@Override
|
||||
public synchronized boolean containsAll(@NotNull Collection<?> c) {
|
||||
return list.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean retainAll(@NotNull Collection<?> c) {
|
||||
return list.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized T get(int index) {
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized T set(int index, T element) {
|
||||
return list.set(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized T remove(int index) {
|
||||
return list.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int indexOf(Object o) {
|
||||
return list.indexOf(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int lastIndexOf(Object o) {
|
||||
return list.lastIndexOf(o);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public synchronized ListIterator<T> listIterator() {
|
||||
return list.listIterator();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public synchronized ListIterator<T> listIterator(int index) {
|
||||
return list.listIterator(index);
|
||||
}
|
||||
}
|
||||
@@ -18,15 +18,13 @@
|
||||
package net.momirealms.customnameplates.bukkit.util;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import net.momirealms.customnameplates.api.helper.VersionHelper;
|
||||
import net.momirealms.customnameplates.common.util.ReflectionUtils;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@@ -51,6 +49,14 @@ public class Reflections {
|
||||
).get(0)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$Either = ReflectionUtils.getClazz(
|
||||
"com.mojang.datafixers.util.Either"
|
||||
);
|
||||
|
||||
public static final Method method$Either$right = Optional.ofNullable(clazz$Either)
|
||||
.map(it -> ReflectionUtils.getMethod(it, new String[]{"right"}))
|
||||
.orElse(null);
|
||||
|
||||
public static final Class<?> clazz$ScoreContents = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("network.chat.contents.ScoreContents")
|
||||
@@ -58,12 +64,20 @@ public class Reflections {
|
||||
);
|
||||
|
||||
public static final Field field$ScoreContents$name = requireNonNull(
|
||||
VersionHelper.isVersionNewerThan1_21_2() ?
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ScoreContents, clazz$Either, 0
|
||||
) :
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ScoreContents, String.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ScoreContents$objective = requireNonNull(
|
||||
VersionHelper.isVersionNewerThan1_21_2() ?
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ScoreContents, String.class, 0
|
||||
) :
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ScoreContents, String.class, 1
|
||||
)
|
||||
@@ -289,7 +303,7 @@ public class Reflections {
|
||||
public static final Object instance$MinecraftRegistry;
|
||||
|
||||
static {
|
||||
if (VersionHelper.isVersionNewerThan1_20()) {
|
||||
if (VersionHelper.isVersionNewerThan1_20_5()) {
|
||||
try {
|
||||
Method method = requireNonNull(ReflectionUtils.getMethod(clazz$CraftRegistry, new String[]{"getMinecraftRegistry"}));
|
||||
instance$MinecraftRegistry = method.invoke(null);
|
||||
@@ -415,6 +429,18 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$ClientboundPlayerInfoRemovePacket = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundPlayerInfoRemovePacket")
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundPlayerInfoRemovePacket$profileIds = requireNonNull(
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ClientboundPlayerInfoRemovePacket, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundRemoveEntitiesPacket$entityIds = requireNonNull(
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ClientboundRemoveEntitiesPacket, 0
|
||||
@@ -805,7 +831,7 @@ public class Reflections {
|
||||
);
|
||||
|
||||
public static final Enum<?> enum$ClientboundPlayerInfoUpdatePacket$Action$UPDATE_GAME_MODE;
|
||||
|
||||
public static final Enum<?> enum$ClientboundPlayerInfoUpdatePacket$Action$ADD_PLAYER;
|
||||
|
||||
static {
|
||||
Enum<?> updateGameMode;
|
||||
@@ -815,6 +841,14 @@ public class Reflections {
|
||||
updateGameMode = Enum.valueOf((Class<Enum>) clazz$ClientboundPlayerInfoUpdatePacket$Action, "c");
|
||||
}
|
||||
enum$ClientboundPlayerInfoUpdatePacket$Action$UPDATE_GAME_MODE = updateGameMode;
|
||||
|
||||
Enum<?> addPlayer;
|
||||
try {
|
||||
addPlayer = Enum.valueOf((Class<Enum>) clazz$ClientboundPlayerInfoUpdatePacket$Action, "ADD_PLAYER");
|
||||
} catch (Exception e) {
|
||||
addPlayer = Enum.valueOf((Class<Enum>) clazz$ClientboundPlayerInfoUpdatePacket$Action, "a");
|
||||
}
|
||||
enum$ClientboundPlayerInfoUpdatePacket$Action$ADD_PLAYER = addPlayer;
|
||||
}
|
||||
|
||||
public static final Class<?> clazz$ClientboundPlayerInfoUpdatePacket$Entry = requireNonNull(
|
||||
@@ -988,4 +1022,79 @@ public class Reflections {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Class<?> clazz$ClientboundSetPlayerTeamPacket = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetPlayerTeamPacket"),
|
||||
BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutScoreboardTeam")
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundSetPlayerTeamPacket$method = requireNonNull(
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ClientboundSetPlayerTeamPacket, int.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundSetPlayerTeamPacket$players = requireNonNull(
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ClientboundSetPlayerTeamPacket, Collection.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundSetPlayerTeamPacket$name = requireNonNull(
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ClientboundSetPlayerTeamPacket, String.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundSetPlayerTeamPacket$parameters = requireNonNull(
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ClientboundSetPlayerTeamPacket, Optional.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$ClientboundSetPlayerTeamPacket$Parameters = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetPlayerTeamPacket$Parameters"),
|
||||
BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutScoreboardTeam$b")
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundSetPlayerTeamPacket$Parameters$nametagVisibility = requireNonNull(
|
||||
ReflectionUtils.getInstanceDeclaredField(
|
||||
clazz$ClientboundSetPlayerTeamPacket$Parameters, String.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$ServerConnectionListener = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("server.network.ServerConnectionListener"),
|
||||
BukkitReflectionUtils.assembleMCClass("server.network.ServerConnection")
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$MinecraftServer$connection = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(clazz$MinecraftServer, clazz$ServerConnectionListener, 0)
|
||||
);
|
||||
|
||||
public static final Field field$ServerConnectionListener$channels;
|
||||
|
||||
static {
|
||||
Field[] fields = clazz$ServerConnectionListener.getDeclaredFields();
|
||||
Field f = null;
|
||||
for (Field field : fields) {
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
Type genericType = field.getGenericType();
|
||||
if (genericType instanceof ParameterizedType paramType) {
|
||||
Type[] actualTypeArguments = paramType.getActualTypeArguments();
|
||||
if (actualTypeArguments.length > 0 && actualTypeArguments[0] == ChannelFuture.class) {
|
||||
f = ReflectionUtils.setAccessible(field);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
field$ServerConnectionListener$channels = requireNonNull(f);
|
||||
}
|
||||
}
|
||||
@@ -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.bukkit.util;
|
||||
|
||||
import net.momirealms.customnameplates.api.util.Vector3;
|
||||
|
||||
public class SimpleLocation {
|
||||
|
||||
private String world;
|
||||
private Vector3 position;
|
||||
|
||||
public SimpleLocation(String world, Vector3 position) {
|
||||
this.world = world;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public String world() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public void world(String world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public Vector3 position() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void position(Vector3 position) {
|
||||
this.position = position;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ softdepend:
|
||||
- AdvancedChat
|
||||
- VentureChat
|
||||
- EssentialsChat
|
||||
- WorldGuard
|
||||
permissions:
|
||||
nameplates.command.equip:
|
||||
default: true
|
||||
|
||||
+6
-2
@@ -154,7 +154,7 @@ public class MiniMessageTranslationRegistryImpl implements Examinable, MiniMessa
|
||||
}
|
||||
|
||||
public static class ArgumentTag implements TagResolver {
|
||||
private static final String NAME = "argument";
|
||||
private static final String NAME_0 = "argument";
|
||||
private static final String NAME_1 = "arg";
|
||||
|
||||
private final List<? extends ComponentLike> argumentComponents;
|
||||
@@ -165,6 +165,10 @@ public class MiniMessageTranslationRegistryImpl implements Examinable, MiniMessa
|
||||
|
||||
@Override
|
||||
public @Nullable Tag resolve(final @NotNull String name, final @NotNull ArgumentQueue arguments, final @NotNull Context ctx) throws ParsingException {
|
||||
if (!has(name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int index = arguments.popOr("No argument number provided").asInt().orElseThrow(() -> ctx.newException("Invalid argument number", arguments));
|
||||
|
||||
if (index < 0 || index >= argumentComponents.size()) {
|
||||
@@ -176,7 +180,7 @@ public class MiniMessageTranslationRegistryImpl implements Examinable, MiniMessa
|
||||
|
||||
@Override
|
||||
public boolean has(final @NotNull String name) {
|
||||
return name.equals(NAME) || name.equals(NAME_1);
|
||||
return name.equals(NAME_0) || name.equals(NAME_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -22,6 +22,7 @@ import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.translation.Translator;
|
||||
import net.momirealms.customnameplates.common.plugin.CustomNameplatesProperties;
|
||||
import net.momirealms.customnameplates.common.plugin.NameplatesPlugin;
|
||||
import net.momirealms.customnameplates.common.util.Pair;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -39,7 +40,6 @@ public class TranslationManager {
|
||||
|
||||
private static final Locale DEFAULT_LOCALE = Locale.ENGLISH;
|
||||
private static Locale FORCE_LOCALE = null;
|
||||
private static final List<String> locales = List.of("en", "zh_cn");
|
||||
private static TranslationManager instance;
|
||||
|
||||
private final NameplatesPlugin plugin;
|
||||
@@ -63,7 +63,9 @@ public class TranslationManager {
|
||||
MiniMessageTranslator.translator().removeSource(this.registry);
|
||||
this.installed.clear();
|
||||
}
|
||||
for (String lang : locales) {
|
||||
|
||||
String supportedLocales = CustomNameplatesProperties.getValue("lang");
|
||||
for (String lang : supportedLocales.split(",")) {
|
||||
this.plugin.getConfigManager().saveResource("translations/" + lang + ".yml");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.common.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum MoonPhase {
|
||||
|
||||
FULL_MOON(0L),
|
||||
WANING_GIBBOUS(1L),
|
||||
LAST_QUARTER(2L),
|
||||
WANING_CRESCENT(3L),
|
||||
NEW_MOON(4L),
|
||||
WAXING_CRESCENT(5L),
|
||||
FIRST_QUARTER(6L),
|
||||
WAXING_GIBBOUS(7L);
|
||||
|
||||
private final long day;
|
||||
|
||||
MoonPhase(long day) {
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
private static final Map<Long, MoonPhase> BY_DAY = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (MoonPhase phase : values()) {
|
||||
BY_DAY.put(phase.day, phase);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MoonPhase getPhase(long day) {
|
||||
return BY_DAY.get(day % 8L);
|
||||
}
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package net.momirealms.customnameplates.common.util;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ThrowableFunction<T, R> extends Function<T, R> {
|
||||
|
||||
@Override
|
||||
default R apply(T t) {
|
||||
try {
|
||||
return applyWithException(t);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
R applyWithException(T t) throws Exception;
|
||||
}
|
||||
@@ -39,6 +39,21 @@ public class UUIDUtils {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the id is a UUID
|
||||
*
|
||||
* @param id id
|
||||
* @return true if it's a UUID
|
||||
*/
|
||||
public static boolean isUUID(String id) {
|
||||
try {
|
||||
UUID.fromString(id);
|
||||
return true;
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link UUID} object to a string without dashes.
|
||||
*
|
||||
|
||||
@@ -27,4 +27,5 @@ h2-driver=${h2_driver_version}
|
||||
sqlite-driver=${sqlite_driver_version}
|
||||
byte-buddy=${byte_buddy_version}
|
||||
commons-io=${commons_io_version}
|
||||
lwjgl=${lwjgl_version}
|
||||
lwjgl=${lwjgl_version}
|
||||
lang=${lang}
|
||||
@@ -11,11 +11,16 @@ repositories {
|
||||
maven("https://repo.essentialsx.net/releases/") // ess
|
||||
maven("https://repo.md-5.net/content/groups/public/") // disguise
|
||||
maven("https://repo.opencollab.dev/main/") // geyser
|
||||
maven("https://maven.enginehub.org/repo/") // worldguard worldedit
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(":api"))
|
||||
compileOnly(project(":common"))
|
||||
compileOnly(project(":backend"))
|
||||
compileOnly("dev.dejvokep:boosted-yaml:${rootProject.properties["boosted_yaml_version"]}")
|
||||
// WorldGuard
|
||||
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.9")
|
||||
// Platform
|
||||
compileOnly("dev.folia:folia-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT")
|
||||
// Chat
|
||||
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.bukkit.compatibility;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.CustomNameplatesAPI;
|
||||
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.common.util.MoonPhase;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
public class NameplatesExtraExpansion extends PlaceholderExpansion {
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
|
||||
public NameplatesExtraExpansion(CustomNameplates plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getIdentifier() {
|
||||
return "npex";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getAuthor() {
|
||||
return "XiaoMoMi";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getVersion() {
|
||||
return "3.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String onRequest(OfflinePlayer player, @NotNull String params) {
|
||||
String[] split = params.split("_", 2);
|
||||
if (split.length == 0) {
|
||||
return null;
|
||||
}
|
||||
switch (split[0]) {
|
||||
case "offset" -> {
|
||||
if (split.length != 2) {
|
||||
return null;
|
||||
}
|
||||
return OffsetFont.createOffsets(Float.parseFloat(split[1]));
|
||||
}
|
||||
case "background" -> {
|
||||
if (split.length != 2) {
|
||||
return null;
|
||||
}
|
||||
String subParams = split[1];
|
||||
String[] subSplit = subParams.split(":", 4);
|
||||
// 0 1 2 3
|
||||
// config:left:right:advance
|
||||
Optional<Background> optional = CustomNameplatesAPI.getInstance().getBackground(subSplit[0]);
|
||||
float advance;
|
||||
try {
|
||||
advance = Float.parseFloat(subSplit[3]);
|
||||
} catch (NumberFormatException e) {
|
||||
String text;
|
||||
if (subSplit[3].startsWith("{") && subSplit[3].endsWith("}")) {
|
||||
String before = "%" + subSplit[3].substring(1, subSplit[3].length() - 1) + "%";
|
||||
text = PlaceholderAPI.setPlaceholders(player, before);
|
||||
advance = Float.parseFloat(text);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
float finalAdvance = advance;
|
||||
return optional.map(background ->
|
||||
AdventureHelper.surroundWithNameplatesFont(background.createImage(finalAdvance, Float.parseFloat(subSplit[1]), Float.parseFloat(subSplit[2]))))
|
||||
.orElse(null);
|
||||
}
|
||||
case "nameplate" -> {
|
||||
if (split.length != 2) {
|
||||
return null;
|
||||
}
|
||||
String subParams = split[1];
|
||||
String[] subSplit = subParams.split(":", 4);
|
||||
// 0 1 2 3
|
||||
// config:left:right:advance
|
||||
Optional<Nameplate> optional = CustomNameplatesAPI.getInstance().getNameplate(subSplit[0]);
|
||||
float advance;
|
||||
try {
|
||||
advance = Float.parseFloat(subSplit[3]);
|
||||
} catch (NumberFormatException e) {
|
||||
String text;
|
||||
if (subSplit[3].startsWith("{") && subSplit[3].endsWith("}")) {
|
||||
String before = "%" + subSplit[3].substring(1, subSplit[3].length() - 1) + "%";
|
||||
text = PlaceholderAPI.setPlaceholders(player, before);
|
||||
advance = Float.parseFloat(text);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
float finalAdvance = advance;
|
||||
return optional.map(nameplate ->
|
||||
AdventureHelper.surroundWithNameplatesFont(nameplate.createImage(finalAdvance, Float.parseFloat(subSplit[1]), Float.parseFloat(subSplit[2]))))
|
||||
.orElse(null);
|
||||
}
|
||||
case "bubble" -> {
|
||||
if (split.length != 2) {
|
||||
return null;
|
||||
}
|
||||
String subParams = split[1];
|
||||
String[] subSplit = subParams.split(":", 4);
|
||||
// 0 1 2 3
|
||||
// config:left:right:advance
|
||||
Optional<Bubble> optional = CustomNameplatesAPI.getInstance().getBubble(subSplit[0]);
|
||||
float advance;
|
||||
try {
|
||||
advance = Float.parseFloat(subSplit[3]);
|
||||
} catch (NumberFormatException e) {
|
||||
String text;
|
||||
if (subSplit[3].startsWith("{") && subSplit[3].endsWith("}")) {
|
||||
String before = "%" + subSplit[3].substring(1, subSplit[3].length() - 1) + "%";
|
||||
text = PlaceholderAPI.setPlaceholders(player, before);
|
||||
advance = Float.parseFloat(text);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
float finalAdvance = advance;
|
||||
return optional.map(bubble ->
|
||||
AdventureHelper.surroundWithNameplatesFont(bubble.createImage(finalAdvance, Float.parseFloat(subSplit[1]), Float.parseFloat(subSplit[2]))))
|
||||
.orElse(null);
|
||||
}
|
||||
case "lunarphase" -> {
|
||||
if (split.length == 1 && player != null && player.isOnline()) {
|
||||
Player online = player.getPlayer();
|
||||
if (online == null) return null;
|
||||
return MoonPhase.getPhase(online.getWorld().getFullTime() / 24_000).name().toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
if (split.length == 2) {
|
||||
String world = split[1];
|
||||
World bukkitWorld = Bukkit.getWorld(world);
|
||||
if (bukkitWorld == null) return null;
|
||||
return MoonPhase.getPhase(bukkitWorld.getFullTime() / 24_000).name().toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case "weather" -> {
|
||||
World world = null;
|
||||
if (split.length == 1 && player != null && player.isOnline()) {
|
||||
Player online = player.getPlayer();
|
||||
if (online == null) return null;
|
||||
world = online.getWorld();
|
||||
}
|
||||
if (split.length == 2) {
|
||||
World bukkitWorld = Bukkit.getWorld(split[1]);
|
||||
if (bukkitWorld == null) return null;
|
||||
world = bukkitWorld;
|
||||
}
|
||||
if (world == null) return null;
|
||||
String currentWeather;
|
||||
if (world.isClearWeather()) currentWeather = "clear";
|
||||
else if (world.isThundering()) currentWeather = "thunder";
|
||||
else currentWeather = "rain";
|
||||
return currentWeather;
|
||||
}
|
||||
case "time12" -> {
|
||||
long time;
|
||||
if (split.length == 1 && player != null && player.isOnline()) {
|
||||
Player online = player.getPlayer();
|
||||
if (online == null) return null;
|
||||
time = online.getWorld().getTime();
|
||||
} else if (split.length == 2) {
|
||||
String world = split[1];
|
||||
World bukkitWorld = Bukkit.getWorld(world);
|
||||
if (bukkitWorld == null) return null;
|
||||
time = bukkitWorld.getTime();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
String ap = time >= 6000 && time < 18000 ? " PM" : " AM";
|
||||
int hours = (int) (time / 1000) ;
|
||||
int minutes = (int) ((time - hours * 1000 ) * 0.06);
|
||||
hours += 6;
|
||||
while (hours >= 12) hours -= 12;
|
||||
if (minutes < 10) return hours + ":0" + minutes + ap;
|
||||
else return hours + ":" + minutes + ap;
|
||||
}
|
||||
case "time24" -> {
|
||||
long time;
|
||||
if (split.length == 1 && player != null && player.isOnline()) {
|
||||
Player online = player.getPlayer();
|
||||
if (online == null) return null;
|
||||
time = online.getWorld().getTime();
|
||||
} else if (split.length == 2) {
|
||||
String world = split[1];
|
||||
World bukkitWorld = Bukkit.getWorld(world);
|
||||
if (bukkitWorld == null) return null;
|
||||
time = bukkitWorld.getTime();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
int hours = (int) (time / 1000);
|
||||
int minutes = (int) ((time - hours * 1000) * 0.06);
|
||||
hours += 6;
|
||||
if (hours >= 24) hours -= 24;
|
||||
String minuteStr = (minutes < 10) ? "0" + minutes : String.valueOf(minutes);
|
||||
return hours + ":" + minuteStr;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+16
-5
@@ -17,7 +17,9 @@
|
||||
|
||||
package net.momirealms.customnameplates.bukkit.compatibility.chat;
|
||||
|
||||
import net.essentialsx.api.v2.events.chat.ChatEvent;
|
||||
import net.essentialsx.api.v2.ChatType;
|
||||
import net.essentialsx.api.v2.events.chat.GlobalChatEvent;
|
||||
import net.essentialsx.api.v2.events.chat.LocalChatEvent;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.feature.chat.AbstractChatMessageProvider;
|
||||
@@ -52,15 +54,24 @@ public class EssentialsChatProvider extends AbstractChatMessageProvider implemen
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEssChat(ChatEvent event) {
|
||||
String channel = event.getChatType().key();
|
||||
Player player = Bukkit.getPlayer(event.getPlayer().getUniqueId());
|
||||
public void onEssChat(LocalChatEvent event) {
|
||||
onChat(event.getChatType(), event.getPlayer(), event.getMessage());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEssChat(GlobalChatEvent event) {
|
||||
onChat(event.getChatType(), event.getPlayer(), event.getMessage());
|
||||
}
|
||||
|
||||
private void onChat(ChatType chatType, Player player2, String message) {
|
||||
String channel = chatType.key();
|
||||
Player player = Bukkit.getPlayer(player2.getUniqueId());
|
||||
if (player == null || !player.isOnline())
|
||||
return;
|
||||
CNPlayer cnPlayer = plugin.getPlayer(player.getUniqueId());
|
||||
if (cnPlayer == null)
|
||||
return;
|
||||
plugin.getScheduler().async().execute(() -> manager.onChat(cnPlayer, event.getMessage(), channel));
|
||||
plugin.getScheduler().async().execute(() -> manager.onChat(cnPlayer, message, channel));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
-2
@@ -24,14 +24,24 @@ import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.api.feature.chat.emoji.EmojiProvider;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class OraxenEmojiProvider implements EmojiProvider {
|
||||
|
||||
private final FontManager fontManager;
|
||||
|
||||
public OraxenEmojiProvider() {
|
||||
this.fontManager = OraxenPlugin.get().getFontManager();
|
||||
public OraxenEmojiProvider(int version) {
|
||||
if (version == 1) {
|
||||
this.fontManager = OraxenPlugin.get().getFontManager();
|
||||
} else {
|
||||
try {
|
||||
Method fm = OraxenPlugin.class.getMethod("fontManager");
|
||||
this.fontManager = (FontManager) fm.invoke(OraxenPlugin.get());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customnameplates.bukkit.compatibility.region;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import net.momirealms.customnameplates.api.CNPlayer;
|
||||
import net.momirealms.customnameplates.backend.requirement.AbstractRequirement;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RegionRequirement extends AbstractRequirement {
|
||||
|
||||
private final List<String> regions;
|
||||
private final int mode;
|
||||
|
||||
public RegionRequirement(int refreshInterval, int mode, Collection<String> regions) {
|
||||
super(refreshInterval);
|
||||
this.regions = new ArrayList<>(regions);
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSatisfied(CNPlayer p1, CNPlayer p2) {
|
||||
Location location = ((Player) p1.player()).getLocation();
|
||||
RegionManager regionManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(location.getWorld()));
|
||||
if (regionManager != null) {
|
||||
ApplicableRegionSet set = regionManager.getApplicableRegions(BlockVector3.at(location.getBlockX(), location.getBlockY(), location.getBlockZ()));
|
||||
if (mode == 1) {
|
||||
for (ProtectedRegion region : set) {
|
||||
if (regions.contains(region.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (mode == 2) {
|
||||
outer: {
|
||||
Set<String> ids = set.getRegions().stream().map(ProtectedRegion::getId).collect(Collectors.toSet());
|
||||
for (String region : regions) {
|
||||
if (!ids.contains(region)) {
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return "region";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof RegionRequirement that)) return false;
|
||||
return mode == that.mode && Objects.equal(regions, that.regions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(regions, mode);
|
||||
}
|
||||
}
|
||||
+51
@@ -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.bukkit.compatibility.region;
|
||||
|
||||
import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
import net.momirealms.customnameplates.api.CustomNameplates;
|
||||
import net.momirealms.customnameplates.api.requirement.EmptyRequirement;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class WorldGuardRegion {
|
||||
|
||||
public static void register() {
|
||||
CustomNameplates.getInstance().getRequirementManager().registerRequirement((args, interval) -> {
|
||||
HashSet<String> regions = new HashSet<>();
|
||||
int mode = 1;
|
||||
if (args instanceof Section section) {
|
||||
mode = section.getInt("mode", 1);
|
||||
regions.addAll(section.getStringList("values"));
|
||||
} else {
|
||||
if (args instanceof List<?> list) {
|
||||
for (Object o : list) {
|
||||
if (o instanceof String) {
|
||||
regions.add((String) o);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CustomNameplates.getInstance().getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at region requirement which is expected be `Section` or `StringList`");
|
||||
return EmptyRequirement.instance();
|
||||
}
|
||||
}
|
||||
return new RegionRequirement(interval, mode, regions);
|
||||
}, "region");
|
||||
}
|
||||
}
|
||||
+11
-7
@@ -1,17 +1,20 @@
|
||||
# Project settings
|
||||
# Rule: [major update].[feature update].[bug fix]
|
||||
project_version=3.0.1
|
||||
config_version=29
|
||||
project_version=3.0.10
|
||||
config_version=32
|
||||
project_group=net.momirealms
|
||||
|
||||
# Supported languages
|
||||
lang=en,zh_cn
|
||||
|
||||
# Dependency settings
|
||||
paper_version=1.20.4
|
||||
jetbrains_annotations_version=24.0.0
|
||||
slf4j_version=2.0.13
|
||||
log4j_version=2.23.1
|
||||
gson_version=2.10.1
|
||||
asm_version=9.7
|
||||
asm_commons_version=9.7
|
||||
gson_version=2.11.0
|
||||
asm_version=9.7.1
|
||||
asm_commons_version=9.7.1
|
||||
jar_relocator_version=1.7
|
||||
h2_driver_version=2.2.224
|
||||
sqlite_driver_version=3.46.1.0
|
||||
@@ -32,15 +35,16 @@ mysql_driver_version=9.0.0
|
||||
hikari_version=5.1.0
|
||||
commons_pool_version=2.12.0
|
||||
bstats_version=3.0.2
|
||||
geantyref_version=1.3.15
|
||||
geantyref_version=1.3.16
|
||||
caffeine_version=3.1.8
|
||||
jedis_version=5.1.5
|
||||
exp4j_version=0.4.8
|
||||
placeholder_api_version=2.11.6
|
||||
vault_version=1.7
|
||||
guava_version=33.2.0-jre
|
||||
guava_version=33.3.1-jre
|
||||
commons_io_version=2.17.0
|
||||
lwjgl_version=3.3.4
|
||||
fastutil_version=8.5.15
|
||||
|
||||
# Proxy settings
|
||||
#systemProp.socks.proxyHost=127.0.0.1
|
||||
|
||||
Reference in new issue
Block a user