9
0
mirror of https://github.com/Xiao-MoMi/Custom-Nameplates.git synced 2025-12-25 09:59:16 +00:00

new text width resolver

This commit is contained in:
XiaoMoMi
2024-01-19 02:16:07 +08:00
parent 8dd4745c15
commit 2c259ad961
236 changed files with 179 additions and 44 deletions

View File

@@ -1,7 +1,5 @@
package net.momirealms.customnameplates.paper;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.momirealms.customnameplates.api.CustomNameplatesPlugin;
import net.momirealms.customnameplates.api.event.CustomNameplatesReloadEvent;
import net.momirealms.customnameplates.api.util.LogUtils;
@@ -90,6 +88,7 @@ public class CustomNameplatesPluginImpl extends CustomNameplatesPlugin {
CNConfig.load();
CNLocale.load();
((SchedulerImpl) this.scheduler).reload();
((AdventureManagerImpl) this.adventureManager).reload();
((WidthManagerImpl) this.widthManager).reload();
((NameplateManagerImpl) this.nameplateManager).reload();
((BackGroundManagerImpl) this.backGroundManager).reload();

View File

@@ -52,11 +52,11 @@ public class AdventureManagerImpl implements AdventureManager {
private final BukkitAudiences adventure;
private static AdventureManager instance;
private final CacheSystem cacheSystem;
private CacheSystem cacheSystem;
public AdventureManagerImpl(CustomNameplatesPlugin plugin) {
this.adventure = BukkitAudiences.create(plugin);
this.cacheSystem = new CacheSystem();
instance = this;
}
@@ -69,6 +69,21 @@ public class AdventureManagerImpl implements AdventureManager {
adventure.close();
}
public void reload() {
if (this.cacheSystem != null) this.cacheSystem.destroy();
this.cacheSystem = new CacheSystem(CNConfig.cacheSize);
}
@Override
public net.momirealms.customnameplates.api.common.Key keyToKey(Key key) {
return net.momirealms.customnameplates.api.common.Key.of(key.namespace(), key.value());
}
@Override
public Key keyToKey(net.momirealms.customnameplates.api.common.Key key) {
return Key.key(key.namespace(), key.value());
}
@Override
public Object getIChatComponentFromMiniMessage(String text) {
return cacheSystem.getIChatFromCache(text);
@@ -272,9 +287,9 @@ public class AdventureManagerImpl implements AdventureManager {
private final LoadingCache<String, Object> miniMessageToIChatComponentCache;
private final LoadingCache<String, Component> miniMessageToComponentCache;
public CacheSystem() {
public CacheSystem(int size) {
miniMessageToIChatComponentCache = CacheBuilder.newBuilder()
.maximumSize(100)
.maximumSize(size)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader<>() {
@@ -285,7 +300,7 @@ public class AdventureManagerImpl implements AdventureManager {
}
});
miniMessageToComponentCache = CacheBuilder.newBuilder()
.maximumSize(100)
.maximumSize(size)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader<>() {
@@ -297,6 +312,11 @@ public class AdventureManagerImpl implements AdventureManager {
});
}
public void destroy() {
miniMessageToComponentCache.cleanUp();
miniMessageToIChatComponentCache.cleanUp();
}
@NotNull
private Object fetchIChatData(String text) {
Component component = getComponentFromMiniMessage(text);

View File

@@ -3,7 +3,6 @@ package net.momirealms.customnameplates.paper.mechanic.bossbar;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.InternalStructure;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import net.momirealms.customnameplates.paper.adventure.AdventureManagerImpl;
import net.momirealms.customnameplates.paper.mechanic.misc.PacketManager;
import net.momirealms.customnameplates.paper.util.ReflectionUtils;

View File

@@ -1,29 +1,43 @@
package net.momirealms.customnameplates.paper.mechanic.font;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import me.clip.placeholderapi.PlaceholderAPI;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.internal.parser.node.ElementNode;
import net.kyori.adventure.text.minimessage.internal.parser.node.TagNode;
import net.kyori.adventure.text.minimessage.internal.parser.node.ValueNode;
import net.kyori.adventure.text.minimessage.tag.Inserting;
import net.momirealms.customnameplates.api.CustomNameplatesPlugin;
import net.momirealms.customnameplates.api.common.Key;
import net.momirealms.customnameplates.api.common.Tuple;
import net.momirealms.customnameplates.api.manager.WidthManager;
import net.momirealms.customnameplates.api.mechanic.font.FontData;
import net.momirealms.customnameplates.api.util.LogUtils;
import net.momirealms.customnameplates.paper.adventure.AdventureManagerImpl;
import net.momirealms.customnameplates.paper.setting.CNConfig;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class WidthManagerImpl implements WidthManager {
private final CustomNameplatesPlugin plugin;
private final HashMap<Key, FontData> fontDataMap;
private char TAG_START = '<';
private char TAG_END = '>';
private char TAG_CLOSE = '/';
private char TAG_ESCAPE = '\\';
private CacheSystem cacheSystem;
public WidthManagerImpl(CustomNameplatesPlugin plugin) {
this.plugin = plugin;
@@ -36,30 +50,37 @@ public class WidthManagerImpl implements WidthManager {
}
public void load() {
YamlConfiguration config = plugin.getConfig("configs" + File.separator + "image-width.yml");
YamlConfiguration config = plugin.getConfig("configs" + File.separator + "font-width-data.yml");
for (Map.Entry<String, Object> entry : config.getValues(false).entrySet()) {
if (entry.getValue() instanceof ConfigurationSection innerSection) {
FontData fontData = new FontData(8);
for (Map.Entry<String, Object> innerEntry : innerSection.getValues(false).entrySet()) {
String key = innerEntry.getKey();
if (key.contains("%") && !key.equals("%")) {
String stripped = AdventureManagerImpl.getInstance().stripTags(AdventureManagerImpl.getInstance().legacyToMiniMessage(PlaceholderAPI.setPlaceholders(null, key)));
if (stripped.length() != 1) {
LogUtils.warn(key + " is not a supported placeholder");
continue;
int defaultWidth = innerSection.getInt("default", 8);
ConfigurationSection customSection = innerSection.getConfigurationSection("values");
if (customSection != null)
for (Map.Entry<String, Object> innerEntry : customSection.getValues(false).entrySet()) {
String key = innerEntry.getKey();
if (key.contains("%") && !key.equals("%")) {
String stripped = AdventureManagerImpl.getInstance().stripTags(AdventureManagerImpl.getInstance().legacyToMiniMessage(PlaceholderAPI.setPlaceholders(null, key)));
if (stripped.length() != 1) {
LogUtils.warn(key + " is not a supported placeholder");
continue;
}
fontData.registerCharWidth(stripped.charAt(0), (Integer) innerEntry.getValue());
} else if (key.length() == 1) {
fontData.registerCharWidth(key.charAt(0), (Integer) innerEntry.getValue());
} else {
LogUtils.warn("Illegal image format: " + key);
}
fontData.registerCharWidth(stripped.charAt(0), (Integer) entry.getValue());
} else if (key.length() == 1) {
fontData.registerCharWidth(key.charAt(0), (Integer) entry.getValue());
} else {
LogUtils.warn("Illegal image format: " + key);
}
}
}
}
this.cacheSystem = new CacheSystem(CNConfig.cacheSize);
}
public void unload() {
if (this.cacheSystem != null)
this.cacheSystem.destroy();
fontDataMap.clear();
}
@@ -77,18 +98,6 @@ public class WidthManagerImpl implements WidthManager {
return fontDataMap.remove(key) != null;
}
@Override
public void registerImageWidth(Key key, char c, int width) {
FontData fontData = fontDataMap.get(key);
if (fontData == null) {
FontData newData = new FontData(8);
fontDataMap.put(key, newData);
newData.registerCharWidth(c, width);
} else {
fontData.registerCharWidth(c, width);
}
}
@Nullable
@Override
public FontData getFontData(Key key) {
@@ -97,6 +106,87 @@ public class WidthManagerImpl implements WidthManager {
@Override
public int getTextWidth(String textWithTags) {
return 0;
return cacheSystem.getWidthFromCache(textWithTags);
}
public class CacheSystem {
private final LoadingCache<String, Integer> textWidthCache;
public CacheSystem(int size) {
textWidthCache = CacheBuilder.newBuilder()
.maximumSize(size)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader<>() {
@NotNull
@Override
public Integer load(@NotNull String text) {
return fetchData(text);
}
});
}
private int fetchData(String text) {
if (CNConfig.legacyColorSupport)
text = AdventureManagerImpl.getInstance().legacyToMiniMessage(text);
ElementNode node = (ElementNode) MiniMessage.miniMessage().deserializeToTree(text);
ArrayList<Tuple<String, Key, Boolean>> list = new ArrayList<>();
nodeToStringInfo(node, list, Key.of("minecraft", "default"), false);
int totalLength = 0;
for (Tuple<String, Key, Boolean> element : list) {
FontData data = getFontData(element.getMid());
if (data == null) {
LogUtils.warn("Unknown font: " + element.getMid() + " Please register it in font-width-data.yml");
continue;
}
for (char c : element.getLeft().toCharArray()) {
totalLength += data.getWidth(c);
}
totalLength += element.getRight() ? element.getLeft().length() * 2 : element.getLeft().length();
}
return totalLength;
}
public Component nodeToStringInfo(ElementNode node, List<Tuple<String, Key, Boolean>> list, Key font, boolean isBold) {
if (node instanceof ValueNode valueNode) {
String text = valueNode.value();
if (!text.equals(""))
list.add(Tuple.of(text, font, isBold));
} else if (node instanceof TagNode tagNode) {
if (tagNode.tag() instanceof Inserting inserting) {
Component component = inserting.value();
if (component instanceof TextComponent textComponent) {
isBold = component.hasDecoration(TextDecoration.BOLD);
var key = component.font();
if (key != null) {
font = AdventureManagerImpl.getInstance().keyToKey(key);
}
String text = textComponent.content();
if (!text.equals(""))
list.add(Tuple.of(text, font, isBold));
}
}
}
if (!node.unsafeChildren().isEmpty()) {
for (ElementNode child : node.unsafeChildren()) {
this.nodeToStringInfo(child, list, font, isBold);
}
}
return null;
}
public int getWidthFromCache(String text) {
try {
return textWidthCache.get(text);
} catch (ExecutionException e) {
e.printStackTrace();
return 0;
}
}
public void destroy() {
textWidthCache.cleanUp();
}
}
}

View File

@@ -17,7 +17,6 @@ import net.momirealms.customnameplates.paper.mechanic.team.provider.TABProvider;
import net.momirealms.customnameplates.paper.mechanic.team.provider.TeamProvider;
import net.momirealms.customnameplates.paper.setting.CNConfig;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.PluginMessageListener;
import org.jetbrains.annotations.NotNull;

View File

@@ -20,6 +20,7 @@ import java.util.Objects;
public class CNConfig {
public static String configVersion = "22";
public static int cacheSize;
public static int corePoolSize;
public static long keepAliveTime;
public static int maximumPoolSize;
@@ -124,6 +125,7 @@ public class CNConfig {
corePoolSize = config.getInt("other-settings.thread-pool-settings.corePoolSize", 10);
maximumPoolSize = config.getInt("other-settings.thread-pool-settings.maximumPoolSize", 10);
keepAliveTime = config.getInt("other-settings.thread-pool-settings.keepAliveTime", 30);
cacheSize = config.getInt("other-settings.cache-size", 100);
}
public static boolean isOtherTeamPluginHooked() {

View File

@@ -18,8 +18,6 @@
package net.momirealms.customnameplates.paper.util;
import com.comphenix.protocol.utility.MinecraftReflection;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.momirealms.customnameplates.api.util.LogUtils;
import java.lang.reflect.Constructor;

View File

@@ -100,4 +100,10 @@ other-settings:
# default width
default-character-width: 8
# delay x ticks before actionbar/bossbar is sent to players
send-delay: 0
send-delay: 0
# Set the size for the cache system. This is useful and would bring huge performance if you keep it to a reasonable value
# Many developers don't seem to think that parsing text labels would incur significant performance overhead but actually it does through it's running asynchronously.
# With cache system, you can save much CPU resource when the same message is displayed to many players.
# The more people on your server, the higher the efficiency of the caching system's operation.
# In most cases you don't have to edit this value. You can increase this value appropriately, especially when there are many players on your server.
cache-size: 100

View File

@@ -0,0 +1,22 @@
minecraft:default:
default: 8
template-loading-sequence:
- unifont
- northern_latin
- ascent
- ascii
# The values here would override the same character in the template
values:
'%img_xxx%': 15
: 8
minecraft:alt:
default: 8
template:
ascii: false
alt: true
minecraft:asciillager:
default: 8
template:
asciillager: true

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Some files were not shown because too many files have changed in this diff Show More