Add .editorconfig & reformat
This commit is contained in:
1 parent
d185424979
commit
24ad7bb99f
74 files changed
+3462
-3454
No files matched your search
@@ -0,0 +1,8 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = off
|
||||
@@ -1,3 +1,3 @@
|
||||
plugins {
|
||||
id("net.megavex.scoreboardlibrary.publish-conventions")
|
||||
}
|
||||
id("net.megavex.scoreboardlibrary.publish-conventions")
|
||||
}
|
||||
@@ -2,9 +2,9 @@ package net.megavex.scoreboardlibrary.api;
|
||||
|
||||
public final class ScoreboardLibrary {
|
||||
|
||||
// Concat is used to trick package relocations
|
||||
public static final String NAMESPACE = "net.vytska".concat("lt.scoreboardlibrary");
|
||||
// Concat is used to trick package relocations
|
||||
public static final String NAMESPACE = "net.vytska".concat("lt.scoreboardlibrary");
|
||||
|
||||
private ScoreboardLibrary() {
|
||||
}
|
||||
private ScoreboardLibrary() {
|
||||
}
|
||||
}
|
||||
@@ -16,89 +16,89 @@ import java.util.Locale;
|
||||
|
||||
public interface ScoreboardManager extends Closeable, HasScoreboardManager {
|
||||
|
||||
/**
|
||||
* Gets the ScoreboardManager for a plugin
|
||||
*
|
||||
* @param plugin Plugin
|
||||
* @return ScoreboardManager
|
||||
*/
|
||||
static ScoreboardManager scoreboardManager(JavaPlugin plugin) {
|
||||
return ScoreboardManagerProvider.instance().scoreboardManager(plugin);
|
||||
}
|
||||
/**
|
||||
* Gets the ScoreboardManager for a plugin
|
||||
*
|
||||
* @param plugin Plugin
|
||||
* @return ScoreboardManager
|
||||
*/
|
||||
static ScoreboardManager scoreboardManager(JavaPlugin plugin) {
|
||||
return ScoreboardManagerProvider.instance().scoreboardManager(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
default @NotNull ScoreboardManager scoreboardManager() {
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
default @NotNull ScoreboardManager scoreboardManager() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Plugin owner of this ScoreboardManager
|
||||
*
|
||||
* @return Plugin owner
|
||||
*/
|
||||
@NotNull Plugin plugin();
|
||||
/**
|
||||
* Gets the Plugin owner of this ScoreboardManager
|
||||
*
|
||||
* @return Plugin owner
|
||||
*/
|
||||
@NotNull Plugin plugin();
|
||||
|
||||
/**
|
||||
* Creates a {@link Sidebar}
|
||||
*
|
||||
* @param maxLines Max sidebar lines
|
||||
* @return Sidebar
|
||||
*/
|
||||
default @NotNull Sidebar sidebar(int maxLines) {
|
||||
return sidebar(maxLines, null);
|
||||
}
|
||||
/**
|
||||
* Creates a {@link Sidebar}
|
||||
*
|
||||
* @param maxLines Max sidebar lines
|
||||
* @return Sidebar
|
||||
*/
|
||||
default @NotNull Sidebar sidebar(int maxLines) {
|
||||
return sidebar(maxLines, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Sidebar}
|
||||
*
|
||||
* @param maxLines Max sidebar lines
|
||||
* @param locale Locale which will be used for translating {@link net.kyori.adventure.text.TranslatableComponent}s
|
||||
* or null if the locale should depend on the player
|
||||
* @return Sidebar
|
||||
*/
|
||||
default @NotNull Sidebar sidebar(int maxLines, @Nullable Locale locale) {
|
||||
return sidebar(maxLines, ComponentTranslator.GLOBAL, locale);
|
||||
}
|
||||
/**
|
||||
* Creates a {@link Sidebar}
|
||||
*
|
||||
* @param maxLines Max sidebar lines
|
||||
* @param locale Locale which will be used for translating {@link net.kyori.adventure.text.TranslatableComponent}s
|
||||
* or null if the locale should depend on the player
|
||||
* @return Sidebar
|
||||
*/
|
||||
default @NotNull Sidebar sidebar(int maxLines, @Nullable Locale locale) {
|
||||
return sidebar(maxLines, ComponentTranslator.GLOBAL, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Sidebar}
|
||||
*
|
||||
* @param maxLines Max sidebar lines
|
||||
* @param componentTranslator Component translator
|
||||
* @param locale Locale which will be used for translating {@link net.kyori.adventure.text.TranslatableComponent}s
|
||||
* or null if the locale should depend on the player
|
||||
* @return Sidebar
|
||||
*/
|
||||
@NotNull Sidebar sidebar(int maxLines, @NotNull ComponentTranslator componentTranslator, @Nullable Locale locale);
|
||||
/**
|
||||
* Creates a {@link Sidebar}
|
||||
*
|
||||
* @param maxLines Max sidebar lines
|
||||
* @param componentTranslator Component translator
|
||||
* @param locale Locale which will be used for translating {@link net.kyori.adventure.text.TranslatableComponent}s
|
||||
* or null if the locale should depend on the player
|
||||
* @return Sidebar
|
||||
*/
|
||||
@NotNull Sidebar sidebar(int maxLines, @NotNull ComponentTranslator componentTranslator, @Nullable Locale locale);
|
||||
|
||||
/**
|
||||
* Gets the sidebars associated with this ScoreboardManager
|
||||
*
|
||||
* @return Sidebars
|
||||
*/
|
||||
@NotNull Collection<Sidebar> sidebars();
|
||||
/**
|
||||
* Gets the sidebars associated with this ScoreboardManager
|
||||
*
|
||||
* @return Sidebars
|
||||
*/
|
||||
@NotNull Collection<Sidebar> sidebars();
|
||||
|
||||
/**
|
||||
* Creates a {@link TeamManager} with the global component translator
|
||||
*
|
||||
* @return TeamManager
|
||||
*/
|
||||
default @NotNull TeamManager teamManager() {
|
||||
return teamManager(ComponentTranslator.GLOBAL);
|
||||
}
|
||||
/**
|
||||
* Creates a {@link TeamManager} with the global component translator
|
||||
*
|
||||
* @return TeamManager
|
||||
*/
|
||||
default @NotNull TeamManager teamManager() {
|
||||
return teamManager(ComponentTranslator.GLOBAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link TeamManager}
|
||||
*
|
||||
* @param componentTranslator Component translator
|
||||
* @return TeamManager
|
||||
*/
|
||||
@NotNull TeamManager teamManager(@NotNull ComponentTranslator componentTranslator);
|
||||
/**
|
||||
* Creates a {@link TeamManager}
|
||||
*
|
||||
* @param componentTranslator Component translator
|
||||
* @return TeamManager
|
||||
*/
|
||||
@NotNull TeamManager teamManager(@NotNull ComponentTranslator componentTranslator);
|
||||
|
||||
/**
|
||||
* Gets the team managers associated with this {@link JavaPlugin}
|
||||
*
|
||||
* @return Team Managers
|
||||
*/
|
||||
Collection<TeamManager> teamManagers();
|
||||
/**
|
||||
* Gets the team managers associated with this {@link JavaPlugin}
|
||||
*
|
||||
* @return Team Managers
|
||||
*/
|
||||
Collection<TeamManager> teamManagers();
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package net.megavex.scoreboardlibrary.api.interfaces;
|
||||
|
||||
public interface Closeable {
|
||||
void close();
|
||||
void close();
|
||||
|
||||
boolean closed();
|
||||
boolean closed();
|
||||
}
|
||||
+3
-3
@@ -8,8 +8,8 @@ import java.util.Locale;
|
||||
|
||||
public interface ComponentTranslator {
|
||||
|
||||
ComponentTranslator GLOBAL = GlobalTranslator::render;
|
||||
ComponentTranslator NONE = (component, locale) -> component;
|
||||
ComponentTranslator GLOBAL = GlobalTranslator::render;
|
||||
ComponentTranslator NONE = (component, locale) -> component;
|
||||
|
||||
@NotNull Component translate(@NotNull Component component, @NotNull Locale locale);
|
||||
@NotNull Component translate(@NotNull Component component, @NotNull Locale locale);
|
||||
}
|
||||
+1
-1
@@ -4,5 +4,5 @@ import net.megavex.scoreboardlibrary.api.ScoreboardManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface HasScoreboardManager {
|
||||
@NotNull ScoreboardManager scoreboardManager();
|
||||
@NotNull ScoreboardManager scoreboardManager();
|
||||
}
|
||||
@@ -6,21 +6,21 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface Players {
|
||||
@NotNull Collection<Player> players();
|
||||
@NotNull Collection<Player> players();
|
||||
|
||||
boolean addPlayer(@NotNull Player player);
|
||||
boolean addPlayer(@NotNull Player player);
|
||||
|
||||
boolean removePlayer(@NotNull Player player);
|
||||
boolean removePlayer(@NotNull Player player);
|
||||
|
||||
default void addPlayers(@NotNull Collection<Player> players) {
|
||||
for (Player player : players) {
|
||||
addPlayer(player);
|
||||
}
|
||||
default void addPlayers(@NotNull Collection<Player> players) {
|
||||
for (Player player : players) {
|
||||
addPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
default void removePlayers(@NotNull Collection<Player> players) {
|
||||
for (Player player : players) {
|
||||
removePlayer(player);
|
||||
}
|
||||
default void removePlayers(@NotNull Collection<Player> players) {
|
||||
for (Player player : players) {
|
||||
removePlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
+150
-150
@@ -17,162 +17,162 @@ import static net.kyori.adventure.text.Component.empty;
|
||||
|
||||
public class AbstractSidebar implements HasScoreboardManager, Closeable {
|
||||
|
||||
private static final SidebarLine emptyLine = SidebarLine.staticLine(empty());
|
||||
protected final Sidebar sidebar;
|
||||
private SidebarLine[] lines;
|
||||
private static final SidebarLine emptyLine = SidebarLine.staticLine(empty());
|
||||
protected final Sidebar sidebar;
|
||||
private SidebarLine[] lines;
|
||||
|
||||
public AbstractSidebar(@NotNull Sidebar sidebar) {
|
||||
this.sidebar = sidebar;
|
||||
this.lines = new SidebarLine[sidebar.maxLines()];
|
||||
public AbstractSidebar(@NotNull Sidebar sidebar) {
|
||||
this.sidebar = sidebar;
|
||||
this.lines = new SidebarLine[sidebar.maxLines()];
|
||||
}
|
||||
|
||||
public final @NotNull Sidebar sidebar() {
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
protected void onClosed() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a line
|
||||
*
|
||||
* @param lineSupplier Line to update
|
||||
*/
|
||||
protected final void updateLine(@NotNull SidebarLine lineSupplier) {
|
||||
checkClosed();
|
||||
Preconditions.checkNotNull(lineSupplier);
|
||||
Preconditions.checkArgument(!lineSupplier.lineStatic());
|
||||
sidebar.line(lineSupplier.line(), lineSupplier.computeValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a line
|
||||
*
|
||||
* @param line Line to unregister
|
||||
* @return Unregistered line
|
||||
*/
|
||||
protected final @Nullable SidebarLine unregisterLine(int line) {
|
||||
SidebarLine lineSupplier = lines[line];
|
||||
if (lineSupplier == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final @NotNull Sidebar sidebar() {
|
||||
return sidebar;
|
||||
lines[line] = null;
|
||||
sidebar.line(line, null);
|
||||
return lineSupplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a static line for this AbstractSidebar
|
||||
*
|
||||
* @param line Line to register
|
||||
* @param value Static value
|
||||
*/
|
||||
protected final @NotNull SidebarLine registerStaticLine(int line, @NotNull Component value) {
|
||||
SidebarLine sidebarLine = SidebarLine.staticLine(value);
|
||||
registerLine(line, sidebarLine);
|
||||
return sidebarLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a line for this AbstractSidebar
|
||||
*
|
||||
* @param line Line to register
|
||||
* @param supplier Supplier
|
||||
* @return The created LineSupplier
|
||||
*/
|
||||
protected final SidebarLine registerLine(int line, @NotNull Supplier<Component> supplier) {
|
||||
checkClosed();
|
||||
Preconditions.checkNotNull(supplier);
|
||||
|
||||
return registerLine(line, new SidebarLine() {
|
||||
@Override
|
||||
public boolean lineStatic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int line() {
|
||||
return line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component computeValue() {
|
||||
return supplier.get();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a line for this AbstractSidebar
|
||||
*
|
||||
* @param line Line to register
|
||||
* @param supplier Supplier
|
||||
* @return The same LineSupplier for convenience
|
||||
*/
|
||||
protected final <S extends SidebarLine> S registerLine(int line, @NotNull S supplier) {
|
||||
checkClosed();
|
||||
Objects.requireNonNull(supplier);
|
||||
|
||||
SidebarUtilities.checkLineBounds(line);
|
||||
if (lines[line] != null) {
|
||||
throw new IllegalStateException("Line " + line + " is already registered");
|
||||
}
|
||||
|
||||
protected void onClosed() {
|
||||
lines[line] = Objects.requireNonNull(supplier, "LineSupplier cannot be null");
|
||||
sidebar.line(line, supplier.computeValue());
|
||||
return supplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an empty line for this AbstractSidebar
|
||||
*
|
||||
* @param line Line to register
|
||||
*/
|
||||
protected final void registerEmptyLine(int line) {
|
||||
registerLine(line, emptyLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the supplier for a line
|
||||
*
|
||||
* @param line Line
|
||||
* @return Supplier of line
|
||||
*/
|
||||
@Nullable
|
||||
protected SidebarLine getLine(int line) {
|
||||
checkClosed();
|
||||
return lines[line];
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NotNull ScoreboardManager scoreboardManager() {
|
||||
return sidebar.scoreboardManager();
|
||||
}
|
||||
|
||||
protected final void checkClosed() {
|
||||
Preconditions.checkState(!sidebar.closed(), "Sidebar is closed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this AbstractSidebar
|
||||
*/
|
||||
@Override
|
||||
public final void close() {
|
||||
if (!sidebar.closed()) {
|
||||
sidebar.close();
|
||||
lines = null;
|
||||
onClosed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a line
|
||||
*
|
||||
* @param lineSupplier Line to update
|
||||
*/
|
||||
protected final void updateLine(@NotNull SidebarLine lineSupplier) {
|
||||
checkClosed();
|
||||
Preconditions.checkNotNull(lineSupplier);
|
||||
Preconditions.checkArgument(!lineSupplier.lineStatic());
|
||||
sidebar.line(lineSupplier.line(), lineSupplier.computeValue());
|
||||
}
|
||||
@Override
|
||||
public boolean closed() {
|
||||
return sidebar.closed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a line
|
||||
*
|
||||
* @param line Line to unregister
|
||||
* @return Unregistered line
|
||||
*/
|
||||
protected final @Nullable SidebarLine unregisterLine(int line) {
|
||||
SidebarLine lineSupplier = lines[line];
|
||||
if (lineSupplier == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
lines[line] = null;
|
||||
sidebar.line(line, null);
|
||||
return lineSupplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a static line for this AbstractSidebar
|
||||
*
|
||||
* @param line Line to register
|
||||
* @param value Static value
|
||||
*/
|
||||
protected final @NotNull SidebarLine registerStaticLine(int line, @NotNull Component value) {
|
||||
SidebarLine sidebarLine = SidebarLine.staticLine(value);
|
||||
registerLine(line, sidebarLine);
|
||||
return sidebarLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a line for this AbstractSidebar
|
||||
*
|
||||
* @param line Line to register
|
||||
* @param supplier Supplier
|
||||
* @return The created LineSupplier
|
||||
*/
|
||||
protected final SidebarLine registerLine(int line, @NotNull Supplier<Component> supplier) {
|
||||
checkClosed();
|
||||
Preconditions.checkNotNull(supplier);
|
||||
|
||||
return registerLine(line, new SidebarLine() {
|
||||
@Override
|
||||
public boolean lineStatic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int line() {
|
||||
return line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component computeValue() {
|
||||
return supplier.get();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a line for this AbstractSidebar
|
||||
*
|
||||
* @param line Line to register
|
||||
* @param supplier Supplier
|
||||
* @return The same LineSupplier for convenience
|
||||
*/
|
||||
protected final <S extends SidebarLine> S registerLine(int line, @NotNull S supplier) {
|
||||
checkClosed();
|
||||
Objects.requireNonNull(supplier);
|
||||
|
||||
SidebarUtilities.checkLineBounds(line);
|
||||
if (lines[line] != null) {
|
||||
throw new IllegalStateException("Line " + line + " is already registered");
|
||||
}
|
||||
|
||||
lines[line] = Objects.requireNonNull(supplier, "LineSupplier cannot be null");
|
||||
sidebar.line(line, supplier.computeValue());
|
||||
return supplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an empty line for this AbstractSidebar
|
||||
*
|
||||
* @param line Line to register
|
||||
*/
|
||||
protected final void registerEmptyLine(int line) {
|
||||
registerLine(line, emptyLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the supplier for a line
|
||||
*
|
||||
* @param line Line
|
||||
* @return Supplier of line
|
||||
*/
|
||||
@Nullable
|
||||
protected SidebarLine getLine(int line) {
|
||||
checkClosed();
|
||||
return lines[line];
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NotNull ScoreboardManager scoreboardManager() {
|
||||
return sidebar.scoreboardManager();
|
||||
}
|
||||
|
||||
protected final void checkClosed() {
|
||||
Preconditions.checkState(!sidebar.closed(), "Sidebar is closed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this AbstractSidebar
|
||||
*/
|
||||
@Override
|
||||
public final void close() {
|
||||
if (!sidebar.closed()) {
|
||||
sidebar.close();
|
||||
lines = null;
|
||||
onClosed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean closed() {
|
||||
return sidebar.closed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return sidebar.hashCode();
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return sidebar.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -15,78 +15,78 @@ import java.util.Locale;
|
||||
*/
|
||||
public interface Sidebar extends HasScoreboardManager, Closeable, Players {
|
||||
|
||||
// Constants
|
||||
// Constants
|
||||
|
||||
byte MAX_LINES = 15;
|
||||
byte MAX_LINES = 15;
|
||||
|
||||
// Main
|
||||
// Main
|
||||
|
||||
/**
|
||||
* Gets the {@link ComponentTranslator} of this Sidebar
|
||||
*
|
||||
* @return Component translator
|
||||
*/
|
||||
@NotNull ComponentTranslator componentTranslator();
|
||||
/**
|
||||
* Gets the {@link ComponentTranslator} of this Sidebar
|
||||
*
|
||||
* @return Component translator
|
||||
*/
|
||||
@NotNull ComponentTranslator componentTranslator();
|
||||
|
||||
/**
|
||||
* Gets the max amount of lines this sidebar can have
|
||||
*
|
||||
* @return Max line amount
|
||||
*/
|
||||
byte maxLines();
|
||||
/**
|
||||
* Gets the max amount of lines this sidebar can have
|
||||
*
|
||||
* @return Max line amount
|
||||
*/
|
||||
byte maxLines();
|
||||
|
||||
/**
|
||||
* Gets the {@link Locale} which is used to translate {@link net.kyori.adventure.text.TranslatableComponent}s
|
||||
*
|
||||
* @return Locale
|
||||
*/
|
||||
@Nullable Locale locale();
|
||||
/**
|
||||
* Gets the {@link Locale} which is used to translate {@link net.kyori.adventure.text.TranslatableComponent}s
|
||||
*
|
||||
* @return Locale
|
||||
*/
|
||||
@Nullable Locale locale();
|
||||
|
||||
// Visibility
|
||||
// Visibility
|
||||
|
||||
/**
|
||||
* Returns the visibility of this Sidebar
|
||||
*
|
||||
* @return Visibility
|
||||
*/
|
||||
boolean visible();
|
||||
/**
|
||||
* Returns the visibility of this Sidebar
|
||||
*
|
||||
* @return Visibility
|
||||
*/
|
||||
boolean visible();
|
||||
|
||||
/**
|
||||
* Changes the visibility of this Sidebar
|
||||
*
|
||||
* @param visible New visibility of this sidebar
|
||||
*/
|
||||
void visible(boolean visible);
|
||||
/**
|
||||
* Changes the visibility of this Sidebar
|
||||
*
|
||||
* @param visible New visibility of this sidebar
|
||||
*/
|
||||
void visible(boolean visible);
|
||||
|
||||
// Lines
|
||||
// Lines
|
||||
|
||||
/**
|
||||
* Sets a line's value
|
||||
*
|
||||
* @param line Line
|
||||
* @param value Value
|
||||
*/
|
||||
void line(int line, Component value);
|
||||
/**
|
||||
* Sets a line's value
|
||||
*
|
||||
* @param line Line
|
||||
* @param value Value
|
||||
*/
|
||||
void line(int line, Component value);
|
||||
|
||||
/**
|
||||
* Gets a line's value
|
||||
*
|
||||
* @param line Line
|
||||
* @return Value of line
|
||||
*/
|
||||
@Nullable Component line(int line);
|
||||
/**
|
||||
* Gets a line's value
|
||||
*
|
||||
* @param line Line
|
||||
* @return Value of line
|
||||
*/
|
||||
@Nullable Component line(int line);
|
||||
|
||||
/**
|
||||
* Returns the current title
|
||||
*
|
||||
* @return Title
|
||||
*/
|
||||
@NotNull Component title();
|
||||
/**
|
||||
* Returns the current title
|
||||
*
|
||||
* @return Title
|
||||
*/
|
||||
@NotNull Component title();
|
||||
|
||||
/**
|
||||
* Sets the title
|
||||
*
|
||||
* @param title Title
|
||||
*/
|
||||
void title(@NotNull Component title);
|
||||
/**
|
||||
* Sets the title
|
||||
*
|
||||
* @param title Title
|
||||
*/
|
||||
void title(@NotNull Component title);
|
||||
}
|
||||
+15
-15
@@ -2,23 +2,23 @@ package net.megavex.scoreboardlibrary.api.sidebar.line;
|
||||
|
||||
public abstract class AbstractSidebarLine implements SidebarLine {
|
||||
|
||||
protected final byte line;
|
||||
protected final byte line;
|
||||
|
||||
public AbstractSidebarLine(int line) {
|
||||
this((byte) line);
|
||||
}
|
||||
public AbstractSidebarLine(int line) {
|
||||
this((byte) line);
|
||||
}
|
||||
|
||||
public AbstractSidebarLine(byte line) {
|
||||
this.line = line;
|
||||
}
|
||||
public AbstractSidebarLine(byte line) {
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean lineStatic() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public final boolean lineStatic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int line() {
|
||||
return line;
|
||||
}
|
||||
@Override
|
||||
public final int line() {
|
||||
return line;
|
||||
}
|
||||
}
|
||||
@@ -5,23 +5,23 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface SidebarLine {
|
||||
|
||||
static @NotNull SidebarLine staticLine(@NotNull Component component) {
|
||||
return new StaticLine(component);
|
||||
}
|
||||
static @NotNull SidebarLine staticLine(@NotNull Component component) {
|
||||
return new StaticLine(component);
|
||||
}
|
||||
|
||||
default boolean lineStatic() {
|
||||
return true;
|
||||
}
|
||||
default boolean lineStatic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the line index
|
||||
*
|
||||
* @return Line index
|
||||
* @throws UnsupportedOperationException If this is a static line
|
||||
*/
|
||||
default int line() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* Gets the line index
|
||||
*
|
||||
* @return Line index
|
||||
* @throws UnsupportedOperationException If this is a static line
|
||||
*/
|
||||
default int line() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
Component computeValue();
|
||||
Component computeValue();
|
||||
}
|
||||
@@ -6,12 +6,12 @@ import java.util.Objects;
|
||||
|
||||
record StaticLine(Component value) implements SidebarLine {
|
||||
|
||||
StaticLine(Component value) {
|
||||
this.value = Objects.requireNonNull(value, "value");
|
||||
}
|
||||
StaticLine(Component value) {
|
||||
this.value = Objects.requireNonNull(value, "value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component computeValue() {
|
||||
return value;
|
||||
}
|
||||
@Override
|
||||
public Component computeValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -9,36 +9,36 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public interface ScoreboardTeam extends Closeable {
|
||||
|
||||
/**
|
||||
* Gets the TeamManager of this Team
|
||||
*
|
||||
* @return TeamManager
|
||||
*/
|
||||
@NotNull TeamManager teamManager();
|
||||
/**
|
||||
* Gets the TeamManager of this Team
|
||||
*
|
||||
* @return TeamManager
|
||||
*/
|
||||
@NotNull TeamManager teamManager();
|
||||
|
||||
@NotNull TeamInfo globalInfo();
|
||||
@NotNull TeamInfo globalInfo();
|
||||
|
||||
/**
|
||||
* Gets the name of this team
|
||||
*
|
||||
* @return Name
|
||||
*/
|
||||
@NotNull String name();
|
||||
/**
|
||||
* Gets the name of this team
|
||||
*
|
||||
* @return Name
|
||||
*/
|
||||
@NotNull String name();
|
||||
|
||||
/**
|
||||
* Gets the {@link TeamInfo} of a Player
|
||||
*
|
||||
* @param player Player
|
||||
* @return {@link TeamInfo} of Player
|
||||
*/
|
||||
@NotNull TeamInfo teamInfo(Player player);
|
||||
/**
|
||||
* Gets the {@link TeamInfo} of a Player
|
||||
*
|
||||
* @param player Player
|
||||
* @return {@link TeamInfo} of Player
|
||||
*/
|
||||
@NotNull TeamInfo teamInfo(Player player);
|
||||
|
||||
/**
|
||||
* Changes a Player's visible {@link TeamInfo}
|
||||
*
|
||||
* @param player Player
|
||||
* @param teamInfo New {@link TeamInfo} of Player
|
||||
* @return new team info of player.
|
||||
*/
|
||||
@NotNull TeamInfo teamInfo(Player player, TeamInfo teamInfo);
|
||||
/**
|
||||
* Changes a Player's visible {@link TeamInfo}
|
||||
*
|
||||
* @param player Player
|
||||
* @param teamInfo New {@link TeamInfo} of Player
|
||||
* @return new team info of player.
|
||||
*/
|
||||
@NotNull TeamInfo teamInfo(Player player, TeamInfo teamInfo);
|
||||
}
|
||||
@@ -12,176 +12,176 @@ import java.util.Collection;
|
||||
|
||||
public interface TeamInfo {
|
||||
|
||||
/**
|
||||
* Creates an empty {@link TeamInfo}
|
||||
*
|
||||
* @return TeamInfo
|
||||
*/
|
||||
static @NotNull TeamInfo teamInfo() {
|
||||
return teamInfo(null);
|
||||
}
|
||||
/**
|
||||
* Creates an empty {@link TeamInfo}
|
||||
*
|
||||
* @return TeamInfo
|
||||
*/
|
||||
static @NotNull TeamInfo teamInfo() {
|
||||
return teamInfo(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link TeamInfo} with specified entries
|
||||
*
|
||||
* @param entries Entries the TeamInfo should have
|
||||
* @return TeamInfo
|
||||
*/
|
||||
static @NotNull TeamInfo teamInfo(@Nullable Collection<String> entries) {
|
||||
return ScoreboardManagerProvider.instance().teamInfo(entries);
|
||||
}
|
||||
/**
|
||||
* Creates a {@link TeamInfo} with specified entries
|
||||
*
|
||||
* @param entries Entries the TeamInfo should have
|
||||
* @return TeamInfo
|
||||
*/
|
||||
static @NotNull TeamInfo teamInfo(@Nullable Collection<String> entries) {
|
||||
return ScoreboardManagerProvider.instance().teamInfo(entries);
|
||||
}
|
||||
|
||||
// Main
|
||||
// Main
|
||||
|
||||
/**
|
||||
* Gets the Team which is assigned to this TeamInfo
|
||||
*
|
||||
* @return Assigned Team
|
||||
* @throws IllegalStateException If not assigned
|
||||
*/
|
||||
ScoreboardTeam team();
|
||||
/**
|
||||
* Gets the Team which is assigned to this TeamInfo
|
||||
*
|
||||
* @return Assigned Team
|
||||
* @throws IllegalStateException If not assigned
|
||||
*/
|
||||
ScoreboardTeam team();
|
||||
|
||||
/**
|
||||
* Returns whether this TeamInfo is assigned to a Team
|
||||
*
|
||||
* @return If assigned
|
||||
*/
|
||||
boolean isAssigned();
|
||||
/**
|
||||
* Returns whether this TeamInfo is assigned to a Team
|
||||
*
|
||||
* @return If assigned
|
||||
*/
|
||||
boolean isAssigned();
|
||||
|
||||
/**
|
||||
* Unassigns TeamInfo info from the currently assigned Team
|
||||
*/
|
||||
void unassign();
|
||||
/**
|
||||
* Unassigns TeamInfo info from the currently assigned Team
|
||||
*/
|
||||
void unassign();
|
||||
|
||||
/**
|
||||
* Returns the name of the assigned Team
|
||||
*
|
||||
* @return Name of Team
|
||||
*/
|
||||
@Nullable
|
||||
default String name() {
|
||||
return team() == null ? null : team().name();
|
||||
}
|
||||
/**
|
||||
* Returns the name of the assigned Team
|
||||
*
|
||||
* @return Name of Team
|
||||
*/
|
||||
@Nullable
|
||||
default String name() {
|
||||
return team() == null ? null : team().name();
|
||||
}
|
||||
|
||||
// Entries
|
||||
// Entries
|
||||
|
||||
@NotNull Collection<String> entries();
|
||||
@NotNull Collection<String> entries();
|
||||
|
||||
/**
|
||||
* Adds an entry
|
||||
*
|
||||
* @param entry Entry to add
|
||||
* @return Whether the entry was added
|
||||
*/
|
||||
boolean addEntry(@NotNull String entry);
|
||||
/**
|
||||
* Adds an entry
|
||||
*
|
||||
* @param entry Entry to add
|
||||
* @return Whether the entry was added
|
||||
*/
|
||||
boolean addEntry(@NotNull String entry);
|
||||
|
||||
/**
|
||||
* Removes an entry
|
||||
*
|
||||
* @param entry Entry to remove
|
||||
* @return Whether the entry was removed
|
||||
*/
|
||||
boolean removeEntry(@NotNull String entry);
|
||||
/**
|
||||
* Removes an entry
|
||||
*
|
||||
* @param entry Entry to remove
|
||||
* @return Whether the entry was removed
|
||||
*/
|
||||
boolean removeEntry(@NotNull String entry);
|
||||
|
||||
// Properties
|
||||
// Properties
|
||||
|
||||
@NotNull Component displayName();
|
||||
@NotNull Component displayName();
|
||||
|
||||
/**
|
||||
* Sets the display name
|
||||
*
|
||||
* @param displayName Display name
|
||||
*/
|
||||
void displayName(@NotNull Component displayName);
|
||||
/**
|
||||
* Sets the display name
|
||||
*
|
||||
* @param displayName Display name
|
||||
*/
|
||||
void displayName(@NotNull Component displayName);
|
||||
|
||||
@NotNull Component prefix();
|
||||
@NotNull Component prefix();
|
||||
|
||||
/**
|
||||
* Sets the prefix
|
||||
*
|
||||
* @param prefix Prefix
|
||||
*/
|
||||
void prefix(@NotNull Component prefix);
|
||||
/**
|
||||
* Sets the prefix
|
||||
*
|
||||
* @param prefix Prefix
|
||||
*/
|
||||
void prefix(@NotNull Component prefix);
|
||||
|
||||
@NotNull Component suffix();
|
||||
@NotNull Component suffix();
|
||||
|
||||
/**
|
||||
* Sets the suffix
|
||||
*
|
||||
* @param suffix Suffix
|
||||
*/
|
||||
void suffix(@NotNull Component suffix);
|
||||
/**
|
||||
* Sets the suffix
|
||||
*
|
||||
* @param suffix Suffix
|
||||
*/
|
||||
void suffix(@NotNull Component suffix);
|
||||
|
||||
default boolean friendlyFire() {
|
||||
return false;
|
||||
}
|
||||
default boolean friendlyFire() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether friendly fire is allowed
|
||||
*
|
||||
* @param allowFriendlyFire whether friendly fire is allowed
|
||||
*/
|
||||
void friendlyFire(boolean allowFriendlyFire);
|
||||
/**
|
||||
* Sets whether friendly fire is allowed
|
||||
*
|
||||
* @param allowFriendlyFire whether friendly fire is allowed
|
||||
*/
|
||||
void friendlyFire(boolean allowFriendlyFire);
|
||||
|
||||
default boolean canSeeFriendlyInvisibles() {
|
||||
return false;
|
||||
}
|
||||
default boolean canSeeFriendlyInvisibles() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether players can see friendly invisibles
|
||||
*
|
||||
* @param canSeeFriendlyInvisibles whether players can see friendly invisibles
|
||||
*/
|
||||
void canSeeFriendlyInvisibles(boolean canSeeFriendlyInvisibles);
|
||||
/**
|
||||
* Sets whether players can see friendly invisibles
|
||||
*
|
||||
* @param canSeeFriendlyInvisibles whether players can see friendly invisibles
|
||||
*/
|
||||
void canSeeFriendlyInvisibles(boolean canSeeFriendlyInvisibles);
|
||||
|
||||
default @NotNull NameTagVisibility nameTagVisibility() {
|
||||
return NameTagVisibility.ALWAYS;
|
||||
}
|
||||
default @NotNull NameTagVisibility nameTagVisibility() {
|
||||
return NameTagVisibility.ALWAYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link NameTagVisibility}
|
||||
*
|
||||
* @param nameTagVisibility Name tag visibility rule
|
||||
*/
|
||||
void nameTagVisibility(@NotNull NameTagVisibility nameTagVisibility);
|
||||
/**
|
||||
* Sets the {@link NameTagVisibility}
|
||||
*
|
||||
* @param nameTagVisibility Name tag visibility rule
|
||||
*/
|
||||
void nameTagVisibility(@NotNull NameTagVisibility nameTagVisibility);
|
||||
|
||||
/**
|
||||
* Gets the {@link CollisionRule}. This will be ignored on 1.8 since in this version teams don't support this
|
||||
*
|
||||
* @return Collision rule
|
||||
*/
|
||||
default @NotNull CollisionRule collisionRule() {
|
||||
return CollisionRule.ALWAYS;
|
||||
}
|
||||
/**
|
||||
* Gets the {@link CollisionRule}. This will be ignored on 1.8 since in this version teams don't support this
|
||||
*
|
||||
* @return Collision rule
|
||||
*/
|
||||
default @NotNull CollisionRule collisionRule() {
|
||||
return CollisionRule.ALWAYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link CollisionRule}
|
||||
*
|
||||
* @param collisionRule Collision rule
|
||||
*/
|
||||
void collisionRule(@NotNull CollisionRule collisionRule);
|
||||
/**
|
||||
* Sets the {@link CollisionRule}
|
||||
*
|
||||
* @param collisionRule Collision rule
|
||||
*/
|
||||
void collisionRule(@NotNull CollisionRule collisionRule);
|
||||
|
||||
/**
|
||||
* Gets the {@link NamedTextColor} of the player. This will be ignored on 1.8 since in this version teams don't support this
|
||||
*
|
||||
* @return Color
|
||||
*/
|
||||
@Nullable
|
||||
default NamedTextColor playerColor() {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Gets the {@link NamedTextColor} of the player. This will be ignored on 1.8 since in this version teams don't support this
|
||||
*
|
||||
* @return Color
|
||||
*/
|
||||
@Nullable
|
||||
default NamedTextColor playerColor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link NamedTextColor}
|
||||
*
|
||||
* @param color Color
|
||||
*/
|
||||
void playerColor(@Nullable NamedTextColor color);
|
||||
/**
|
||||
* Sets the {@link NamedTextColor}
|
||||
*
|
||||
* @param color Color
|
||||
*/
|
||||
void playerColor(@Nullable NamedTextColor color);
|
||||
|
||||
// Options
|
||||
// Options
|
||||
|
||||
default void unpackOptions(int options) {
|
||||
friendlyFire((options & 1) > 0);
|
||||
canSeeFriendlyInvisibles((options & 2) > 0);
|
||||
}
|
||||
default void unpackOptions(int options) {
|
||||
friendlyFire((options & 1) > 0);
|
||||
canSeeFriendlyInvisibles((options & 2) > 0);
|
||||
}
|
||||
}
|
||||
@@ -14,78 +14,78 @@ import java.util.Objects;
|
||||
*/
|
||||
public class TeamInfoBuilder {
|
||||
|
||||
private Component displayName, prefix, suffix;
|
||||
private boolean allowFriendlyFire, canSeeFriendlyInvisibles;
|
||||
private NameTagVisibility nameTagVisibility;
|
||||
private CollisionRule collisionRule;
|
||||
private NamedTextColor playerColor;
|
||||
private Collection<String> entries;
|
||||
private Component displayName, prefix, suffix;
|
||||
private boolean allowFriendlyFire, canSeeFriendlyInvisibles;
|
||||
private NameTagVisibility nameTagVisibility;
|
||||
private CollisionRule collisionRule;
|
||||
private NamedTextColor playerColor;
|
||||
private Collection<String> entries;
|
||||
|
||||
public TeamInfo build() {
|
||||
TeamInfo teamInfo = ScoreboardManagerProvider.instance().teamInfo(entries);
|
||||
teamInfo.displayName(displayName);
|
||||
teamInfo.prefix(prefix);
|
||||
teamInfo.suffix(suffix);
|
||||
teamInfo.friendlyFire(allowFriendlyFire);
|
||||
teamInfo.canSeeFriendlyInvisibles(canSeeFriendlyInvisibles);
|
||||
teamInfo.nameTagVisibility(nameTagVisibility == null ? NameTagVisibility.ALWAYS : nameTagVisibility);
|
||||
teamInfo.collisionRule(collisionRule == null ? CollisionRule.ALWAYS : collisionRule);
|
||||
teamInfo.playerColor(playerColor);
|
||||
return teamInfo;
|
||||
}
|
||||
public TeamInfo build() {
|
||||
TeamInfo teamInfo = ScoreboardManagerProvider.instance().teamInfo(entries);
|
||||
teamInfo.displayName(displayName);
|
||||
teamInfo.prefix(prefix);
|
||||
teamInfo.suffix(suffix);
|
||||
teamInfo.friendlyFire(allowFriendlyFire);
|
||||
teamInfo.canSeeFriendlyInvisibles(canSeeFriendlyInvisibles);
|
||||
teamInfo.nameTagVisibility(nameTagVisibility == null ? NameTagVisibility.ALWAYS : nameTagVisibility);
|
||||
teamInfo.collisionRule(collisionRule == null ? CollisionRule.ALWAYS : collisionRule);
|
||||
teamInfo.playerColor(playerColor);
|
||||
return teamInfo;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder entries(Collection<String> entries) {
|
||||
this.entries = entries;
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder entries(Collection<String> entries) {
|
||||
this.entries = entries;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder addEntry(String entry) {
|
||||
Objects.requireNonNull(entries).add(entry);
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder addEntry(String entry) {
|
||||
Objects.requireNonNull(entries).add(entry);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder removeEntry(String entry) {
|
||||
Objects.requireNonNull(entries).remove(entry);
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder removeEntry(String entry) {
|
||||
Objects.requireNonNull(entries).remove(entry);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder displayName(Component displayName) {
|
||||
this.displayName = displayName;
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder displayName(Component displayName) {
|
||||
this.displayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder prefix(Component prefix) {
|
||||
this.prefix = prefix;
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder prefix(Component prefix) {
|
||||
this.prefix = prefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder suffix(Component suffix) {
|
||||
this.suffix = suffix;
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder suffix(Component suffix) {
|
||||
this.suffix = suffix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder allowFriendlyFire(boolean allowFriendlyFire) {
|
||||
this.allowFriendlyFire = allowFriendlyFire;
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder allowFriendlyFire(boolean allowFriendlyFire) {
|
||||
this.allowFriendlyFire = allowFriendlyFire;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder canSeeFriendlyInvisibles(boolean canSeeFriendlyInvisibles) {
|
||||
this.canSeeFriendlyInvisibles = canSeeFriendlyInvisibles;
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder canSeeFriendlyInvisibles(boolean canSeeFriendlyInvisibles) {
|
||||
this.canSeeFriendlyInvisibles = canSeeFriendlyInvisibles;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder nameTagVisibility(NameTagVisibility nameTagVisibility) {
|
||||
this.nameTagVisibility = nameTagVisibility;
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder nameTagVisibility(NameTagVisibility nameTagVisibility) {
|
||||
this.nameTagVisibility = nameTagVisibility;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder collisionRule(CollisionRule collisionRule) {
|
||||
this.collisionRule = collisionRule;
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder collisionRule(CollisionRule collisionRule) {
|
||||
this.collisionRule = collisionRule;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TeamInfoBuilder playerColor(NamedTextColor playerColor) {
|
||||
this.playerColor = playerColor;
|
||||
return this;
|
||||
}
|
||||
public TeamInfoBuilder playerColor(NamedTextColor playerColor) {
|
||||
this.playerColor = playerColor;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -17,103 +17,103 @@ import java.util.function.Function;
|
||||
*/
|
||||
public interface TeamManager extends Closeable, HasScoreboardManager, Players {
|
||||
|
||||
@NotNull ComponentTranslator componentTranslator();
|
||||
@NotNull ComponentTranslator componentTranslator();
|
||||
|
||||
// Teams
|
||||
// Teams
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable set of teams in this team manager
|
||||
*
|
||||
* @return Teams
|
||||
*/
|
||||
@NotNull Collection<ScoreboardTeam> teams();
|
||||
/**
|
||||
* Returns an unmodifiable set of teams in this team manager
|
||||
*
|
||||
* @return Teams
|
||||
*/
|
||||
@NotNull Collection<ScoreboardTeam> teams();
|
||||
|
||||
/**
|
||||
* Returns team based on its name
|
||||
*
|
||||
* @param name Name of team
|
||||
* @return Team with this name
|
||||
*/
|
||||
@Nullable ScoreboardTeam team(@NotNull String name);
|
||||
/**
|
||||
* Returns team based on its name
|
||||
*
|
||||
* @param name Name of team
|
||||
* @return Team with this name
|
||||
*/
|
||||
@Nullable ScoreboardTeam team(@NotNull String name);
|
||||
|
||||
/**
|
||||
* Returns whether a team by the name exists
|
||||
*
|
||||
* @param name Name of team
|
||||
* @return Whether a team by the name exists
|
||||
*/
|
||||
boolean teamExists(@NotNull String name);
|
||||
/**
|
||||
* Returns whether a team by the name exists
|
||||
*
|
||||
* @param name Name of team
|
||||
* @return Whether a team by the name exists
|
||||
*/
|
||||
boolean teamExists(@NotNull String name);
|
||||
|
||||
/**
|
||||
* Returns team based on its name. If it doesn't already exist, creates it
|
||||
*
|
||||
* @param name Name of team.
|
||||
* @return Team with this name, null if not found
|
||||
*/
|
||||
default @NotNull ScoreboardTeam createIfAbsent(@NotNull String name) {
|
||||
return createIfAbsent(name, null);
|
||||
}
|
||||
/**
|
||||
* Returns team based on its name. If it doesn't already exist, creates it
|
||||
*
|
||||
* @param name Name of team.
|
||||
* @return Team with this name, null if not found
|
||||
*/
|
||||
default @NotNull ScoreboardTeam createIfAbsent(@NotNull String name) {
|
||||
return createIfAbsent(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a team based on its name. If it doesn't already exist, it creates it
|
||||
*
|
||||
* @param name Name of team
|
||||
* @param teamInfoFunction A function that provides team info's for each player
|
||||
* @return Team with this name
|
||||
*/
|
||||
@NotNull ScoreboardTeam createIfAbsent(@NotNull String name, @Nullable BiFunction<Player, ScoreboardTeam, TeamInfo> teamInfoFunction);
|
||||
/**
|
||||
* Returns a team based on its name. If it doesn't already exist, it creates it
|
||||
*
|
||||
* @param name Name of team
|
||||
* @param teamInfoFunction A function that provides team info's for each player
|
||||
* @return Team with this name
|
||||
*/
|
||||
@NotNull ScoreboardTeam createIfAbsent(@NotNull String name, @Nullable BiFunction<Player, ScoreboardTeam, TeamInfo> teamInfoFunction);
|
||||
|
||||
// Players
|
||||
// Players
|
||||
|
||||
/**
|
||||
* Adds a player to this TeamManager
|
||||
*
|
||||
* @param player Player to add to TeamManager
|
||||
* @return Whether the player was added
|
||||
*/
|
||||
default boolean addPlayer(@NotNull Player player) {
|
||||
return addPlayer(player, null);
|
||||
}
|
||||
/**
|
||||
* Adds a player to this TeamManager
|
||||
*
|
||||
* @param player Player to add to TeamManager
|
||||
* @return Whether the player was added
|
||||
*/
|
||||
default boolean addPlayer(@NotNull Player player) {
|
||||
return addPlayer(player, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a player to this TeamManager
|
||||
*
|
||||
* @param player Player to add
|
||||
* @param teamInfoFunction A function that returns the {@link TeamInfo} that the player should have
|
||||
* @return Whether the player was added
|
||||
*/
|
||||
boolean addPlayer(@NotNull Player player, @Nullable Function<ScoreboardTeam, TeamInfo> teamInfoFunction);
|
||||
/**
|
||||
* Adds a player to this TeamManager
|
||||
*
|
||||
* @param player Player to add
|
||||
* @param teamInfoFunction A function that returns the {@link TeamInfo} that the player should have
|
||||
* @return Whether the player was added
|
||||
*/
|
||||
boolean addPlayer(@NotNull Player player, @Nullable Function<ScoreboardTeam, TeamInfo> teamInfoFunction);
|
||||
|
||||
/**
|
||||
* Adds a player to this TeamManager
|
||||
*
|
||||
* @param players Players to add
|
||||
*/
|
||||
default void addPlayers(@NotNull Collection<Player> players) {
|
||||
addPlayers(players, null);
|
||||
}
|
||||
/**
|
||||
* Adds a player to this TeamManager
|
||||
*
|
||||
* @param players Players to add
|
||||
*/
|
||||
default void addPlayers(@NotNull Collection<Player> players) {
|
||||
addPlayers(players, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a list of players to this TeamManager
|
||||
*
|
||||
* @param players Players to add
|
||||
* @param teamInfoFunction A function that returns the {@link TeamInfo} that the player should have
|
||||
* @return A collection of players that have been added
|
||||
*/
|
||||
@NotNull Collection<Player> addPlayers(@NotNull Collection<Player> players, @Nullable Function<ScoreboardTeam, TeamInfo> teamInfoFunction);
|
||||
/**
|
||||
* Adds a list of players to this TeamManager
|
||||
*
|
||||
* @param players Players to add
|
||||
* @param teamInfoFunction A function that returns the {@link TeamInfo} that the player should have
|
||||
* @return A collection of players that have been added
|
||||
*/
|
||||
@NotNull Collection<Player> addPlayers(@NotNull Collection<Player> players, @Nullable Function<ScoreboardTeam, TeamInfo> teamInfoFunction);
|
||||
|
||||
/**
|
||||
* Removes a player from this TeamManager
|
||||
*
|
||||
* @param player Player to remove
|
||||
* @return If the player was removed
|
||||
*/
|
||||
boolean removePlayer(@NotNull Player player);
|
||||
/**
|
||||
* Removes a player from this TeamManager
|
||||
*
|
||||
* @param player Player to remove
|
||||
* @return If the player was removed
|
||||
*/
|
||||
boolean removePlayer(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Removes a list of players from this TeamManager
|
||||
*
|
||||
* @param players Player to remove
|
||||
*/
|
||||
void removePlayers(@NotNull Collection<Player> players);
|
||||
/**
|
||||
* Removes a list of players from this TeamManager
|
||||
*
|
||||
* @param players Player to remove
|
||||
*/
|
||||
void removePlayers(@NotNull Collection<Player> players);
|
||||
}
|
||||
@@ -3,30 +3,30 @@ package net.megavex.scoreboardlibrary.api.team.enums;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public enum CollisionRule {
|
||||
ALWAYS("always"),
|
||||
NEVER("never"),
|
||||
PUSH_OTHER_TEAMS("pushOtherTeams"),
|
||||
PUSH_OWN_TEAM("pushOwnTeam");
|
||||
ALWAYS("always"),
|
||||
NEVER("never"),
|
||||
PUSH_OTHER_TEAMS("pushOtherTeams"),
|
||||
PUSH_OWN_TEAM("pushOwnTeam");
|
||||
|
||||
private static final CollisionRule[] values = values();
|
||||
private final String key;
|
||||
private static final CollisionRule[] values = values();
|
||||
private final String key;
|
||||
|
||||
CollisionRule(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
CollisionRule(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static CollisionRule of(byte id) {
|
||||
return values[id];
|
||||
}
|
||||
@ApiStatus.Internal
|
||||
public static CollisionRule of(byte id) {
|
||||
return values[id];
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public byte id() {
|
||||
return (byte) ordinal();
|
||||
}
|
||||
@ApiStatus.Internal
|
||||
public byte id() {
|
||||
return (byte) ordinal();
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public String key() {
|
||||
return this.key;
|
||||
}
|
||||
@ApiStatus.Internal
|
||||
public String key() {
|
||||
return this.key;
|
||||
}
|
||||
}
|
||||
+21
-21
@@ -3,30 +3,30 @@ package net.megavex.scoreboardlibrary.api.team.enums;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public enum NameTagVisibility {
|
||||
ALWAYS("always"),
|
||||
NEVER("never"),
|
||||
HIDE_FOR_OTHER_TEAMS("hideForOtherTeams"),
|
||||
HIDE_FOR_OWN_TEAM("hideForOwnTeam");
|
||||
ALWAYS("always"),
|
||||
NEVER("never"),
|
||||
HIDE_FOR_OTHER_TEAMS("hideForOtherTeams"),
|
||||
HIDE_FOR_OWN_TEAM("hideForOwnTeam");
|
||||
|
||||
private static final NameTagVisibility[] values = values();
|
||||
private final String key;
|
||||
private static final NameTagVisibility[] values = values();
|
||||
private final String key;
|
||||
|
||||
NameTagVisibility(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
NameTagVisibility(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static NameTagVisibility of(byte id) {
|
||||
return values[id];
|
||||
}
|
||||
@ApiStatus.Internal
|
||||
public static NameTagVisibility of(byte id) {
|
||||
return values[id];
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public byte id() {
|
||||
return (byte) ordinal();
|
||||
}
|
||||
@ApiStatus.Internal
|
||||
public byte id() {
|
||||
return (byte) ordinal();
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public String key() {
|
||||
return this.key;
|
||||
}
|
||||
@ApiStatus.Internal
|
||||
public String key() {
|
||||
return this.key;
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,12 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
@ApiStatus.Internal
|
||||
public final class SidebarUtilities {
|
||||
|
||||
private SidebarUtilities() {
|
||||
}
|
||||
private SidebarUtilities() {
|
||||
}
|
||||
|
||||
public static void checkLineBounds(int line) {
|
||||
if (line > Sidebar.MAX_LINES || line < 0) {
|
||||
throw new IndexOutOfBoundsException("Invalid line: " + line);
|
||||
}
|
||||
public static void checkLineBounds(int line) {
|
||||
if (line > Sidebar.MAX_LINES || line < 0) {
|
||||
throw new IndexOutOfBoundsException("Invalid line: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
-17
@@ -6,25 +6,25 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
@ApiStatus.Internal
|
||||
public class ScoreboardLibraryLogger {
|
||||
|
||||
public static final boolean DEBUG;
|
||||
public static final boolean DEBUG;
|
||||
|
||||
static {
|
||||
String property = System.getProperty(ScoreboardLibrary.NAMESPACE + ".debug");
|
||||
if (property != null) {
|
||||
DEBUG = property.equalsIgnoreCase("true");
|
||||
logMessage("Debug enabled.");
|
||||
} else {
|
||||
DEBUG = false;
|
||||
}
|
||||
static {
|
||||
String property = System.getProperty(ScoreboardLibrary.NAMESPACE + ".debug");
|
||||
if (property != null) {
|
||||
DEBUG = property.equalsIgnoreCase("true");
|
||||
logMessage("Debug enabled.");
|
||||
} else {
|
||||
DEBUG = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void logMessage(String message) {
|
||||
if (DEBUG) {
|
||||
ScoreboardManagerProvider provider = ScoreboardManagerProvider.instance();
|
||||
ScoreboardManagerProvider
|
||||
.loaderPlugin()
|
||||
.getLogger()
|
||||
.info("[ScoreboardManager] " + message);
|
||||
}
|
||||
public static void logMessage(String message) {
|
||||
if (DEBUG) {
|
||||
ScoreboardManagerProvider provider = ScoreboardManagerProvider.instance();
|
||||
ScoreboardManagerProvider
|
||||
.loaderPlugin()
|
||||
.getLogger()
|
||||
.info("[ScoreboardManager] " + message);
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
-38
@@ -18,52 +18,52 @@ import java.util.Collection;
|
||||
@ApiStatus.Internal
|
||||
public abstract class ScoreboardManagerProvider {
|
||||
|
||||
private static ScoreboardManagerProvider instance;
|
||||
private static JavaPlugin loaderPlugin;
|
||||
private static ScoreboardManagerProvider instance;
|
||||
private static JavaPlugin loaderPlugin;
|
||||
|
||||
public static ScoreboardManagerProvider instance() {
|
||||
return instance;
|
||||
}
|
||||
public static ScoreboardManagerProvider instance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void instance(ScoreboardManagerProvider instance) {
|
||||
ScoreboardManagerProvider.instance = instance;
|
||||
}
|
||||
public static void instance(ScoreboardManagerProvider instance) {
|
||||
ScoreboardManagerProvider.instance = instance;
|
||||
}
|
||||
|
||||
public static JavaPlugin loaderPlugin() {
|
||||
return loaderPlugin;
|
||||
}
|
||||
public static JavaPlugin loaderPlugin() {
|
||||
return loaderPlugin;
|
||||
}
|
||||
|
||||
public static void loaderPlugin(JavaPlugin loaderPlugin) {
|
||||
ScoreboardManagerProvider.loaderPlugin = loaderPlugin;
|
||||
}
|
||||
public static void loaderPlugin(JavaPlugin loaderPlugin) {
|
||||
ScoreboardManagerProvider.loaderPlugin = loaderPlugin;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TeamInfo teamInfo() {
|
||||
return teamInfo(null);
|
||||
}
|
||||
@NotNull
|
||||
public TeamInfo teamInfo() {
|
||||
return teamInfo(null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract TeamInfo teamInfo(@Nullable Collection<String> entries);
|
||||
@NotNull
|
||||
public abstract TeamInfo teamInfo(@Nullable Collection<String> entries);
|
||||
|
||||
|
||||
@NotNull
|
||||
public abstract ScoreboardManager scoreboardManager(JavaPlugin plugin);
|
||||
@NotNull
|
||||
public abstract ScoreboardManager scoreboardManager(JavaPlugin plugin);
|
||||
|
||||
/**
|
||||
* Gets the {@link Sidebar} that a player has
|
||||
*
|
||||
* @param player Player
|
||||
* @return Sidebar
|
||||
*/
|
||||
@Nullable
|
||||
public abstract Sidebar sidebar(Player player);
|
||||
/**
|
||||
* Gets the {@link Sidebar} that a player has
|
||||
*
|
||||
* @param player Player
|
||||
* @return Sidebar
|
||||
*/
|
||||
@Nullable
|
||||
public abstract Sidebar sidebar(Player player);
|
||||
|
||||
/**
|
||||
* Gets the {@link TeamManager} that a player has
|
||||
*
|
||||
* @param player Player
|
||||
* @return Sidebar
|
||||
*/
|
||||
@Nullable
|
||||
public abstract TeamManager teamManager(Player player);
|
||||
/**
|
||||
* Gets the {@link TeamManager} that a player has
|
||||
*
|
||||
* @param player Player
|
||||
* @return Sidebar
|
||||
*/
|
||||
@Nullable
|
||||
public abstract TeamManager teamManager(Player player);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
gradlePluginPortal()
|
||||
}
|
||||
+22
-22
@@ -1,38 +1,38 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven { url = uri("https://oss.sonatype.org/content/groups/public/") }
|
||||
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven { url = uri("https://oss.sonatype.org/content/groups/public/") }
|
||||
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.18.2-R0.1-SNAPSHOT")
|
||||
compileOnly("io.papermc.paper:paper-api:1.18.2-R0.1-SNAPSHOT")
|
||||
|
||||
val adventureVersion = "4.9.3"
|
||||
compileOnly("net.kyori:adventure-api:$adventureVersion")
|
||||
compileOnly("net.kyori:adventure-text-serializer-legacy:$adventureVersion")
|
||||
compileOnly("net.kyori:adventure-text-serializer-gson:$adventureVersion")
|
||||
val adventureVersion = "4.9.3"
|
||||
compileOnly("net.kyori:adventure-api:$adventureVersion")
|
||||
compileOnly("net.kyori:adventure-text-serializer-legacy:$adventureVersion")
|
||||
compileOnly("net.kyori:adventure-text-serializer-gson:$adventureVersion")
|
||||
}
|
||||
|
||||
group = "net.megavex.scoreboardlibrary"
|
||||
version = "1.0.0"
|
||||
|
||||
tasks {
|
||||
compileJava {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release.set(17)
|
||||
}
|
||||
compileJava {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release.set(17)
|
||||
}
|
||||
|
||||
javadoc {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
}
|
||||
javadoc {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
}
|
||||
|
||||
processResources {
|
||||
filteringCharset = Charsets.UTF_8.name()
|
||||
}
|
||||
}
|
||||
processResources {
|
||||
filteringCharset = Charsets.UTF_8.name()
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
id("net.megavex.scoreboardlibrary.java-conventions")
|
||||
id("net.megavex.scoreboardlibrary.java-conventions")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(":nms-base"))
|
||||
}
|
||||
compileOnly(project(":nms-base"))
|
||||
}
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
plugins {
|
||||
id("net.megavex.scoreboardlibrary.java-conventions")
|
||||
`maven-publish`
|
||||
id("net.megavex.scoreboardlibrary.java-conventions")
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications.create<MavenPublication>("maven") {
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
publications.create<MavenPublication>("maven") {
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
plugins {
|
||||
id("net.megavex.scoreboardlibrary.publish-conventions")
|
||||
id("net.megavex.scoreboardlibrary.publish-conventions")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":api"))
|
||||
implementation(project(":nms-base"))
|
||||
}
|
||||
api(project(":api"))
|
||||
implementation(project(":nms-base"))
|
||||
}
|
||||
+46
-46
@@ -16,56 +16,56 @@ import java.lang.reflect.InvocationTargetException;
|
||||
*/
|
||||
public final class ScoreboardLibraryImplementation {
|
||||
|
||||
private ScoreboardLibraryImplementation() {
|
||||
private ScoreboardLibraryImplementation() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the library
|
||||
*/
|
||||
public static synchronized void init() throws ScoreboardLibraryLoadException {
|
||||
if (ScoreboardManagerProvider.instance() != null) {
|
||||
return; // Already initialised
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the library
|
||||
*/
|
||||
public static synchronized void init() throws ScoreboardLibraryLoadException {
|
||||
if (ScoreboardManagerProvider.instance() != null) {
|
||||
return; // Already initialised
|
||||
}
|
||||
JavaPlugin plugin = JavaPlugin.getProvidingPlugin(ScoreboardLibraryImplementation.class);
|
||||
ScoreboardManagerProvider.loaderPlugin(plugin);
|
||||
|
||||
JavaPlugin plugin = JavaPlugin.getProvidingPlugin(ScoreboardLibraryImplementation.class);
|
||||
ScoreboardManagerProvider.loaderPlugin(plugin);
|
||||
|
||||
try {
|
||||
Class.forName("net.kyori.adventure.Adventure");
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new ScoreboardLibraryLoadException("Adventure is not in the classpath");
|
||||
}
|
||||
|
||||
String versionName = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
Class<?> nmsClass;
|
||||
try {
|
||||
nmsClass = Class.forName("net.megavex.scoreboardlibrary.internal.nms." + versionName + ".NMSImpl");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
throw new ScoreboardLibraryLoadException("Server version " + versionName + " is not supported");
|
||||
}
|
||||
|
||||
try {
|
||||
nmsClass.getConstructors()[0].newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new ScoreboardLibraryLoadException("Couldn't initialize NMS implementation", e);
|
||||
}
|
||||
|
||||
ScoreboardManagerProviderImpl.init();
|
||||
ScoreboardLibraryLogger.logMessage("Loaded implementation " + nmsClass.getName());
|
||||
try {
|
||||
Class.forName("net.kyori.adventure.Adventure");
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new ScoreboardLibraryLoadException("Adventure is not in the classpath");
|
||||
}
|
||||
|
||||
public static synchronized void close() {
|
||||
if (ScoreboardManagerProvider.instance() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScoreboardManagerProviderImpl provider = ScoreboardManagerProviderImpl.instance();
|
||||
if (provider != null && !provider.scoreboardManagerMap.isEmpty()) {
|
||||
ImmutableList.copyOf(provider.scoreboardManagerMap.values()).forEach(ScoreboardManager::close);
|
||||
}
|
||||
|
||||
ScoreboardManagerProvider.instance(null);
|
||||
ScoreboardManagerProviderImpl.instance(null);
|
||||
ScoreboardLibraryLogger.logMessage("Closed");
|
||||
String versionName = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
Class<?> nmsClass;
|
||||
try {
|
||||
nmsClass = Class.forName("net.megavex.scoreboardlibrary.internal.nms." + versionName + ".NMSImpl");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
throw new ScoreboardLibraryLoadException("Server version " + versionName + " is not supported");
|
||||
}
|
||||
|
||||
try {
|
||||
nmsClass.getConstructors()[0].newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new ScoreboardLibraryLoadException("Couldn't initialize NMS implementation", e);
|
||||
}
|
||||
|
||||
ScoreboardManagerProviderImpl.init();
|
||||
ScoreboardLibraryLogger.logMessage("Loaded implementation " + nmsClass.getName());
|
||||
}
|
||||
|
||||
public static synchronized void close() {
|
||||
if (ScoreboardManagerProvider.instance() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScoreboardManagerProviderImpl provider = ScoreboardManagerProviderImpl.instance();
|
||||
if (provider != null && !provider.scoreboardManagerMap.isEmpty()) {
|
||||
ImmutableList.copyOf(provider.scoreboardManagerMap.values()).forEach(ScoreboardManager::close);
|
||||
}
|
||||
|
||||
ScoreboardManagerProvider.instance(null);
|
||||
ScoreboardManagerProviderImpl.instance(null);
|
||||
ScoreboardLibraryLogger.logMessage("Closed");
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -2,11 +2,11 @@ package net.megavex.scoreboardlibrary.exception;
|
||||
|
||||
public class ScoreboardLibraryLoadException extends Exception {
|
||||
|
||||
public ScoreboardLibraryLoadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
public ScoreboardLibraryLoadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ScoreboardLibraryLoadException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
public ScoreboardLibraryLoadException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
+113
-113
@@ -28,139 +28,139 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ScoreboardManagerImpl implements ScoreboardManager {
|
||||
|
||||
public final JavaPlugin plugin;
|
||||
public final PlayerListener playerListener = new PlayerListener(this);
|
||||
public LocaleListener localeListener;
|
||||
public boolean closed;
|
||||
public TeamUpdaterTask teamTask;
|
||||
public SidebarUpdaterTask sidebarTask;
|
||||
public Set<TeamManagerImpl> teamManagers;
|
||||
public Set<AbstractSidebar> sidebars;
|
||||
public final JavaPlugin plugin;
|
||||
public final PlayerListener playerListener = new PlayerListener(this);
|
||||
public LocaleListener localeListener;
|
||||
public boolean closed;
|
||||
public TeamUpdaterTask teamTask;
|
||||
public SidebarUpdaterTask sidebarTask;
|
||||
public Set<TeamManagerImpl> teamManagers;
|
||||
public Set<AbstractSidebar> sidebars;
|
||||
|
||||
public ScoreboardManagerImpl(JavaPlugin plugin) {
|
||||
Preconditions.checkNotNull(plugin, "JavaPlugin cannot be null");
|
||||
this.plugin = plugin;
|
||||
public ScoreboardManagerImpl(JavaPlugin plugin) {
|
||||
Preconditions.checkNotNull(plugin, "JavaPlugin cannot be null");
|
||||
this.plugin = plugin;
|
||||
|
||||
plugin.getServer().getPluginManager().registerEvents(playerListener, plugin);
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerLocaleChangeEvent");
|
||||
ScoreboardLibraryLogger.logMessage("PlayerLocaleChangeEvent was found");
|
||||
localeListener = new LocaleListener(this);
|
||||
plugin.getServer().getPluginManager().registerEvents(localeListener, plugin);
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
plugin.getServer().getPluginManager().registerEvents(playerListener, plugin);
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerLocaleChangeEvent");
|
||||
ScoreboardLibraryLogger.logMessage("PlayerLocaleChangeEvent was found");
|
||||
localeListener = new LocaleListener(this);
|
||||
plugin.getServer().getPluginManager().registerEvents(localeListener, plugin);
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Plugin plugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Sidebar sidebar(int maxLines, @NotNull ComponentTranslator componentTranslator, @Nullable Locale locale) {
|
||||
checkDestroyed();
|
||||
getSidebars0();
|
||||
|
||||
if (maxLines < 0 || maxLines > Sidebar.MAX_LINES) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Plugin plugin() {
|
||||
return plugin;
|
||||
AbstractSidebar sidebar;
|
||||
if (locale == null) {
|
||||
sidebar = new PlayerDependantLocaleSidebar(this, componentTranslator, maxLines);
|
||||
} else {
|
||||
sidebar = new SingleLocaleSidebar(this, componentTranslator, maxLines, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Sidebar sidebar(int maxLines, @NotNull ComponentTranslator componentTranslator, @Nullable Locale locale) {
|
||||
checkDestroyed();
|
||||
getSidebars0();
|
||||
sidebars.add(sidebar);
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
if (maxLines < 0 || maxLines > Sidebar.MAX_LINES) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
@Override
|
||||
public @NotNull TeamManagerImpl teamManager(@NotNull ComponentTranslator componentTranslator) {
|
||||
checkDestroyed();
|
||||
getTeamManagers0();
|
||||
|
||||
AbstractSidebar sidebar;
|
||||
if (locale == null) {
|
||||
sidebar = new PlayerDependantLocaleSidebar(this, componentTranslator, maxLines);
|
||||
} else {
|
||||
sidebar = new SingleLocaleSidebar(this, componentTranslator, maxLines, locale);
|
||||
}
|
||||
TeamManagerImpl teamManager = new TeamManagerImpl(this, componentTranslator);
|
||||
teamManagers.add(teamManager);
|
||||
return teamManager;
|
||||
}
|
||||
|
||||
sidebars.add(sidebar);
|
||||
return sidebar;
|
||||
@Override
|
||||
public void close() {
|
||||
if (closed)
|
||||
return;
|
||||
|
||||
closed = true;
|
||||
|
||||
ScoreboardManagerProviderImpl.instance().scoreboardManagerMap.remove(plugin);
|
||||
HandlerList.unregisterAll(playerListener);
|
||||
|
||||
if (teamManagers != null) {
|
||||
teamTask.cancel();
|
||||
for (TeamManagerImpl teamManager : teamManagers) {
|
||||
teamManager.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TeamManagerImpl teamManager(@NotNull ComponentTranslator componentTranslator) {
|
||||
checkDestroyed();
|
||||
getTeamManagers0();
|
||||
|
||||
TeamManagerImpl teamManager = new TeamManagerImpl(this, componentTranslator);
|
||||
teamManagers.add(teamManager);
|
||||
return teamManager;
|
||||
if (sidebars != null) {
|
||||
sidebarTask.cancel();
|
||||
for (AbstractSidebar sidebar : ImmutableList.copyOf(sidebars)) {
|
||||
sidebar.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (closed)
|
||||
return;
|
||||
@Override
|
||||
public boolean closed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
closed = true;
|
||||
|
||||
ScoreboardManagerProviderImpl.instance().scoreboardManagerMap.remove(plugin);
|
||||
HandlerList.unregisterAll(playerListener);
|
||||
|
||||
if (teamManagers != null) {
|
||||
teamTask.cancel();
|
||||
for (TeamManagerImpl teamManager : teamManagers) {
|
||||
teamManager.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (sidebars != null) {
|
||||
sidebarTask.cancel();
|
||||
for (AbstractSidebar sidebar : ImmutableList.copyOf(sidebars)) {
|
||||
sidebar.close();
|
||||
}
|
||||
}
|
||||
public Set<TeamManagerImpl> getTeamManagers0() {
|
||||
if (teamManagers == null) {
|
||||
teamManagers = ConcurrentHashMap.newKeySet(4);
|
||||
teamTask = new TeamUpdaterTask(this);
|
||||
}
|
||||
return teamManagers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean closed() {
|
||||
return closed;
|
||||
public Set<AbstractSidebar> getSidebars0() {
|
||||
if (sidebars == null) {
|
||||
sidebars = ConcurrentHashMap.newKeySet(4);
|
||||
sidebarTask = new SidebarUpdaterTask(this);
|
||||
}
|
||||
return sidebars;
|
||||
}
|
||||
|
||||
public Set<TeamManagerImpl> getTeamManagers0() {
|
||||
if (teamManagers == null) {
|
||||
teamManagers = ConcurrentHashMap.newKeySet(4);
|
||||
teamTask = new TeamUpdaterTask(this);
|
||||
}
|
||||
return teamManagers;
|
||||
}
|
||||
@Override
|
||||
public Set<TeamManager> teamManagers() {
|
||||
return Collections.unmodifiableSet(getTeamManagers0());
|
||||
}
|
||||
|
||||
public Set<AbstractSidebar> getSidebars0() {
|
||||
if (sidebars == null) {
|
||||
sidebars = ConcurrentHashMap.newKeySet(4);
|
||||
sidebarTask = new SidebarUpdaterTask(this);
|
||||
}
|
||||
return sidebars;
|
||||
}
|
||||
@Override
|
||||
public Set<Sidebar> sidebars() {
|
||||
return Collections.unmodifiableSet(getSidebars0());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TeamManager> teamManagers() {
|
||||
return Collections.unmodifiableSet(getTeamManagers0());
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ScoreboardManagerImpl that = (ScoreboardManagerImpl) o;
|
||||
return closed == that.closed &&
|
||||
Objects.equals(plugin, that.plugin) &&
|
||||
Objects.equals(teamTask, that.teamTask) &&
|
||||
Objects.equals(sidebarTask, that.sidebarTask) &&
|
||||
Objects.equals(teamManagers, that.teamManagers) &&
|
||||
Objects.equals(sidebars, that.sidebars);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Sidebar> sidebars() {
|
||||
return Collections.unmodifiableSet(getSidebars0());
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return plugin.getName().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ScoreboardManagerImpl that = (ScoreboardManagerImpl) o;
|
||||
return closed == that.closed &&
|
||||
Objects.equals(plugin, that.plugin) &&
|
||||
Objects.equals(teamTask, that.teamTask) &&
|
||||
Objects.equals(sidebarTask, that.sidebarTask) &&
|
||||
Objects.equals(teamManagers, that.teamManagers) &&
|
||||
Objects.equals(sidebars, that.sidebars);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return plugin.getName().hashCode();
|
||||
}
|
||||
|
||||
private void checkDestroyed() {
|
||||
Preconditions.checkState(!closed, "ScoreboardManager is closed");
|
||||
}
|
||||
private void checkDestroyed() {
|
||||
Preconditions.checkState(!closed, "ScoreboardManager is closed");
|
||||
}
|
||||
}
|
||||
+43
-43
@@ -18,53 +18,53 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ScoreboardManagerProviderImpl extends ScoreboardManagerProvider {
|
||||
|
||||
private static ScoreboardManagerProviderImpl instance;
|
||||
public final Map<Player, AbstractSidebar> sidebarMap = new ConcurrentHashMap<>();
|
||||
public final Map<Player, TeamManagerImpl> teamManagerMap = new ConcurrentHashMap<>();
|
||||
public final Map<JavaPlugin, ScoreboardManager> scoreboardManagerMap = CollectionProvider.map(1);
|
||||
private static ScoreboardManagerProviderImpl instance;
|
||||
public final Map<Player, AbstractSidebar> sidebarMap = new ConcurrentHashMap<>();
|
||||
public final Map<Player, TeamManagerImpl> teamManagerMap = new ConcurrentHashMap<>();
|
||||
public final Map<JavaPlugin, ScoreboardManager> scoreboardManagerMap = CollectionProvider.map(1);
|
||||
|
||||
private ScoreboardManagerProviderImpl() {
|
||||
private ScoreboardManagerProviderImpl() {
|
||||
}
|
||||
|
||||
public static ScoreboardManagerProviderImpl instance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void instance(ScoreboardManagerProviderImpl instance) {
|
||||
ScoreboardManagerProviderImpl.instance = instance;
|
||||
}
|
||||
|
||||
public static synchronized void init() {
|
||||
Preconditions.checkState(instance == null && ScoreboardManagerProvider.instance() == null);
|
||||
ScoreboardManagerProviderImpl provider = new ScoreboardManagerProviderImpl();
|
||||
instance = provider;
|
||||
ScoreboardManagerProvider.instance(provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public TeamInfo teamInfo(Collection<String> entries) {
|
||||
TeamInfoImpl impl = new TeamInfoImpl();
|
||||
if (entries != null) {
|
||||
impl.entries.addAll(entries);
|
||||
}
|
||||
|
||||
public static ScoreboardManagerProviderImpl instance() {
|
||||
return instance;
|
||||
}
|
||||
return impl;
|
||||
}
|
||||
|
||||
public static void instance(ScoreboardManagerProviderImpl instance) {
|
||||
ScoreboardManagerProviderImpl.instance = instance;
|
||||
}
|
||||
@Override
|
||||
@NotNull
|
||||
public ScoreboardManager scoreboardManager(JavaPlugin plugin) {
|
||||
return scoreboardManagerMap.computeIfAbsent(plugin, name -> new ScoreboardManagerImpl(plugin));
|
||||
}
|
||||
|
||||
public static synchronized void init() {
|
||||
Preconditions.checkState(instance == null && ScoreboardManagerProvider.instance() == null);
|
||||
ScoreboardManagerProviderImpl provider = new ScoreboardManagerProviderImpl();
|
||||
instance = provider;
|
||||
ScoreboardManagerProvider.instance(provider);
|
||||
}
|
||||
@Override
|
||||
public Sidebar sidebar(Player player) {
|
||||
return sidebarMap.get(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public TeamInfo teamInfo(Collection<String> entries) {
|
||||
TeamInfoImpl impl = new TeamInfoImpl();
|
||||
if (entries != null) {
|
||||
impl.entries.addAll(entries);
|
||||
}
|
||||
|
||||
return impl;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ScoreboardManager scoreboardManager(JavaPlugin plugin) {
|
||||
return scoreboardManagerMap.computeIfAbsent(plugin, name -> new ScoreboardManagerImpl(plugin));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sidebar sidebar(Player player) {
|
||||
return sidebarMap.get(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamManagerImpl teamManager(Player player) {
|
||||
return teamManagerMap.get(player);
|
||||
}
|
||||
@Override
|
||||
public TeamManagerImpl teamManager(Player player) {
|
||||
return teamManagerMap.get(player);
|
||||
}
|
||||
}
|
||||
+22
-22
@@ -18,27 +18,27 @@ import java.util.Collections;
|
||||
|
||||
public record LocaleListener(ScoreboardManagerImpl instance) implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onPlayerLocaleChanged(PlayerLocaleChangeEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
// Need to wait a tick because the locale didn't update yet
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TeamManagerImpl teamManager = ScoreboardManagerProviderImpl.instance().teamManager(player);
|
||||
if (teamManager != null) {
|
||||
for (ScoreboardTeamImpl team : teamManager.teams.values()) {
|
||||
TeamInfoImpl teamInfo = team.teamInfo(player);
|
||||
teamInfo.nms.updateTeam(Collections.singleton(player));
|
||||
}
|
||||
}
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onPlayerLocaleChanged(PlayerLocaleChangeEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
// Need to wait a tick because the locale didn't update yet
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TeamManagerImpl teamManager = ScoreboardManagerProviderImpl.instance().teamManager(player);
|
||||
if (teamManager != null) {
|
||||
for (ScoreboardTeamImpl team : teamManager.teams.values()) {
|
||||
TeamInfoImpl teamInfo = team.teamInfo(player);
|
||||
teamInfo.nms.updateTeam(Collections.singleton(player));
|
||||
}
|
||||
}
|
||||
|
||||
AbstractSidebar sidebar = ScoreboardManagerProviderImpl.instance().sidebarMap.get(player);
|
||||
if (sidebar instanceof PlayerDependantLocaleSidebar) {
|
||||
sidebar.removePlayer(player);
|
||||
sidebar.addPlayer(player);
|
||||
}
|
||||
}
|
||||
}.runTaskLater(instance.plugin, 1);
|
||||
}
|
||||
AbstractSidebar sidebar = ScoreboardManagerProviderImpl.instance().sidebarMap.get(player);
|
||||
if (sidebar instanceof PlayerDependantLocaleSidebar) {
|
||||
sidebar.removePlayer(player);
|
||||
sidebar.addPlayer(player);
|
||||
}
|
||||
}
|
||||
}.runTaskLater(instance.plugin, 1);
|
||||
}
|
||||
}
|
||||
+12
-12
@@ -12,17 +12,17 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
public record PlayerListener(ScoreboardManagerImpl instance) implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
AbstractSidebar sidebar = ScoreboardManagerProviderImpl.instance().sidebarMap.get(player);
|
||||
if (sidebar != null) {
|
||||
sidebar.removePlayer(player);
|
||||
}
|
||||
|
||||
TeamManagerImpl teamManager = ScoreboardManagerProviderImpl.instance().teamManagerMap.get(player);
|
||||
if (teamManager != null) {
|
||||
teamManager.removePlayer(player);
|
||||
}
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
AbstractSidebar sidebar = ScoreboardManagerProviderImpl.instance().sidebarMap.get(player);
|
||||
if (sidebar != null) {
|
||||
sidebar.removePlayer(player);
|
||||
}
|
||||
|
||||
TeamManagerImpl teamManager = ScoreboardManagerProviderImpl.instance().teamManagerMap.get(player);
|
||||
if (teamManager != null) {
|
||||
teamManager.removePlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
+264
-264
@@ -26,287 +26,287 @@ import static net.kyori.adventure.text.Component.empty;
|
||||
|
||||
public abstract class AbstractSidebar implements Sidebar {
|
||||
|
||||
public final GlobalLineInfo[] lines;
|
||||
protected final Object lock = new Object();
|
||||
protected final Object visibilityLock = new Object();
|
||||
protected final Object playerLock = new Object();
|
||||
private final ScoreboardManager scoreboardManager;
|
||||
private final ComponentTranslator componentTranslator;
|
||||
private final AtomicBoolean updateTitle = new AtomicBoolean(),
|
||||
updateLines = new AtomicBoolean();
|
||||
protected volatile boolean closed, visible, visibilityChanged;
|
||||
private Component title = empty();
|
||||
private volatile SidebarNMS<?, ?> nms;
|
||||
public final GlobalLineInfo[] lines;
|
||||
protected final Object lock = new Object();
|
||||
protected final Object visibilityLock = new Object();
|
||||
protected final Object playerLock = new Object();
|
||||
private final ScoreboardManager scoreboardManager;
|
||||
private final ComponentTranslator componentTranslator;
|
||||
private final AtomicBoolean updateTitle = new AtomicBoolean(),
|
||||
updateLines = new AtomicBoolean();
|
||||
protected volatile boolean closed, visible, visibilityChanged;
|
||||
private Component title = empty();
|
||||
private volatile SidebarNMS<?, ?> nms;
|
||||
|
||||
public AbstractSidebar(ScoreboardManager scoreboardManager, ComponentTranslator componentTranslator, int size) {
|
||||
this.scoreboardManager = scoreboardManager;
|
||||
this.componentTranslator = componentTranslator;
|
||||
SidebarUtilities.checkLineBounds(size);
|
||||
this.lines = new GlobalLineInfo[size];
|
||||
public AbstractSidebar(ScoreboardManager scoreboardManager, ComponentTranslator componentTranslator, int size) {
|
||||
this.scoreboardManager = scoreboardManager;
|
||||
this.componentTranslator = componentTranslator;
|
||||
SidebarUtilities.checkLineBounds(size);
|
||||
this.lines = new GlobalLineInfo[size];
|
||||
}
|
||||
|
||||
protected abstract void forEachSidebar(Consumer<SidebarLineHandler> consumer);
|
||||
|
||||
protected abstract SidebarLineHandler addPlayer0(Player player);
|
||||
|
||||
protected abstract SidebarLineHandler removePlayer0(Player player);
|
||||
|
||||
protected void updateScores() {
|
||||
byte size = 0;
|
||||
for (GlobalLineInfo line : lines) {
|
||||
if (line != null && line.value != null) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void forEachSidebar(Consumer<SidebarLineHandler> consumer);
|
||||
|
||||
protected abstract SidebarLineHandler addPlayer0(Player player);
|
||||
|
||||
protected abstract SidebarLineHandler removePlayer0(Player player);
|
||||
|
||||
protected void updateScores() {
|
||||
byte size = 0;
|
||||
for (GlobalLineInfo line : lines) {
|
||||
if (line != null && line.value != null) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
byte i = 0;
|
||||
for (GlobalLineInfo line : lines) {
|
||||
if (line != null && line.value != null) {
|
||||
byte oldScore = line.objectiveScore;
|
||||
line.objectiveScore = (byte) (size - i - 1);
|
||||
if (line.objectiveScore != oldScore) line.updateScore = true;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
byte i = 0;
|
||||
for (GlobalLineInfo line : lines) {
|
||||
if (line != null && line.value != null) {
|
||||
byte oldScore = line.objectiveScore;
|
||||
line.objectiveScore = (byte) (size - i - 1);
|
||||
if (line.objectiveScore != oldScore) line.updateScore = true;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ScoreboardManager scoreboardManager() {
|
||||
return scoreboardManager;
|
||||
}
|
||||
@Override
|
||||
public @NotNull ScoreboardManager scoreboardManager() {
|
||||
return scoreboardManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ComponentTranslator componentTranslator() {
|
||||
return componentTranslator;
|
||||
}
|
||||
@Override
|
||||
public @NotNull ComponentTranslator componentTranslator() {
|
||||
return componentTranslator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte maxLines() {
|
||||
return (byte) lines.length;
|
||||
}
|
||||
@Override
|
||||
public byte maxLines() {
|
||||
return (byte) lines.length;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (closed) return;
|
||||
public void update() {
|
||||
if (closed) return;
|
||||
|
||||
synchronized (lock) {
|
||||
if (closed) return;
|
||||
synchronized (lock) {
|
||||
if (closed) return;
|
||||
|
||||
synchronized (playerLock) {
|
||||
Collection<Player> players = players();
|
||||
synchronized (playerLock) {
|
||||
Collection<Player> players = players();
|
||||
|
||||
if (visibilityChanged) {
|
||||
synchronized (visibilityLock) {
|
||||
if (!visibilityChanged) return;
|
||||
|
||||
if (visible) {
|
||||
sidebarBridge().create(players);
|
||||
forEachSidebar(SidebarLineHandler::show);
|
||||
ScoreboardManagerNMS.INSTANCE.displaySidebar(players);
|
||||
} else {
|
||||
forEachSidebar(SidebarLineHandler::hide);
|
||||
ScoreboardManagerNMS.INSTANCE.removeSidebar(players);
|
||||
}
|
||||
|
||||
visibilityChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateTitle.getAndSet(false)) {
|
||||
sidebarBridge().updateTitle(title);
|
||||
if (visible) {
|
||||
nms.update(players);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updateLines.getAndSet(false)) {
|
||||
updateScores();
|
||||
|
||||
boolean updateTeams = false;
|
||||
for (GlobalLineInfo line : lines) {
|
||||
if (line == null || !line.update) continue;
|
||||
line.updateTeams = true;
|
||||
updateTeams = true;
|
||||
|
||||
forEachSidebar(s -> {
|
||||
if (line.value != null) {
|
||||
Component rendered = componentTranslator.translate(line.value, s.locale());
|
||||
s.setLine(line.line, rendered);
|
||||
} else {
|
||||
s.setLine(line.line, null);
|
||||
}
|
||||
});
|
||||
|
||||
line.update = false;
|
||||
}
|
||||
|
||||
if (updateTeams) {
|
||||
forEachSidebar(SidebarLineHandler::update);
|
||||
|
||||
for (GlobalLineInfo line : lines) {
|
||||
if (line != null) line.updateTeams = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addPlayer(@NotNull Player player) {
|
||||
checkClosed();
|
||||
checkPlayer(player);
|
||||
|
||||
synchronized (playerLock) {
|
||||
SidebarLineHandler sidebar = addPlayer0(player);
|
||||
if (sidebar == null) return false;
|
||||
|
||||
LineType lineType = LineType.getType(player);
|
||||
sidebar.playersInit(lineType).add(player);
|
||||
|
||||
ScoreboardManagerProviderImpl.instance().sidebarMap.put(player, this);
|
||||
if (visibilityChanged) {
|
||||
synchronized (visibilityLock) {
|
||||
if (!visibilityChanged) return;
|
||||
|
||||
if (visible) {
|
||||
var singleton = Collections.singleton(player);
|
||||
sidebarBridge().create(singleton);
|
||||
sidebar.show(singleton, lineType);
|
||||
ScoreboardManagerNMS.INSTANCE.displaySidebar(singleton);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removePlayer(@NotNull Player player) {
|
||||
checkClosed();
|
||||
|
||||
synchronized (playerLock) {
|
||||
SidebarLineHandler sidebar = removePlayer0(player);
|
||||
if (sidebar == null) return false;
|
||||
|
||||
LineType lineType = LineType.getType(player);
|
||||
sidebar.players(lineType).remove(player);
|
||||
|
||||
ScoreboardManagerProviderImpl.instance().sidebarMap.remove(player, this);
|
||||
|
||||
if (visible) {
|
||||
var singleton = Collections.singleton(player);
|
||||
sidebar.hide(singleton, lineType);
|
||||
ScoreboardManagerNMS.INSTANCE.removeSidebar(singleton);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visible(boolean visible) {
|
||||
checkClosed();
|
||||
|
||||
if (this.visible == visible) return;
|
||||
|
||||
synchronized (visibilityLock) {
|
||||
if (this.visible == visible) return;
|
||||
|
||||
this.visible = visible;
|
||||
this.visibilityChanged = !visibilityChanged;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component title() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void line(int line, Component value) {
|
||||
checkClosed();
|
||||
checkLine(line);
|
||||
|
||||
Component component = line(line);
|
||||
if (Objects.equals(value, component)) return;
|
||||
|
||||
GlobalLineInfo lineInfo = getLineInfo(line);
|
||||
lineInfo.value = value;
|
||||
|
||||
if (visible) {
|
||||
lineInfo.update = true;
|
||||
updateLines.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Component line(int line) {
|
||||
GlobalLineInfo info = lines[line];
|
||||
return info == null ? null : info.value;
|
||||
}
|
||||
|
||||
public GlobalLineInfo getLineInfo(int line) {
|
||||
GlobalLineInfo info = lines[line];
|
||||
if (info == null) {
|
||||
info = new GlobalLineInfo((byte) line);
|
||||
lines[line] = info;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void title(Component title) {
|
||||
checkClosed();
|
||||
Preconditions.checkNotNull(title);
|
||||
|
||||
if (!this.title.equals(title)) {
|
||||
this.title = title;
|
||||
updateTitle.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
synchronized (lock) {
|
||||
removePlayers(players());
|
||||
visible = false;
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean closed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
public SidebarNMS<?, ?> sidebarBridge() {
|
||||
if (nms == null)
|
||||
synchronized (lock) {
|
||||
if (nms == null) nms = ScoreboardManagerNMS.INSTANCE.createSidebarNMS(this);
|
||||
sidebarBridge().create(players);
|
||||
forEachSidebar(SidebarLineHandler::show);
|
||||
ScoreboardManagerNMS.INSTANCE.displaySidebar(players);
|
||||
} else {
|
||||
forEachSidebar(SidebarLineHandler::hide);
|
||||
ScoreboardManagerNMS.INSTANCE.removeSidebar(players);
|
||||
}
|
||||
|
||||
return nms;
|
||||
}
|
||||
|
||||
private void checkPlayer(Player player) {
|
||||
// TODO: remove this restriction
|
||||
Sidebar sidebar = ScoreboardManagerProviderImpl.instance().sidebar(player);
|
||||
if (sidebar != null && sidebar != this)
|
||||
throw new IllegalArgumentException("Player " + player.getName() + " already has a sidebar");
|
||||
}
|
||||
|
||||
private void checkClosed() {
|
||||
if (closed) {
|
||||
throw new IllegalStateException("Sidebar is closed");
|
||||
visibilityChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateTitle.getAndSet(false)) {
|
||||
sidebarBridge().updateTitle(title);
|
||||
if (visible) {
|
||||
nms.update(players);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updateLines.getAndSet(false)) {
|
||||
updateScores();
|
||||
|
||||
boolean updateTeams = false;
|
||||
for (GlobalLineInfo line : lines) {
|
||||
if (line == null || !line.update) continue;
|
||||
line.updateTeams = true;
|
||||
updateTeams = true;
|
||||
|
||||
forEachSidebar(s -> {
|
||||
if (line.value != null) {
|
||||
Component rendered = componentTranslator.translate(line.value, s.locale());
|
||||
s.setLine(line.line, rendered);
|
||||
} else {
|
||||
s.setLine(line.line, null);
|
||||
}
|
||||
});
|
||||
|
||||
line.update = false;
|
||||
}
|
||||
|
||||
if (updateTeams) {
|
||||
forEachSidebar(SidebarLineHandler::update);
|
||||
|
||||
for (GlobalLineInfo line : lines) {
|
||||
if (line != null) line.updateTeams = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkLine(int line) {
|
||||
if (line > lines.length || line < 0) {
|
||||
throw new IndexOutOfBoundsException("Invalid line " + line);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addPlayer(@NotNull Player player) {
|
||||
checkClosed();
|
||||
checkPlayer(player);
|
||||
|
||||
synchronized (playerLock) {
|
||||
SidebarLineHandler sidebar = addPlayer0(player);
|
||||
if (sidebar == null) return false;
|
||||
|
||||
LineType lineType = LineType.getType(player);
|
||||
sidebar.playersInit(lineType).add(player);
|
||||
|
||||
ScoreboardManagerProviderImpl.instance().sidebarMap.put(player, this);
|
||||
|
||||
if (visible) {
|
||||
var singleton = Collections.singleton(player);
|
||||
sidebarBridge().create(singleton);
|
||||
sidebar.show(singleton, lineType);
|
||||
ScoreboardManagerNMS.INSTANCE.displaySidebar(singleton);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removePlayer(@NotNull Player player) {
|
||||
checkClosed();
|
||||
|
||||
synchronized (playerLock) {
|
||||
SidebarLineHandler sidebar = removePlayer0(player);
|
||||
if (sidebar == null) return false;
|
||||
|
||||
LineType lineType = LineType.getType(player);
|
||||
sidebar.players(lineType).remove(player);
|
||||
|
||||
ScoreboardManagerProviderImpl.instance().sidebarMap.remove(player, this);
|
||||
|
||||
if (visible) {
|
||||
var singleton = Collections.singleton(player);
|
||||
sidebar.hide(singleton, lineType);
|
||||
ScoreboardManagerNMS.INSTANCE.removeSidebar(singleton);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visible(boolean visible) {
|
||||
checkClosed();
|
||||
|
||||
if (this.visible == visible) return;
|
||||
|
||||
synchronized (visibilityLock) {
|
||||
if (this.visible == visible) return;
|
||||
|
||||
this.visible = visible;
|
||||
this.visibilityChanged = !visibilityChanged;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component title() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void line(int line, Component value) {
|
||||
checkClosed();
|
||||
checkLine(line);
|
||||
|
||||
Component component = line(line);
|
||||
if (Objects.equals(value, component)) return;
|
||||
|
||||
GlobalLineInfo lineInfo = getLineInfo(line);
|
||||
lineInfo.value = value;
|
||||
|
||||
if (visible) {
|
||||
lineInfo.update = true;
|
||||
updateLines.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Component line(int line) {
|
||||
GlobalLineInfo info = lines[line];
|
||||
return info == null ? null : info.value;
|
||||
}
|
||||
|
||||
public GlobalLineInfo getLineInfo(int line) {
|
||||
GlobalLineInfo info = lines[line];
|
||||
if (info == null) {
|
||||
info = new GlobalLineInfo((byte) line);
|
||||
lines[line] = info;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void title(Component title) {
|
||||
checkClosed();
|
||||
Preconditions.checkNotNull(title);
|
||||
|
||||
if (!this.title.equals(title)) {
|
||||
this.title = title;
|
||||
updateTitle.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
synchronized (lock) {
|
||||
removePlayers(players());
|
||||
visible = false;
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean closed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
public SidebarNMS<?, ?> sidebarBridge() {
|
||||
if (nms == null)
|
||||
synchronized (lock) {
|
||||
if (nms == null) nms = ScoreboardManagerNMS.INSTANCE.createSidebarNMS(this);
|
||||
}
|
||||
|
||||
return nms;
|
||||
}
|
||||
|
||||
private void checkPlayer(Player player) {
|
||||
// TODO: remove this restriction
|
||||
Sidebar sidebar = ScoreboardManagerProviderImpl.instance().sidebar(player);
|
||||
if (sidebar != null && sidebar != this)
|
||||
throw new IllegalArgumentException("Player " + player.getName() + " already has a sidebar");
|
||||
}
|
||||
|
||||
private void checkClosed() {
|
||||
if (closed) {
|
||||
throw new IllegalStateException("Sidebar is closed");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkLine(int line) {
|
||||
if (line > lines.length || line < 0) {
|
||||
throw new IndexOutOfBoundsException("Invalid line " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
+74
-74
@@ -17,86 +17,86 @@ import java.util.function.Consumer;
|
||||
|
||||
public class PlayerDependantLocaleSidebar extends AbstractSidebar {
|
||||
|
||||
private volatile Map<Player, SidebarLineHandler> playerMap;
|
||||
private volatile Map<Locale, SidebarLineHandler> localeMap;
|
||||
private volatile Map<Player, SidebarLineHandler> playerMap;
|
||||
private volatile Map<Locale, SidebarLineHandler> localeMap;
|
||||
|
||||
public PlayerDependantLocaleSidebar(ScoreboardManager scoreboardManager, ComponentTranslator componentTranslator, int size) {
|
||||
super(scoreboardManager, componentTranslator, size);
|
||||
public PlayerDependantLocaleSidebar(ScoreboardManager scoreboardManager, ComponentTranslator componentTranslator, int size) {
|
||||
super(scoreboardManager, componentTranslator, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Locale locale() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void forEachSidebar(Consumer<SidebarLineHandler> consumer) {
|
||||
if (localeMap != null) {
|
||||
for (SidebarLineHandler value : localeMap.values()) {
|
||||
consumer.accept(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Player> players() {
|
||||
return playerMap == null ? Collections.emptySet() : playerMap.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SidebarLineHandler addPlayer0(Player player) {
|
||||
SidebarLineHandler sidebar = playerMap == null ? null : playerMap.get(player);
|
||||
if (sidebar != null) {
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Locale locale() {
|
||||
return null;
|
||||
Locale locale = LocaleUtilities.getLocaleOfPlayer(player);
|
||||
|
||||
if (localeMap == null)
|
||||
synchronized (lock) {
|
||||
if (localeMap == null) localeMap = new ConcurrentHashMap<>(4, 0.75f, 2);
|
||||
}
|
||||
|
||||
sidebar = localeMap.get(locale);
|
||||
if (sidebar != null) {
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void forEachSidebar(Consumer<SidebarLineHandler> consumer) {
|
||||
if (localeMap != null) {
|
||||
for (SidebarLineHandler value : localeMap.values()) {
|
||||
consumer.accept(value);
|
||||
}
|
||||
}
|
||||
sidebar = new SidebarLineHandler(this, locale);
|
||||
|
||||
localeMap.put(locale, sidebar);
|
||||
|
||||
if (playerMap == null)
|
||||
synchronized (lock) {
|
||||
if (playerMap == null) playerMap = new ConcurrentHashMap<>(4, 0.75f, 2);
|
||||
}
|
||||
|
||||
playerMap.put(player, sidebar);
|
||||
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SidebarLineHandler removePlayer0(Player player) {
|
||||
if (playerMap == null) return null;
|
||||
|
||||
SidebarLineHandler lineHandler = playerMap.remove(player);
|
||||
if (lineHandler == null) return null;
|
||||
|
||||
if (!lineHandler.hasPlayers() && localeMap != null) {
|
||||
localeMap.remove(lineHandler.locale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Player> players() {
|
||||
return playerMap == null ? Collections.emptySet() : playerMap.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SidebarLineHandler addPlayer0(Player player) {
|
||||
SidebarLineHandler sidebar = playerMap == null ? null : playerMap.get(player);
|
||||
if (sidebar != null) {
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
Locale locale = LocaleUtilities.getLocaleOfPlayer(player);
|
||||
|
||||
if (localeMap == null)
|
||||
synchronized (lock) {
|
||||
if (localeMap == null) localeMap = new ConcurrentHashMap<>(4, 0.75f, 2);
|
||||
}
|
||||
|
||||
sidebar = localeMap.get(locale);
|
||||
if (sidebar != null) {
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
sidebar = new SidebarLineHandler(this, locale);
|
||||
|
||||
localeMap.put(locale, sidebar);
|
||||
|
||||
if (playerMap == null)
|
||||
synchronized (lock) {
|
||||
if (playerMap == null) playerMap = new ConcurrentHashMap<>(4, 0.75f, 2);
|
||||
}
|
||||
|
||||
playerMap.put(player, sidebar);
|
||||
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SidebarLineHandler removePlayer0(Player player) {
|
||||
if (playerMap == null) return null;
|
||||
|
||||
SidebarLineHandler lineHandler = playerMap.remove(player);
|
||||
if (lineHandler == null) return null;
|
||||
|
||||
if (!lineHandler.hasPlayers() && localeMap != null) {
|
||||
localeMap.remove(lineHandler.locale());
|
||||
}
|
||||
|
||||
return lineHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
|
||||
if (closed) {
|
||||
playerMap = null;
|
||||
localeMap = null;
|
||||
}
|
||||
return lineHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
|
||||
if (closed) {
|
||||
playerMap = null;
|
||||
localeMap = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-18
@@ -10,25 +10,25 @@ import java.util.logging.Logger;
|
||||
|
||||
public class SidebarUpdaterTask extends BukkitRunnable {
|
||||
|
||||
private final Logger logger;
|
||||
private final Set<AbstractSidebar> sidebars;
|
||||
private final Logger logger;
|
||||
private final Set<AbstractSidebar> sidebars;
|
||||
|
||||
public SidebarUpdaterTask(ScoreboardManagerImpl manager) {
|
||||
Preconditions.checkNotNull(manager);
|
||||
this.logger = manager.plugin().getLogger();
|
||||
this.sidebars = manager.sidebars;
|
||||
public SidebarUpdaterTask(ScoreboardManagerImpl manager) {
|
||||
Preconditions.checkNotNull(manager);
|
||||
this.logger = manager.plugin().getLogger();
|
||||
this.sidebars = manager.sidebars;
|
||||
|
||||
runTaskTimerAsynchronously(manager.plugin(), 1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (AbstractSidebar sidebar : sidebars) {
|
||||
try {
|
||||
sidebar.update();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Exception caught when updating Sidebar", e);
|
||||
}
|
||||
}
|
||||
runTaskTimerAsynchronously(manager.plugin(), 1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (AbstractSidebar sidebar : sidebars) {
|
||||
try {
|
||||
sidebar.update();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Exception caught when updating Sidebar", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
-59
@@ -16,70 +16,70 @@ import java.util.function.Consumer;
|
||||
|
||||
public class SingleLocaleSidebar extends AbstractSidebar {
|
||||
|
||||
private final Locale locale;
|
||||
private volatile SidebarLineHandler sidebar;
|
||||
private volatile Set<Player> players;
|
||||
private final Locale locale;
|
||||
private volatile SidebarLineHandler sidebar;
|
||||
private volatile Set<Player> players;
|
||||
|
||||
public SingleLocaleSidebar(ScoreboardManager scoreboardManager, ComponentTranslator componentTranslator, int size, Locale locale) {
|
||||
super(scoreboardManager, componentTranslator, size);
|
||||
this.locale = locale;
|
||||
public SingleLocaleSidebar(ScoreboardManager scoreboardManager, ComponentTranslator componentTranslator, int size, Locale locale) {
|
||||
super(scoreboardManager, componentTranslator, size);
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Player> players() {
|
||||
return players == null ? Collections.emptySet() : Collections.unmodifiableCollection(players);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SidebarLineHandler addPlayer0(Player player) {
|
||||
if (!playerSet().add(player)) return null;
|
||||
|
||||
return lineHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SidebarLineHandler removePlayer0(Player player) {
|
||||
if (players == null || !players.remove(player)) return null;
|
||||
|
||||
return lineHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Locale locale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void forEachSidebar(Consumer<SidebarLineHandler> consumer) {
|
||||
consumer.accept(lineHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
|
||||
if (closed) {
|
||||
players = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Player> players() {
|
||||
return players == null ? Collections.emptySet() : Collections.unmodifiableCollection(players);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SidebarLineHandler addPlayer0(Player player) {
|
||||
if (!playerSet().add(player)) return null;
|
||||
|
||||
return lineHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SidebarLineHandler removePlayer0(Player player) {
|
||||
if (players == null || !players.remove(player)) return null;
|
||||
|
||||
return lineHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Locale locale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void forEachSidebar(Consumer<SidebarLineHandler> consumer) {
|
||||
consumer.accept(lineHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
|
||||
if (closed) {
|
||||
players = null;
|
||||
private Set<Player> playerSet() {
|
||||
if (players == null)
|
||||
synchronized (lock) {
|
||||
if (players == null) {
|
||||
players = CollectionProvider.set(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Player> playerSet() {
|
||||
if (players == null)
|
||||
synchronized (lock) {
|
||||
if (players == null) {
|
||||
players = CollectionProvider.set(1);
|
||||
}
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
private SidebarLineHandler lineHandler() {
|
||||
if (sidebar == null)
|
||||
synchronized (lock) {
|
||||
if (sidebar == null) sidebar = new SidebarLineHandler(this, locale());
|
||||
}
|
||||
|
||||
private SidebarLineHandler lineHandler() {
|
||||
if (sidebar == null)
|
||||
synchronized (lock) {
|
||||
if (sidebar == null) sidebar = new SidebarLineHandler(this, locale());
|
||||
}
|
||||
|
||||
return sidebar;
|
||||
}
|
||||
return sidebar;
|
||||
}
|
||||
}
|
||||
+18
-18
@@ -7,27 +7,27 @@ import org.bukkit.ChatColor;
|
||||
|
||||
public class GlobalLineInfo {
|
||||
|
||||
private static final String[] lineColors = new String[15];
|
||||
private static final String[] lineColors = new String[15];
|
||||
|
||||
static {
|
||||
ChatColor[] values = ChatColor.values();
|
||||
for (byte i = 0; i < lineColors.length; i++) {
|
||||
lineColors[i] = values[i].toString();
|
||||
}
|
||||
static {
|
||||
ChatColor[] values = ChatColor.values();
|
||||
for (byte i = 0; i < lineColors.length; i++) {
|
||||
lineColors[i] = values[i].toString();
|
||||
}
|
||||
}
|
||||
|
||||
public final byte line;
|
||||
public final TeamNMS<?, ?> bridge;
|
||||
public Component value;
|
||||
public byte objectiveScore;
|
||||
public boolean update, updateTeams, updateScore;
|
||||
public final byte line;
|
||||
public final TeamNMS<?, ?> bridge;
|
||||
public Component value;
|
||||
public byte objectiveScore;
|
||||
public boolean update, updateTeams, updateScore;
|
||||
|
||||
public GlobalLineInfo(byte line) {
|
||||
this.line = line;
|
||||
this.bridge = ScoreboardManagerNMS.INSTANCE.createTeamNMS("_l" + line);
|
||||
}
|
||||
public GlobalLineInfo(byte line) {
|
||||
this.line = line;
|
||||
this.bridge = ScoreboardManagerNMS.INSTANCE.createTeamNMS("_l" + line);
|
||||
}
|
||||
|
||||
public String player() {
|
||||
return lineColors[line];
|
||||
}
|
||||
public String player() {
|
||||
return lineColors[line];
|
||||
}
|
||||
}
|
||||
+138
-138
@@ -13,170 +13,170 @@ import java.util.Set;
|
||||
|
||||
public class SidebarLineHandler {
|
||||
|
||||
private final AbstractSidebar sidebar;
|
||||
private final Locale locale;
|
||||
private final AbstractSidebar sidebar;
|
||||
private final Locale locale;
|
||||
|
||||
private Set<Player> players, legacyPlayers;
|
||||
private LocaleLine<?>[] lines, legacyLines;
|
||||
private Set<Player> players, legacyPlayers;
|
||||
private LocaleLine<?>[] lines, legacyLines;
|
||||
|
||||
public SidebarLineHandler(AbstractSidebar sidebar, Locale locale) {
|
||||
this.sidebar = sidebar;
|
||||
this.locale = locale;
|
||||
public SidebarLineHandler(AbstractSidebar sidebar, Locale locale) {
|
||||
this.sidebar = sidebar;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public AbstractSidebar sidebar() {
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
public Locale locale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public boolean hasPlayers() {
|
||||
if (players != null && !players.isEmpty()) return true;
|
||||
return legacyPlayers != null && !legacyPlayers.isEmpty();
|
||||
}
|
||||
|
||||
public Set<Player> players(LineType lineType) {
|
||||
if (lineType == LineType.NEW) {
|
||||
return players;
|
||||
} else {
|
||||
return legacyPlayers;
|
||||
}
|
||||
}
|
||||
|
||||
public AbstractSidebar sidebar() {
|
||||
return sidebar;
|
||||
public Set<Player> playersInit(LineType lineType) {
|
||||
if (lineType == LineType.NEW) {
|
||||
if (players == null) players = CollectionProvider.set(1);
|
||||
return players;
|
||||
} else {
|
||||
if (legacyPlayers == null) legacyPlayers = CollectionProvider.set(1);
|
||||
return legacyPlayers;
|
||||
}
|
||||
}
|
||||
|
||||
public Locale locale() {
|
||||
return locale;
|
||||
public LocaleLine<?>[] lines(LineType lineType) {
|
||||
if (lineType == LineType.NEW) {
|
||||
return lines;
|
||||
} else {
|
||||
return legacyLines;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasPlayers() {
|
||||
if (players != null && !players.isEmpty()) return true;
|
||||
return legacyPlayers != null && !legacyPlayers.isEmpty();
|
||||
public LocaleLine<?>[] linesInit(LineType lineType) {
|
||||
if (lineType == LineType.NEW) {
|
||||
if (lines == null) {
|
||||
lines = new LocaleLine[sidebar.maxLines()];
|
||||
initLines(lineType);
|
||||
}
|
||||
return lines;
|
||||
} else {
|
||||
if (legacyLines == null) {
|
||||
legacyLines = new LocaleLine[sidebar.maxLines()];
|
||||
initLines(lineType);
|
||||
}
|
||||
return legacyLines;
|
||||
}
|
||||
}
|
||||
|
||||
public Set<Player> players(LineType lineType) {
|
||||
if (lineType == LineType.NEW) {
|
||||
return players;
|
||||
} else {
|
||||
return legacyPlayers;
|
||||
}
|
||||
}
|
||||
public void update() {
|
||||
update(LineType.NEW);
|
||||
update(LineType.LEGACY);
|
||||
}
|
||||
|
||||
public Set<Player> playersInit(LineType lineType) {
|
||||
if (lineType == LineType.NEW) {
|
||||
if (players == null) players = CollectionProvider.set(1);
|
||||
return players;
|
||||
} else {
|
||||
if (legacyPlayers == null) legacyPlayers = CollectionProvider.set(1);
|
||||
return legacyPlayers;
|
||||
}
|
||||
}
|
||||
private void update(LineType lineType) {
|
||||
LocaleLine<?>[] lines = lines(lineType);
|
||||
if (lines == null) return;
|
||||
Set<Player> players = players(lineType);
|
||||
|
||||
public LocaleLine<?>[] lines(LineType lineType) {
|
||||
if (lineType == LineType.NEW) {
|
||||
return lines;
|
||||
} else {
|
||||
return legacyLines;
|
||||
}
|
||||
}
|
||||
|
||||
public LocaleLine<?>[] linesInit(LineType lineType) {
|
||||
if (lineType == LineType.NEW) {
|
||||
if (lines == null) {
|
||||
lines = new LocaleLine[sidebar.maxLines()];
|
||||
initLines(lineType);
|
||||
}
|
||||
return lines;
|
||||
} else {
|
||||
if (legacyLines == null) {
|
||||
legacyLines = new LocaleLine[sidebar.maxLines()];
|
||||
initLines(lineType);
|
||||
}
|
||||
return legacyLines;
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
update(LineType.NEW);
|
||||
update(LineType.LEGACY);
|
||||
}
|
||||
|
||||
private void update(LineType lineType) {
|
||||
LocaleLine<?>[] lines = lines(lineType);
|
||||
if (lines == null) return;
|
||||
Set<Player> players = players(lineType);
|
||||
|
||||
for (LocaleLine<?> line : lines) {
|
||||
if (line != null) {
|
||||
if (line.info().updateTeams) {
|
||||
line.updateTeam();
|
||||
}
|
||||
|
||||
if (line.info().updateScore && sidebar.visible()) {
|
||||
line.sendScore(players);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setLine(int line, Component renderedLine) {
|
||||
setLine(line, renderedLine, LineType.NEW);
|
||||
setLine(line, renderedLine, LineType.LEGACY);
|
||||
}
|
||||
|
||||
public void setLine(int line, Component renderedLine, LineType lineType) {
|
||||
setLine(line, renderedLine, lineType, true);
|
||||
}
|
||||
|
||||
public void setLine(int line, Component renderedLine, LineType lineType, boolean sendPackets) {
|
||||
LocaleLine<?>[] lines = lines(lineType);
|
||||
if (lines == null) return;
|
||||
|
||||
LocaleLine<?> localeLine = lines[line];
|
||||
if (renderedLine == null && localeLine == null) {
|
||||
return;
|
||||
for (LocaleLine<?> line : lines) {
|
||||
if (line != null) {
|
||||
if (line.info().updateTeams) {
|
||||
line.updateTeam();
|
||||
}
|
||||
|
||||
boolean newlyCreated = false;
|
||||
if (localeLine == null) {
|
||||
lines[line] = localeLine = lineType.create(sidebar.getLineInfo(line), this);
|
||||
newlyCreated = true;
|
||||
if (line.info().updateScore && sidebar.visible()) {
|
||||
line.sendScore(players);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (renderedLine == null) {
|
||||
lines[line] = null;
|
||||
} else {
|
||||
localeLine.value(renderedLine);
|
||||
}
|
||||
public void setLine(int line, Component renderedLine) {
|
||||
setLine(line, renderedLine, LineType.NEW);
|
||||
setLine(line, renderedLine, LineType.LEGACY);
|
||||
}
|
||||
|
||||
if (!sidebar.visible() || !sendPackets) return;
|
||||
public void setLine(int line, Component renderedLine, LineType lineType) {
|
||||
setLine(line, renderedLine, lineType, true);
|
||||
}
|
||||
|
||||
Collection<Player> players = players(lineType);
|
||||
public void setLine(int line, Component renderedLine, LineType lineType, boolean sendPackets) {
|
||||
LocaleLine<?>[] lines = lines(lineType);
|
||||
if (lines == null) return;
|
||||
|
||||
if (renderedLine == null) {
|
||||
localeLine.hide(players);
|
||||
} else if (newlyCreated) {
|
||||
localeLine.show(players);
|
||||
}
|
||||
LocaleLine<?> localeLine = lines[line];
|
||||
if (renderedLine == null && localeLine == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (players != null) show(players, LineType.NEW);
|
||||
if (legacyPlayers != null) show(legacyPlayers, LineType.LEGACY);
|
||||
boolean newlyCreated = false;
|
||||
if (localeLine == null) {
|
||||
lines[line] = localeLine = lineType.create(sidebar.getLineInfo(line), this);
|
||||
newlyCreated = true;
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
if (players != null) hide(players, LineType.NEW);
|
||||
if (legacyPlayers != null) hide(legacyPlayers, LineType.LEGACY);
|
||||
if (renderedLine == null) {
|
||||
lines[line] = null;
|
||||
} else {
|
||||
localeLine.value(renderedLine);
|
||||
}
|
||||
|
||||
public void show(Collection<Player> players, LineType lineType) {
|
||||
LocaleLine<?>[] lines = linesInit(lineType);
|
||||
for (LocaleLine<?> line : lines) {
|
||||
if (line != null && line.info().value != null) {
|
||||
line.show(players);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!sidebar.visible() || !sendPackets) return;
|
||||
|
||||
public void hide(Collection<Player> players, LineType lineType) {
|
||||
LocaleLine<?>[] lines = lines(lineType);
|
||||
if (lines == null) return;
|
||||
for (LocaleLine<?> line : lines) {
|
||||
if (line != null && ((line.info().update) || line.info().value != null)) {
|
||||
line.hide(players);
|
||||
}
|
||||
}
|
||||
}
|
||||
Collection<Player> players = players(lineType);
|
||||
|
||||
private void initLines(LineType lineType) {
|
||||
for (GlobalLineInfo line : sidebar.lines) {
|
||||
if (line != null) {
|
||||
setLine(line.line, sidebar.componentTranslator().translate(line.value, locale), lineType, false);
|
||||
}
|
||||
}
|
||||
if (renderedLine == null) {
|
||||
localeLine.hide(players);
|
||||
} else if (newlyCreated) {
|
||||
localeLine.show(players);
|
||||
}
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (players != null) show(players, LineType.NEW);
|
||||
if (legacyPlayers != null) show(legacyPlayers, LineType.LEGACY);
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
if (players != null) hide(players, LineType.NEW);
|
||||
if (legacyPlayers != null) hide(legacyPlayers, LineType.LEGACY);
|
||||
}
|
||||
|
||||
public void show(Collection<Player> players, LineType lineType) {
|
||||
LocaleLine<?>[] lines = linesInit(lineType);
|
||||
for (LocaleLine<?> line : lines) {
|
||||
if (line != null && line.info().value != null) {
|
||||
line.show(players);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void hide(Collection<Player> players, LineType lineType) {
|
||||
LocaleLine<?>[] lines = lines(lineType);
|
||||
if (lines == null) return;
|
||||
for (LocaleLine<?> line : lines) {
|
||||
if (line != null && ((line.info().update) || line.info().value != null)) {
|
||||
line.hide(players);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initLines(LineType lineType) {
|
||||
for (GlobalLineInfo line : sidebar.lines) {
|
||||
if (line != null) {
|
||||
setLine(line.line, sidebar.componentTranslator().translate(line.value, locale), lineType, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+116
-116
@@ -14,142 +14,142 @@ import java.util.Set;
|
||||
|
||||
class LegacyLocaleLine implements LocaleLine<String> {
|
||||
|
||||
private final GlobalLineInfo info;
|
||||
private final SidebarLineHandler handler;
|
||||
private final TeamNMS.TeamInfoNMS<String> bridge;
|
||||
private String player, oldPlayer;
|
||||
private String prefix, suffix;
|
||||
private String currentValue;
|
||||
private boolean update = false;
|
||||
private final GlobalLineInfo info;
|
||||
private final SidebarLineHandler handler;
|
||||
private final TeamNMS.TeamInfoNMS<String> bridge;
|
||||
private String player, oldPlayer;
|
||||
private String prefix, suffix;
|
||||
private String currentValue;
|
||||
private boolean update = false;
|
||||
|
||||
public LegacyLocaleLine(GlobalLineInfo info, SidebarLineHandler handler) {
|
||||
this.info = info;
|
||||
this.handler = handler;
|
||||
public LegacyLocaleLine(GlobalLineInfo info, SidebarLineHandler handler) {
|
||||
this.info = info;
|
||||
this.handler = handler;
|
||||
this.player = info.player();
|
||||
this.bridge = info.bridge.createLegacyTeamInfoNMS(this);
|
||||
bridge.updateTeamPackets(entries());
|
||||
}
|
||||
|
||||
public GlobalLineInfo info() {
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String prefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String suffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> entries() {
|
||||
return Collections.singleton(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Component renderedComponent) {
|
||||
String legacyValue = LegacyComponentSerializer.legacySection().serialize(renderedComponent);
|
||||
|
||||
oldPlayer = player;
|
||||
|
||||
if (legacyValue.length() <= 16) {
|
||||
this.prefix = legacyValue;
|
||||
this.suffix = "";
|
||||
|
||||
if (this.currentValue != null && this.currentValue.length() > 32) {
|
||||
this.player = info.player();
|
||||
this.bridge = info.bridge.createLegacyTeamInfoNMS(this);
|
||||
bridge.updateTeamPackets(entries());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolean color = legacyValue.charAt(15) == ChatColor.COLOR_CHAR;
|
||||
|
||||
public GlobalLineInfo info() {
|
||||
return info;
|
||||
}
|
||||
int prefixEnd = color ? 15 : 16;
|
||||
this.prefix = legacyValue.substring(0, prefixEnd);
|
||||
|
||||
@Override
|
||||
public String displayName() {
|
||||
return "";
|
||||
}
|
||||
this.player = info.player() + ChatColor.RESET
|
||||
+ ChatColor.getLastColors(prefix +
|
||||
ChatColor.COLOR_CHAR + (color ? legacyValue.charAt(16) : ""));
|
||||
|
||||
@Override
|
||||
public String prefix() {
|
||||
return prefix;
|
||||
}
|
||||
int playerEnd = prefixEnd;
|
||||
if (legacyValue.length() > 32) {
|
||||
int remaining = 16 - player.length();
|
||||
assert remaining > 0;
|
||||
|
||||
@Override
|
||||
public String suffix() {
|
||||
return suffix;
|
||||
}
|
||||
playerEnd += remaining;
|
||||
player += legacyValue.substring(prefixEnd, playerEnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> entries() {
|
||||
return Collections.singleton(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Component renderedComponent) {
|
||||
String legacyValue = LegacyComponentSerializer.legacySection().serialize(renderedComponent);
|
||||
|
||||
oldPlayer = player;
|
||||
|
||||
if (legacyValue.length() <= 16) {
|
||||
this.prefix = legacyValue;
|
||||
this.suffix = "";
|
||||
|
||||
if (this.currentValue != null && this.currentValue.length() > 32) {
|
||||
this.player = info.player();
|
||||
}
|
||||
} else {
|
||||
boolean color = legacyValue.charAt(15) == ChatColor.COLOR_CHAR;
|
||||
|
||||
int prefixEnd = color ? 15 : 16;
|
||||
this.prefix = legacyValue.substring(0, prefixEnd);
|
||||
|
||||
this.player = info.player() + ChatColor.RESET
|
||||
+ ChatColor.getLastColors(prefix +
|
||||
ChatColor.COLOR_CHAR + (color ? legacyValue.charAt(16) : ""));
|
||||
|
||||
int playerEnd = prefixEnd;
|
||||
if (legacyValue.length() > 32) {
|
||||
int remaining = 16 - player.length();
|
||||
assert remaining > 0;
|
||||
|
||||
playerEnd += remaining;
|
||||
player += legacyValue.substring(prefixEnd, playerEnd);
|
||||
}
|
||||
|
||||
this.suffix = legacyValue.substring(playerEnd + (color ? 2 : 0));
|
||||
if (suffix.length() > 16) {
|
||||
String newSuffix = suffix.substring(0, 16);
|
||||
if (newSuffix.endsWith(String.valueOf(ChatColor.COLOR_CHAR)) &&
|
||||
ChatColor.getByChar(suffix.charAt(16)) != null) {
|
||||
newSuffix = newSuffix.substring(0, 15);
|
||||
}
|
||||
|
||||
suffix = newSuffix;
|
||||
}
|
||||
this.suffix = legacyValue.substring(playerEnd + (color ? 2 : 0));
|
||||
if (suffix.length() > 16) {
|
||||
String newSuffix = suffix.substring(0, 16);
|
||||
if (newSuffix.endsWith(String.valueOf(ChatColor.COLOR_CHAR)) &&
|
||||
ChatColor.getByChar(suffix.charAt(16)) != null) {
|
||||
newSuffix = newSuffix.substring(0, 15);
|
||||
}
|
||||
|
||||
currentValue = legacyValue;
|
||||
update = true;
|
||||
|
||||
if (oldPlayer.equals(player)) {
|
||||
oldPlayer = null;
|
||||
}
|
||||
suffix = newSuffix;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTeam() {
|
||||
if (!update) {
|
||||
return;
|
||||
}
|
||||
currentValue = legacyValue;
|
||||
update = true;
|
||||
|
||||
Set<Player> players = handler.players(LineType.LEGACY);
|
||||
if (oldPlayer != null) {
|
||||
bridge.removeEntries(players, Collections.singleton(oldPlayer));
|
||||
handler.sidebar().sidebarBridge().removeLine(players, oldPlayer);
|
||||
oldPlayer = null;
|
||||
}
|
||||
if (oldPlayer.equals(player)) {
|
||||
oldPlayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
Collection<String> entries = entries();
|
||||
bridge.updateTeamPackets(entries);
|
||||
bridge.addEntries(players, entries);
|
||||
bridge.updateTeam(players);
|
||||
|
||||
update = false;
|
||||
@Override
|
||||
public void updateTeam() {
|
||||
if (!update) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendScore(Collection<Player> players) {
|
||||
if (oldPlayer != null) {
|
||||
handler.sidebar().sidebarBridge().removeLine(players, oldPlayer);
|
||||
}
|
||||
|
||||
handler.sidebar().sidebarBridge().score(players, info.objectiveScore, player);
|
||||
Set<Player> players = handler.players(LineType.LEGACY);
|
||||
if (oldPlayer != null) {
|
||||
bridge.removeEntries(players, Collections.singleton(oldPlayer));
|
||||
handler.sidebar().sidebarBridge().removeLine(players, oldPlayer);
|
||||
oldPlayer = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(Collection<Player> players) {
|
||||
sendScore(players);
|
||||
bridge.createTeam(players);
|
||||
Collection<String> entries = entries();
|
||||
bridge.updateTeamPackets(entries);
|
||||
bridge.addEntries(players, entries);
|
||||
bridge.updateTeam(players);
|
||||
|
||||
update = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendScore(Collection<Player> players) {
|
||||
if (oldPlayer != null) {
|
||||
handler.sidebar().sidebarBridge().removeLine(players, oldPlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide(Collection<Player> players) {
|
||||
if (oldPlayer != null) {
|
||||
handler.sidebar().sidebarBridge().removeLine(players, oldPlayer);
|
||||
}
|
||||
handler.sidebar().sidebarBridge().score(players, info.objectiveScore, player);
|
||||
}
|
||||
|
||||
handler.sidebar().sidebarBridge().removeLine(players, player);
|
||||
info.bridge.removeTeam(players);
|
||||
@Override
|
||||
public void show(Collection<Player> players) {
|
||||
sendScore(players);
|
||||
bridge.createTeam(players);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide(Collection<Player> players) {
|
||||
if (oldPlayer != null) {
|
||||
handler.sidebar().sidebarBridge().removeLine(players, oldPlayer);
|
||||
}
|
||||
|
||||
handler.sidebar().sidebarBridge().removeLine(players, player);
|
||||
info.bridge.removeTeam(players);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -8,20 +8,20 @@ import org.bukkit.entity.Player;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public enum LineType {
|
||||
NEW(LocaleLineImpl::new),
|
||||
LEGACY(LegacyLocaleLine::new);
|
||||
NEW(LocaleLineImpl::new),
|
||||
LEGACY(LegacyLocaleLine::new);
|
||||
|
||||
private final BiFunction<GlobalLineInfo, SidebarLineHandler, LocaleLine<?>> constructor;
|
||||
private final BiFunction<GlobalLineInfo, SidebarLineHandler, LocaleLine<?>> constructor;
|
||||
|
||||
LineType(BiFunction<GlobalLineInfo, SidebarLineHandler, LocaleLine<?>> constructor) {
|
||||
this.constructor = constructor;
|
||||
}
|
||||
LineType(BiFunction<GlobalLineInfo, SidebarLineHandler, LocaleLine<?>> constructor) {
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
public static LineType getType(Player player) {
|
||||
return ScoreboardManagerNMS.INSTANCE.isLegacy(player) ? LEGACY : NEW;
|
||||
}
|
||||
public static LineType getType(Player player) {
|
||||
return ScoreboardManagerNMS.INSTANCE.isLegacy(player) ? LEGACY : NEW;
|
||||
}
|
||||
|
||||
public LocaleLine<?> create(GlobalLineInfo line, SidebarLineHandler sidebarLineHandler) {
|
||||
return constructor.apply(line, sidebarLineHandler);
|
||||
}
|
||||
public LocaleLine<?> create(GlobalLineInfo line, SidebarLineHandler sidebarLineHandler) {
|
||||
return constructor.apply(line, sidebarLineHandler);
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -8,15 +8,15 @@ import org.bukkit.entity.Player;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface LocaleLine<C> extends ImmutableTeamProperties<C> {
|
||||
GlobalLineInfo info();
|
||||
GlobalLineInfo info();
|
||||
|
||||
void value(Component renderedComponent);
|
||||
void value(Component renderedComponent);
|
||||
|
||||
void updateTeam();
|
||||
void updateTeam();
|
||||
|
||||
void sendScore(Collection<Player> players);
|
||||
void sendScore(Collection<Player> players);
|
||||
|
||||
void show(Collection<Player> players);
|
||||
void show(Collection<Player> players);
|
||||
|
||||
void hide(Collection<Player> players);
|
||||
void hide(Collection<Player> players);
|
||||
}
|
||||
+61
-61
@@ -14,75 +14,75 @@ import static net.kyori.adventure.text.Component.empty;
|
||||
// Implementation for new versions above 1.12.2
|
||||
class LocaleLineImpl implements LocaleLine<Component> {
|
||||
|
||||
private final GlobalLineInfo info;
|
||||
private final SidebarLineHandler handler;
|
||||
private final Collection<String> entries;
|
||||
private final TeamNMS.TeamInfoNMS<Component> bridge;
|
||||
private boolean update = false;
|
||||
private final GlobalLineInfo info;
|
||||
private final SidebarLineHandler handler;
|
||||
private final Collection<String> entries;
|
||||
private final TeamNMS.TeamInfoNMS<Component> bridge;
|
||||
private boolean update = false;
|
||||
|
||||
public LocaleLineImpl(GlobalLineInfo info, SidebarLineHandler handler) {
|
||||
this.info = info;
|
||||
this.handler = handler;
|
||||
this.entries = Collections.singletonList(info.player());
|
||||
this.bridge = info.bridge.createTeamInfoNMS(this, handler.sidebar().componentTranslator());
|
||||
bridge.updateTeamPackets(entries);
|
||||
public LocaleLineImpl(GlobalLineInfo info, SidebarLineHandler handler) {
|
||||
this.info = info;
|
||||
this.handler = handler;
|
||||
this.entries = Collections.singletonList(info.player());
|
||||
this.bridge = info.bridge.createTeamInfoNMS(this, handler.sidebar().componentTranslator());
|
||||
bridge.updateTeamPackets(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalLineInfo info() {
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Component renderedComponent) {
|
||||
update = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTeam() {
|
||||
if (!update) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalLineInfo info() {
|
||||
return info;
|
||||
}
|
||||
bridge.updateTeamPackets(entries);
|
||||
if (handler.sidebar().visible()) bridge.updateTeam(handler.players(LineType.NEW));
|
||||
update = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Component renderedComponent) {
|
||||
update = true;
|
||||
}
|
||||
@Override
|
||||
public void sendScore(Collection<Player> players) {
|
||||
handler.sidebar().sidebarBridge().score(players, info.objectiveScore, info.player());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTeam() {
|
||||
if (!update) {
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void show(Collection<Player> players) {
|
||||
sendScore(players);
|
||||
bridge.createTeam(players);
|
||||
}
|
||||
|
||||
bridge.updateTeamPackets(entries);
|
||||
if (handler.sidebar().visible()) bridge.updateTeam(handler.players(LineType.NEW));
|
||||
update = false;
|
||||
}
|
||||
@Override
|
||||
public void hide(Collection<Player> players) {
|
||||
handler.sidebar().sidebarBridge().removeLine(players, info.player());
|
||||
info.bridge.removeTeam(players);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendScore(Collection<Player> players) {
|
||||
handler.sidebar().sidebarBridge().score(players, info.objectiveScore, info.player());
|
||||
}
|
||||
@Override
|
||||
public Collection<String> entries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(Collection<Player> players) {
|
||||
sendScore(players);
|
||||
bridge.createTeam(players);
|
||||
}
|
||||
@Override
|
||||
public Component displayName() {
|
||||
return empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide(Collection<Player> players) {
|
||||
handler.sidebar().sidebarBridge().removeLine(players, info.player());
|
||||
info.bridge.removeTeam(players);
|
||||
}
|
||||
@Override
|
||||
public Component prefix() {
|
||||
return info.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> entries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component displayName() {
|
||||
return empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component prefix() {
|
||||
return info.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component suffix() {
|
||||
return empty();
|
||||
}
|
||||
@Override
|
||||
public Component suffix() {
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
+135
-135
@@ -18,166 +18,166 @@ import java.util.Set;
|
||||
|
||||
public class ScoreboardTeamImpl implements ScoreboardTeam {
|
||||
|
||||
public final TeamManagerImpl teamManager;
|
||||
public final String name;
|
||||
public final TeamNMS<?, ?> nms;
|
||||
public Collection<TeamInfoImpl> infos;
|
||||
public boolean closed;
|
||||
short idCounter = 0;
|
||||
private TeamInfoImpl globalInfo;
|
||||
public final TeamManagerImpl teamManager;
|
||||
public final String name;
|
||||
public final TeamNMS<?, ?> nms;
|
||||
public Collection<TeamInfoImpl> infos;
|
||||
public boolean closed;
|
||||
short idCounter = 0;
|
||||
private TeamInfoImpl globalInfo;
|
||||
|
||||
public ScoreboardTeamImpl(TeamManagerImpl teamManager, String name) {
|
||||
this.teamManager = teamManager;
|
||||
this.name = name;
|
||||
this.nms = ScoreboardManagerNMS.INSTANCE.createTeamNMS(name);
|
||||
public ScoreboardTeamImpl(TeamManagerImpl teamManager, String name) {
|
||||
this.teamManager = teamManager;
|
||||
this.name = name;
|
||||
this.nms = ScoreboardManagerNMS.INSTANCE.createTeamNMS(name);
|
||||
}
|
||||
|
||||
public Collection<TeamInfoImpl> teamInfos() {
|
||||
if (infos == null) {
|
||||
infos = CollectionProvider.set(1);
|
||||
}
|
||||
|
||||
public Collection<TeamInfoImpl> teamInfos() {
|
||||
if (infos == null) {
|
||||
infos = CollectionProvider.set(1);
|
||||
}
|
||||
return infos;
|
||||
}
|
||||
|
||||
return infos;
|
||||
public void update() {
|
||||
if (infos == null) return;
|
||||
for (TeamInfoImpl teamInfo : infos) {
|
||||
teamInfo.update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TeamInfoImpl globalInfo() {
|
||||
if (globalInfo == null) {
|
||||
globalInfo = new TeamInfoImpl();
|
||||
globalInfo.assign(this);
|
||||
infos.add(globalInfo);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (infos == null) return;
|
||||
for (TeamInfoImpl teamInfo : infos) {
|
||||
teamInfo.update();
|
||||
}
|
||||
return globalInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TeamManager teamManager() {
|
||||
return teamManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TeamInfoImpl teamInfo(Player player) {
|
||||
return getTeamInfo(player, true, false);
|
||||
}
|
||||
|
||||
public TeamInfoImpl getTeamInfo(Player player, boolean check, boolean nullable) {
|
||||
checkDestroyed();
|
||||
if (check) {
|
||||
checkPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TeamInfoImpl globalInfo() {
|
||||
if (globalInfo == null) {
|
||||
globalInfo = new TeamInfoImpl();
|
||||
globalInfo.assign(this);
|
||||
infos.add(globalInfo);
|
||||
}
|
||||
|
||||
return globalInfo;
|
||||
for (TeamInfoImpl teamInfo : infos) {
|
||||
if (teamInfo.players.contains(player)) {
|
||||
return teamInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String name() {
|
||||
return name;
|
||||
if (nullable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TeamManager teamManager() {
|
||||
return teamManager;
|
||||
}
|
||||
globalInfo().players.add(player);
|
||||
return globalInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TeamInfoImpl teamInfo(Player player) {
|
||||
return getTeamInfo(player, true, false);
|
||||
}
|
||||
@Override
|
||||
public @NotNull TeamInfoImpl teamInfo(Player player, @Nullable TeamInfo teamInfo) {
|
||||
checkDestroyed();
|
||||
checkPlayer(player);
|
||||
|
||||
public TeamInfoImpl getTeamInfo(Player player, boolean check, boolean nullable) {
|
||||
checkDestroyed();
|
||||
if (check) {
|
||||
checkPlayer(player);
|
||||
}
|
||||
|
||||
for (TeamInfoImpl teamInfo : infos) {
|
||||
if (teamInfo.players.contains(player)) {
|
||||
return teamInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (nullable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
globalInfo().players.add(player);
|
||||
return globalInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TeamInfoImpl teamInfo(Player player, @Nullable TeamInfo teamInfo) {
|
||||
checkDestroyed();
|
||||
checkPlayer(player);
|
||||
|
||||
TeamInfoImpl impl = teamInfo == null ? globalInfo() : (TeamInfoImpl) teamInfo;
|
||||
|
||||
TeamInfoImpl oldInfo = getTeamInfo(player, true, true);
|
||||
if (oldInfo != null) {
|
||||
if (oldInfo == impl)
|
||||
return impl;
|
||||
oldInfo.players.remove(player);
|
||||
}
|
||||
|
||||
if (impl.team() != this)
|
||||
impl.unassign();
|
||||
impl.assign(this);
|
||||
|
||||
Set<Player> singleton = Collections.singleton(player);
|
||||
impl.addPlayers(singleton);
|
||||
if (oldInfo != null) {
|
||||
impl.nms.updateTeam(singleton);
|
||||
TeamInfoImpl.syncEntries(singleton, oldInfo, impl);
|
||||
} else {
|
||||
impl.nms.createTeam(singleton);
|
||||
}
|
||||
TeamInfoImpl impl = teamInfo == null ? globalInfo() : (TeamInfoImpl) teamInfo;
|
||||
|
||||
TeamInfoImpl oldInfo = getTeamInfo(player, true, true);
|
||||
if (oldInfo != null) {
|
||||
if (oldInfo == impl)
|
||||
return impl;
|
||||
oldInfo.players.remove(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean closed() {
|
||||
return closed;
|
||||
if (impl.team() != this)
|
||||
impl.unassign();
|
||||
impl.assign(this);
|
||||
|
||||
Set<Player> singleton = Collections.singleton(player);
|
||||
impl.addPlayers(singleton);
|
||||
if (oldInfo != null) {
|
||||
impl.nms.updateTeam(singleton);
|
||||
TeamInfoImpl.syncEntries(singleton, oldInfo, impl);
|
||||
} else {
|
||||
impl.nms.createTeam(singleton);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (closed) {
|
||||
return;
|
||||
return impl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean closed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (infos != null) {
|
||||
infos.forEach(info -> {
|
||||
if (info != null && info.team() != null) {
|
||||
Objects.requireNonNull(info.team()).nms.removeTeam(info.players);
|
||||
}
|
||||
|
||||
if (infos != null) {
|
||||
infos.forEach(info -> {
|
||||
if (info != null && info.team() != null) {
|
||||
Objects.requireNonNull(info.team()).nms.removeTeam(info.players);
|
||||
}
|
||||
});
|
||||
}
|
||||
teamManager.teams.remove(name);
|
||||
closed = true;
|
||||
});
|
||||
}
|
||||
teamManager.teams.remove(name);
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ScoreboardTeamImpl that = (ScoreboardTeamImpl) o;
|
||||
return closed == that.closed &&
|
||||
idCounter == that.idCounter &&
|
||||
Objects.equals(teamManager, that.teamManager) &&
|
||||
Objects.equals(name, that.name) &&
|
||||
Objects.equals(nms, that.nms) &&
|
||||
Objects.equals(globalInfo, that.globalInfo) &&
|
||||
Objects.equals(infos, that.infos);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ScoreboardTeamImpl that = (ScoreboardTeamImpl) o;
|
||||
return closed == that.closed &&
|
||||
idCounter == that.idCounter &&
|
||||
Objects.equals(teamManager, that.teamManager) &&
|
||||
Objects.equals(name, that.name) &&
|
||||
Objects.equals(nms, that.nms) &&
|
||||
Objects.equals(globalInfo, that.globalInfo) &&
|
||||
Objects.equals(infos, that.infos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ScoreboardTeamImpl{" +
|
||||
"name='" + name + '\'' +
|
||||
", destroyed=" + closed +
|
||||
'}';
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ScoreboardTeamImpl{" +
|
||||
"name='" + name + '\'' +
|
||||
", destroyed=" + closed +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(teamManager, name);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(teamManager, name);
|
||||
}
|
||||
|
||||
protected void checkDestroyed() {
|
||||
Preconditions.checkState(!closed, "Team is closed");
|
||||
}
|
||||
protected void checkDestroyed() {
|
||||
Preconditions.checkState(!closed, "Team is closed");
|
||||
}
|
||||
|
||||
protected void checkPlayer(Player player) {
|
||||
Preconditions.checkNotNull(player, "Player cannot be null");
|
||||
Preconditions.checkArgument(teamManager.players().contains(player), "Player is not in fillTeamPacket teamManager");
|
||||
}
|
||||
protected void checkPlayer(Player player) {
|
||||
Preconditions.checkNotNull(player, "Player cannot be null");
|
||||
Preconditions.checkArgument(teamManager.players().contains(player), "Player is not in fillTeamPacket teamManager");
|
||||
}
|
||||
}
|
||||
+306
-306
@@ -22,324 +22,324 @@ import static net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializ
|
||||
|
||||
public class TeamInfoImpl implements TeamInfo, ImmutableTeamProperties<Component> {
|
||||
|
||||
public final Set<Player> players = Collections.synchronizedSet(CollectionProvider.set(4));
|
||||
public final Set<String> entries = Collections.synchronizedSet(CollectionProvider.set(4));
|
||||
private final AtomicBoolean updateTeam = new AtomicBoolean();
|
||||
public Component displayName = empty(),
|
||||
prefix = empty(),
|
||||
suffix = empty();
|
||||
public boolean allowFriendlyFire, canSeeFriendlyInvisibles;
|
||||
public byte nameTagVisibility = NameTagVisibility.ALWAYS.id(),
|
||||
collisionRule = CollisionRule.ALWAYS.id();
|
||||
public char playerColor = '\0';
|
||||
public TeamNMS.TeamInfoNMS<Component> nms;
|
||||
private ScoreboardTeamImpl team;
|
||||
private List<String> addEntries, removeEntries;
|
||||
private short id;
|
||||
private volatile boolean updateEntries;
|
||||
public final Set<Player> players = Collections.synchronizedSet(CollectionProvider.set(4));
|
||||
public final Set<String> entries = Collections.synchronizedSet(CollectionProvider.set(4));
|
||||
private final AtomicBoolean updateTeam = new AtomicBoolean();
|
||||
public Component displayName = empty(),
|
||||
prefix = empty(),
|
||||
suffix = empty();
|
||||
public boolean allowFriendlyFire, canSeeFriendlyInvisibles;
|
||||
public byte nameTagVisibility = NameTagVisibility.ALWAYS.id(),
|
||||
collisionRule = CollisionRule.ALWAYS.id();
|
||||
public char playerColor = '\0';
|
||||
public TeamNMS.TeamInfoNMS<Component> nms;
|
||||
private ScoreboardTeamImpl team;
|
||||
private List<String> addEntries, removeEntries;
|
||||
private short id;
|
||||
private volatile boolean updateEntries;
|
||||
|
||||
public TeamInfoImpl() {
|
||||
public TeamInfoImpl() {
|
||||
}
|
||||
|
||||
public static void syncEntries(Collection<Player> players, TeamInfoImpl old, TeamInfoImpl info) {
|
||||
if (old != null && !old.entries.isEmpty()) {
|
||||
List<String> entries = new ArrayList<>(old.entries);
|
||||
entries.removeAll(info.entries);
|
||||
if (!entries.isEmpty())
|
||||
info.nms.removeEntries(players, entries);
|
||||
|
||||
entries = new ArrayList<>(info.entries);
|
||||
entries.removeAll(old.entries);
|
||||
if (!entries.isEmpty())
|
||||
info.nms.addEntries(players, entries);
|
||||
} else if (!info.entries.isEmpty()) {
|
||||
info.nms.addEntries(players, info.entries);
|
||||
}
|
||||
}
|
||||
|
||||
public void assign(ScoreboardTeamImpl team) {
|
||||
if (this.team == team) return;
|
||||
|
||||
this.team = team;
|
||||
this.id = team.idCounter++;
|
||||
|
||||
team.teamInfos().add(this);
|
||||
nms = team.nms.createTeamInfoNMS(this, team.teamManager.componentTranslator());
|
||||
nms.updateTeamPackets(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoreboardTeamImpl team() {
|
||||
if (team == null) throw new IllegalStateException("Not assigned to a team");
|
||||
return team;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssigned() {
|
||||
return team != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void unassign() {
|
||||
if (!isAssigned()) return;
|
||||
|
||||
Preconditions.checkState(team.globalInfo() != this, "Cannot unnasign a global TeamInfo");
|
||||
team.teamInfos().remove(this);
|
||||
|
||||
TeamInfoImpl global = team.globalInfo();
|
||||
global.addPlayers(players);
|
||||
global.nms.updateTeam(players);
|
||||
|
||||
syncEntries(players, this, global);
|
||||
|
||||
players.clear();
|
||||
team = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<String> entries() {
|
||||
return Collections.unmodifiableSet(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addEntry(@NotNull String entry) {
|
||||
Preconditions.checkNotNull(entry);
|
||||
|
||||
synchronized (entries) {
|
||||
if (entries.add(entry)) {
|
||||
entries.add(entry);
|
||||
if (addEntries == null) addEntries = CollectionProvider.list(1);
|
||||
addEntries.add(entry);
|
||||
if (removeEntries != null) removeEntries.remove(entry);
|
||||
updateEntries();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeEntry(@NotNull String entry) {
|
||||
Preconditions.checkNotNull(entry);
|
||||
|
||||
synchronized (entries) {
|
||||
if (entries.remove(entry)) {
|
||||
entries.remove(entry);
|
||||
if (removeEntries == null) removeEntries = CollectionProvider.list(1);
|
||||
removeEntries.add(entry);
|
||||
if (addEntries != null) addEntries.remove(entry);
|
||||
updateEntries();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component displayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayName(@NotNull Component displayName) {
|
||||
Preconditions.checkNotNull(displayName);
|
||||
|
||||
if (!Objects.equals(displayName, this.displayName)) {
|
||||
this.displayName = displayName;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component prefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prefix(@NotNull Component prefix) {
|
||||
Preconditions.checkNotNull(prefix);
|
||||
|
||||
if ((!Objects.equals(prefix, this.prefix))) {
|
||||
this.prefix = prefix;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component suffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suffix(@NotNull Component suffix) {
|
||||
Preconditions.checkNotNull(suffix);
|
||||
|
||||
if (!Objects.equals(suffix, this.suffix)) {
|
||||
this.suffix = suffix;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean friendlyFire() {
|
||||
return allowFriendlyFire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void friendlyFire(boolean allowFriendlyFire) {
|
||||
if (this.allowFriendlyFire != allowFriendlyFire) {
|
||||
this.allowFriendlyFire = allowFriendlyFire;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void canSeeFriendlyInvisibles(boolean canSeeFriendlyInvisibles) {
|
||||
if (this.canSeeFriendlyInvisibles != canSeeFriendlyInvisibles) {
|
||||
this.canSeeFriendlyInvisibles = canSeeFriendlyInvisibles;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSeeFriendlyInvisibles() {
|
||||
return canSeeFriendlyInvisibles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull NameTagVisibility nameTagVisibility() {
|
||||
return NameTagVisibility.of(nameTagVisibility);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nameTagVisibility(@NotNull NameTagVisibility nameTagVisibility) {
|
||||
Preconditions.checkNotNull(nameTagVisibility);
|
||||
|
||||
if (this.nameTagVisibility != nameTagVisibility.id()) {
|
||||
this.nameTagVisibility = nameTagVisibility.id();
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CollisionRule collisionRule() {
|
||||
return CollisionRule.of(collisionRule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collisionRule(@NotNull CollisionRule collisionRule) {
|
||||
Preconditions.checkNotNull(collisionRule);
|
||||
|
||||
if (this.collisionRule != collisionRule.id()) {
|
||||
this.collisionRule = collisionRule.id();
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamedTextColor playerColor() {
|
||||
if (playerColor == '\0') return null;
|
||||
return (NamedTextColor) requireNonNull(parseChar(playerColor)).color();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerColor(NamedTextColor color) {
|
||||
if (color == null) {
|
||||
playerColor = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
public static void syncEntries(Collection<Player> players, TeamInfoImpl old, TeamInfoImpl info) {
|
||||
if (old != null && !old.entries.isEmpty()) {
|
||||
List<String> entries = new ArrayList<>(old.entries);
|
||||
entries.removeAll(info.entries);
|
||||
if (!entries.isEmpty())
|
||||
info.nms.removeEntries(players, entries);
|
||||
char c = LegacyFormatUtil.getChar(color);
|
||||
if (this.playerColor != c) {
|
||||
this.playerColor = c;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
entries = new ArrayList<>(info.entries);
|
||||
entries.removeAll(old.entries);
|
||||
if (!entries.isEmpty())
|
||||
info.nms.addEntries(players, entries);
|
||||
} else if (!info.entries.isEmpty()) {
|
||||
info.nms.addEntries(players, info.entries);
|
||||
}
|
||||
public void scheduleUpdate() {
|
||||
team.teamManager.update.set(true);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (updateTeam.getAndSet(false)) {
|
||||
nms.updateTeamPackets(entries);
|
||||
if (!players.isEmpty()) {
|
||||
nms.updateTeam(players);
|
||||
}
|
||||
}
|
||||
|
||||
public void assign(ScoreboardTeamImpl team) {
|
||||
if (this.team == team) return;
|
||||
|
||||
this.team = team;
|
||||
this.id = team.idCounter++;
|
||||
|
||||
team.teamInfos().add(this);
|
||||
nms = team.nms.createTeamInfoNMS(this, team.teamManager.componentTranslator());
|
||||
nms.updateTeamPackets(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoreboardTeamImpl team() {
|
||||
if (team == null) throw new IllegalStateException("Not assigned to a team");
|
||||
return team;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssigned() {
|
||||
return team != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void unassign() {
|
||||
if (!isAssigned()) return;
|
||||
|
||||
Preconditions.checkState(team.globalInfo() != this, "Cannot unnasign a global TeamInfo");
|
||||
team.teamInfos().remove(this);
|
||||
|
||||
TeamInfoImpl global = team.globalInfo();
|
||||
global.addPlayers(players);
|
||||
global.nms.updateTeam(players);
|
||||
|
||||
syncEntries(players, this, global);
|
||||
|
||||
players.clear();
|
||||
team = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<String> entries() {
|
||||
return Collections.unmodifiableSet(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addEntry(@NotNull String entry) {
|
||||
Preconditions.checkNotNull(entry);
|
||||
|
||||
synchronized (entries) {
|
||||
if (entries.add(entry)) {
|
||||
entries.add(entry);
|
||||
if (addEntries == null) addEntries = CollectionProvider.list(1);
|
||||
addEntries.add(entry);
|
||||
if (removeEntries != null) removeEntries.remove(entry);
|
||||
updateEntries();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeEntry(@NotNull String entry) {
|
||||
Preconditions.checkNotNull(entry);
|
||||
|
||||
synchronized (entries) {
|
||||
if (entries.remove(entry)) {
|
||||
entries.remove(entry);
|
||||
if (removeEntries == null) removeEntries = CollectionProvider.list(1);
|
||||
removeEntries.add(entry);
|
||||
if (addEntries != null) addEntries.remove(entry);
|
||||
updateEntries();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component displayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayName(@NotNull Component displayName) {
|
||||
Preconditions.checkNotNull(displayName);
|
||||
|
||||
if (!Objects.equals(displayName, this.displayName)) {
|
||||
this.displayName = displayName;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component prefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prefix(@NotNull Component prefix) {
|
||||
Preconditions.checkNotNull(prefix);
|
||||
|
||||
if ((!Objects.equals(prefix, this.prefix))) {
|
||||
this.prefix = prefix;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component suffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suffix(@NotNull Component suffix) {
|
||||
Preconditions.checkNotNull(suffix);
|
||||
|
||||
if (!Objects.equals(suffix, this.suffix)) {
|
||||
this.suffix = suffix;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean friendlyFire() {
|
||||
return allowFriendlyFire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void friendlyFire(boolean allowFriendlyFire) {
|
||||
if (this.allowFriendlyFire != allowFriendlyFire) {
|
||||
this.allowFriendlyFire = allowFriendlyFire;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void canSeeFriendlyInvisibles(boolean canSeeFriendlyInvisibles) {
|
||||
if (this.canSeeFriendlyInvisibles != canSeeFriendlyInvisibles) {
|
||||
this.canSeeFriendlyInvisibles = canSeeFriendlyInvisibles;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSeeFriendlyInvisibles() {
|
||||
return canSeeFriendlyInvisibles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull NameTagVisibility nameTagVisibility() {
|
||||
return NameTagVisibility.of(nameTagVisibility);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nameTagVisibility(@NotNull NameTagVisibility nameTagVisibility) {
|
||||
Preconditions.checkNotNull(nameTagVisibility);
|
||||
|
||||
if (this.nameTagVisibility != nameTagVisibility.id()) {
|
||||
this.nameTagVisibility = nameTagVisibility.id();
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CollisionRule collisionRule() {
|
||||
return CollisionRule.of(collisionRule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collisionRule(@NotNull CollisionRule collisionRule) {
|
||||
Preconditions.checkNotNull(collisionRule);
|
||||
|
||||
if (this.collisionRule != collisionRule.id()) {
|
||||
this.collisionRule = collisionRule.id();
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamedTextColor playerColor() {
|
||||
if (playerColor == '\0') return null;
|
||||
return (NamedTextColor) requireNonNull(parseChar(playerColor)).color();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerColor(NamedTextColor color) {
|
||||
if (color == null) {
|
||||
playerColor = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
char c = LegacyFormatUtil.getChar(color);
|
||||
if (this.playerColor != c) {
|
||||
this.playerColor = c;
|
||||
updateTeam.set(true);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void scheduleUpdate() {
|
||||
team.teamManager.update.set(true);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (updateTeam.getAndSet(false)) {
|
||||
nms.updateTeamPackets(entries);
|
||||
if (!players.isEmpty()) {
|
||||
nms.updateTeam(players);
|
||||
}
|
||||
}
|
||||
|
||||
if (updateEntries) {
|
||||
synchronized (entries) {
|
||||
if (!players.isEmpty()) {
|
||||
if (addEntries != null && !addEntries.isEmpty()) {
|
||||
nms.addEntries(players, addEntries);
|
||||
addEntries.clear();
|
||||
}
|
||||
if (removeEntries != null && !removeEntries.isEmpty()) {
|
||||
nms.removeEntries(players, removeEntries);
|
||||
removeEntries.clear();
|
||||
}
|
||||
}
|
||||
updateEntries = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlayers(Collection<Player> players) {
|
||||
this.players.addAll(players);
|
||||
}
|
||||
|
||||
private void updateEntries() {
|
||||
if (updateEntries) return;
|
||||
|
||||
if (updateEntries) {
|
||||
synchronized (entries) {
|
||||
if (!players.isEmpty()) {
|
||||
updateEntries = true;
|
||||
scheduleUpdate();
|
||||
} else {
|
||||
if (addEntries != null) addEntries.clear();
|
||||
if (removeEntries != null) removeEntries.clear();
|
||||
if (addEntries != null && !addEntries.isEmpty()) {
|
||||
nms.addEntries(players, addEntries);
|
||||
addEntries.clear();
|
||||
}
|
||||
if (removeEntries != null && !removeEntries.isEmpty()) {
|
||||
nms.removeEntries(players, removeEntries);
|
||||
removeEntries.clear();
|
||||
}
|
||||
}
|
||||
updateEntries = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(team, id);
|
||||
public void addPlayers(Collection<Player> players) {
|
||||
this.players.addAll(players);
|
||||
}
|
||||
|
||||
private void updateEntries() {
|
||||
if (updateEntries) return;
|
||||
|
||||
if (!players.isEmpty()) {
|
||||
updateEntries = true;
|
||||
scheduleUpdate();
|
||||
} else {
|
||||
if (addEntries != null) addEntries.clear();
|
||||
if (removeEntries != null) removeEntries.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(team, id);
|
||||
}
|
||||
|
||||
TeamInfoImpl teamInfo = (TeamInfoImpl) o;
|
||||
return allowFriendlyFire == teamInfo.allowFriendlyFire &&
|
||||
canSeeFriendlyInvisibles == teamInfo.canSeeFriendlyInvisibles &&
|
||||
Objects.equals(players, teamInfo.players) &&
|
||||
Objects.equals(entries, teamInfo.entries) &&
|
||||
Objects.equals(addEntries, teamInfo.addEntries) &&
|
||||
Objects.equals(removeEntries, teamInfo.removeEntries) &&
|
||||
Objects.equals(displayName, teamInfo.displayName) &&
|
||||
Objects.equals(prefix, teamInfo.prefix) &&
|
||||
Objects.equals(suffix, teamInfo.suffix) &&
|
||||
nameTagVisibility == teamInfo.nameTagVisibility &&
|
||||
Objects.equals(nms, teamInfo.nms) &&
|
||||
Objects.equals(team, teamInfo.team);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TeamInfo{" +
|
||||
"players=" + players +
|
||||
", entries=" + entries +
|
||||
", team=" + team +
|
||||
'}';
|
||||
}
|
||||
TeamInfoImpl teamInfo = (TeamInfoImpl) o;
|
||||
return allowFriendlyFire == teamInfo.allowFriendlyFire &&
|
||||
canSeeFriendlyInvisibles == teamInfo.canSeeFriendlyInvisibles &&
|
||||
Objects.equals(players, teamInfo.players) &&
|
||||
Objects.equals(entries, teamInfo.entries) &&
|
||||
Objects.equals(addEntries, teamInfo.addEntries) &&
|
||||
Objects.equals(removeEntries, teamInfo.removeEntries) &&
|
||||
Objects.equals(displayName, teamInfo.displayName) &&
|
||||
Objects.equals(prefix, teamInfo.prefix) &&
|
||||
Objects.equals(suffix, teamInfo.suffix) &&
|
||||
nameTagVisibility == teamInfo.nameTagVisibility &&
|
||||
Objects.equals(nms, teamInfo.nms) &&
|
||||
Objects.equals(team, teamInfo.team);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TeamInfo{" +
|
||||
"players=" + players +
|
||||
", entries=" + entries +
|
||||
", team=" + team +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+207
-207
@@ -21,227 +21,227 @@ import java.util.function.Function;
|
||||
|
||||
public class TeamManagerImpl implements TeamManager {
|
||||
|
||||
private static int idCounter = 0;
|
||||
public final Map<String, ScoreboardTeamImpl> teams = CollectionProvider.map(5);
|
||||
public final AtomicBoolean update = new AtomicBoolean();
|
||||
private final ScoreboardManagerImpl scoreboardManager;
|
||||
private final ComponentTranslator componentTranslator;
|
||||
private final Set<Player> players = CollectionProvider.set(4);
|
||||
private final int id = idCounter++;
|
||||
private boolean closed;
|
||||
private static int idCounter = 0;
|
||||
public final Map<String, ScoreboardTeamImpl> teams = CollectionProvider.map(5);
|
||||
public final AtomicBoolean update = new AtomicBoolean();
|
||||
private final ScoreboardManagerImpl scoreboardManager;
|
||||
private final ComponentTranslator componentTranslator;
|
||||
private final Set<Player> players = CollectionProvider.set(4);
|
||||
private final int id = idCounter++;
|
||||
private boolean closed;
|
||||
|
||||
public TeamManagerImpl(ScoreboardManagerImpl scoreboardManager, ComponentTranslator componentTranslator) {
|
||||
this.scoreboardManager = Objects.requireNonNull(scoreboardManager);
|
||||
this.componentTranslator = Objects.requireNonNull(componentTranslator);
|
||||
public TeamManagerImpl(ScoreboardManagerImpl scoreboardManager, ComponentTranslator componentTranslator) {
|
||||
this.scoreboardManager = Objects.requireNonNull(scoreboardManager);
|
||||
this.componentTranslator = Objects.requireNonNull(componentTranslator);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (!update.getAndSet(false)) return;
|
||||
|
||||
ImmutableList<ScoreboardTeamImpl> list;
|
||||
synchronized (teams) {
|
||||
list = ImmutableList.copyOf(teams.values());
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (!update.getAndSet(false)) return;
|
||||
for (ScoreboardTeamImpl team : list) {
|
||||
team.update();
|
||||
}
|
||||
}
|
||||
|
||||
ImmutableList<ScoreboardTeamImpl> list;
|
||||
synchronized (teams) {
|
||||
list = ImmutableList.copyOf(teams.values());
|
||||
@Override
|
||||
public @NotNull ScoreboardManager scoreboardManager() {
|
||||
return scoreboardManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Player> players() {
|
||||
return Collections.unmodifiableCollection(players);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ComponentTranslator componentTranslator() {
|
||||
return componentTranslator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<ScoreboardTeam> teams() {
|
||||
synchronized (teams) {
|
||||
return Collections.unmodifiableCollection(teams.values());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ScoreboardTeamImpl team(@NotNull String name) {
|
||||
checkDestroyed();
|
||||
checkTeamName(name);
|
||||
|
||||
synchronized (teams) {
|
||||
return teams.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean teamExists(String name) {
|
||||
return team(name) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ScoreboardTeam createIfAbsent(@NotNull String name, @Nullable BiFunction<Player, ScoreboardTeam, TeamInfo> teamInfoFunction) {
|
||||
checkDestroyed();
|
||||
ScoreboardTeamImpl team = team(name);
|
||||
if (team != null)
|
||||
return team;
|
||||
team = new ScoreboardTeamImpl(this, name);
|
||||
synchronized (teams) {
|
||||
teams.put(name, team);
|
||||
}
|
||||
|
||||
for (Player player : players) {
|
||||
team.teamInfo(player, teamInfoFunction == null ? null : teamInfoFunction.apply(player, team));
|
||||
}
|
||||
return team;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addPlayer(@NotNull Player player, @Nullable Function<ScoreboardTeam, TeamInfo> teamInfoFunction) {
|
||||
checkDestroyed();
|
||||
|
||||
checkPlayer(player);
|
||||
if (players.add(player)) {
|
||||
ScoreboardManagerProviderImpl.instance().teamManagerMap.put(player, this);
|
||||
for (ScoreboardTeamImpl team : teams.values()) {
|
||||
TeamInfoImpl info = teamInfoFunction == null ? team.globalInfo() : (TeamInfoImpl) teamInfoFunction.apply(team);
|
||||
info = info == null ? team.globalInfo() : info;
|
||||
|
||||
Collection<Player> singleton = Collections.singletonList(player);
|
||||
info.assign(team);
|
||||
info.addPlayers(singleton);
|
||||
info.nms.createTeam(singleton);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Player> addPlayers(@NotNull Collection<Player> players, @Nullable Function<ScoreboardTeam, TeamInfo> teamInfoFunction) {
|
||||
checkDestroyed();
|
||||
Preconditions.checkNotNull(players, "Players cannot be null");
|
||||
|
||||
List<Player> filteredPlayers = new ArrayList<>(players.size());
|
||||
for (Player player : players) {
|
||||
checkPlayer(player);
|
||||
if (this.players.add(player)) {
|
||||
filteredPlayers.add(player);
|
||||
ScoreboardManagerProviderImpl.instance().teamManagerMap.put(player, this);
|
||||
}
|
||||
}
|
||||
|
||||
if (!filteredPlayers.isEmpty()) {
|
||||
for (ScoreboardTeamImpl team : teams.values()) {
|
||||
TeamInfoImpl info = teamInfoFunction == null ? team.globalInfo() : (TeamInfoImpl) teamInfoFunction.apply(team);
|
||||
info = info == null ? team.globalInfo() : info;
|
||||
|
||||
info.assign(team);
|
||||
info.players.addAll(players);
|
||||
info.nms.createTeam(filteredPlayers);
|
||||
}
|
||||
}
|
||||
return filteredPlayers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removePlayer(@NotNull Player player) {
|
||||
checkDestroyed();
|
||||
checkPlayer(player);
|
||||
|
||||
if (players.remove(player)) {
|
||||
Collection<Player> singleton = Collections.singleton(player);
|
||||
for (ScoreboardTeamImpl team : teams.values()) {
|
||||
TeamInfoImpl info = team.getTeamInfo(player, false, true);
|
||||
if (info != null) {
|
||||
info.players.remove(player);
|
||||
team.nms.removeTeam(singleton);
|
||||
}
|
||||
}
|
||||
ScoreboardManagerProviderImpl.instance().teamManagerMap.remove(player);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ScoreboardTeamImpl team : list) {
|
||||
team.update();
|
||||
@Override
|
||||
public void removePlayers(@NotNull Collection<Player> players) {
|
||||
checkDestroyed();
|
||||
Preconditions.checkNotNull(players);
|
||||
|
||||
List<Player> filteredPlayers = CollectionProvider.list(players.size());
|
||||
for (Player player : players) {
|
||||
if (!this.players.remove(player)) continue;
|
||||
ScoreboardManagerProviderImpl.instance().teamManagerMap.remove(player);
|
||||
for (ScoreboardTeamImpl team : teams.values()) {
|
||||
TeamInfoImpl info = team.getTeamInfo(player, false, true);
|
||||
if (info != null) {
|
||||
info.players.remove(player);
|
||||
filteredPlayers.add(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ScoreboardManager scoreboardManager() {
|
||||
return scoreboardManager;
|
||||
for (ScoreboardTeamImpl team : teams.values()) {
|
||||
team.nms.removeTeam(filteredPlayers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Player> players() {
|
||||
return Collections.unmodifiableCollection(players);
|
||||
@Override
|
||||
public boolean closed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (!closed) {
|
||||
ImmutableList.copyOf(teams.values()).forEach(ScoreboardTeam::close);
|
||||
if (scoreboardManager.teamManagers != null) {
|
||||
scoreboardManager.teamManagers.remove(this);
|
||||
}
|
||||
|
||||
for (Player player : players) {
|
||||
ScoreboardManagerProviderImpl.instance().teamManagerMap.remove(player);
|
||||
}
|
||||
players.clear(); // Prevent a memory leak
|
||||
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ComponentTranslator componentTranslator() {
|
||||
return componentTranslator;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TeamManagerImpl{" +
|
||||
"teams=" + teams +
|
||||
", scoreboardManager=" + scoreboardManager +
|
||||
", players=" + players +
|
||||
", closed=" + closed +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<ScoreboardTeam> teams() {
|
||||
synchronized (teams) {
|
||||
return Collections.unmodifiableCollection(teams.values());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(scoreboardManager, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ScoreboardTeamImpl team(@NotNull String name) {
|
||||
checkDestroyed();
|
||||
checkTeamName(name);
|
||||
protected void checkDestroyed() {
|
||||
Preconditions.checkState(!closed, "Team manager is closed");
|
||||
}
|
||||
|
||||
synchronized (teams) {
|
||||
return teams.get(name);
|
||||
}
|
||||
}
|
||||
protected void checkTeamName(String name) {
|
||||
Preconditions.checkNotNull(name, "Team name cannot be null");
|
||||
Preconditions.checkArgument(!name.isEmpty(), "Team name cannot be empty");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean teamExists(String name) {
|
||||
return team(name) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ScoreboardTeam createIfAbsent(@NotNull String name, @Nullable BiFunction<Player, ScoreboardTeam, TeamInfo> teamInfoFunction) {
|
||||
checkDestroyed();
|
||||
ScoreboardTeamImpl team = team(name);
|
||||
if (team != null)
|
||||
return team;
|
||||
team = new ScoreboardTeamImpl(this, name);
|
||||
synchronized (teams) {
|
||||
teams.put(name, team);
|
||||
}
|
||||
|
||||
for (Player player : players) {
|
||||
team.teamInfo(player, teamInfoFunction == null ? null : teamInfoFunction.apply(player, team));
|
||||
}
|
||||
return team;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addPlayer(@NotNull Player player, @Nullable Function<ScoreboardTeam, TeamInfo> teamInfoFunction) {
|
||||
checkDestroyed();
|
||||
|
||||
checkPlayer(player);
|
||||
if (players.add(player)) {
|
||||
ScoreboardManagerProviderImpl.instance().teamManagerMap.put(player, this);
|
||||
for (ScoreboardTeamImpl team : teams.values()) {
|
||||
TeamInfoImpl info = teamInfoFunction == null ? team.globalInfo() : (TeamInfoImpl) teamInfoFunction.apply(team);
|
||||
info = info == null ? team.globalInfo() : info;
|
||||
|
||||
Collection<Player> singleton = Collections.singletonList(player);
|
||||
info.assign(team);
|
||||
info.addPlayers(singleton);
|
||||
info.nms.createTeam(singleton);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Player> addPlayers(@NotNull Collection<Player> players, @Nullable Function<ScoreboardTeam, TeamInfo> teamInfoFunction) {
|
||||
checkDestroyed();
|
||||
Preconditions.checkNotNull(players, "Players cannot be null");
|
||||
|
||||
List<Player> filteredPlayers = new ArrayList<>(players.size());
|
||||
for (Player player : players) {
|
||||
checkPlayer(player);
|
||||
if (this.players.add(player)) {
|
||||
filteredPlayers.add(player);
|
||||
ScoreboardManagerProviderImpl.instance().teamManagerMap.put(player, this);
|
||||
}
|
||||
}
|
||||
|
||||
if (!filteredPlayers.isEmpty()) {
|
||||
for (ScoreboardTeamImpl team : teams.values()) {
|
||||
TeamInfoImpl info = teamInfoFunction == null ? team.globalInfo() : (TeamInfoImpl) teamInfoFunction.apply(team);
|
||||
info = info == null ? team.globalInfo() : info;
|
||||
|
||||
info.assign(team);
|
||||
info.players.addAll(players);
|
||||
info.nms.createTeam(filteredPlayers);
|
||||
}
|
||||
}
|
||||
return filteredPlayers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removePlayer(@NotNull Player player) {
|
||||
checkDestroyed();
|
||||
checkPlayer(player);
|
||||
|
||||
if (players.remove(player)) {
|
||||
Collection<Player> singleton = Collections.singleton(player);
|
||||
for (ScoreboardTeamImpl team : teams.values()) {
|
||||
TeamInfoImpl info = team.getTeamInfo(player, false, true);
|
||||
if (info != null) {
|
||||
info.players.remove(player);
|
||||
team.nms.removeTeam(singleton);
|
||||
}
|
||||
}
|
||||
ScoreboardManagerProviderImpl.instance().teamManagerMap.remove(player);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePlayers(@NotNull Collection<Player> players) {
|
||||
checkDestroyed();
|
||||
Preconditions.checkNotNull(players);
|
||||
|
||||
List<Player> filteredPlayers = CollectionProvider.list(players.size());
|
||||
for (Player player : players) {
|
||||
if (!this.players.remove(player)) continue;
|
||||
ScoreboardManagerProviderImpl.instance().teamManagerMap.remove(player);
|
||||
for (ScoreboardTeamImpl team : teams.values()) {
|
||||
TeamInfoImpl info = team.getTeamInfo(player, false, true);
|
||||
if (info != null) {
|
||||
info.players.remove(player);
|
||||
filteredPlayers.add(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ScoreboardTeamImpl team : teams.values()) {
|
||||
team.nms.removeTeam(filteredPlayers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean closed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (!closed) {
|
||||
ImmutableList.copyOf(teams.values()).forEach(ScoreboardTeam::close);
|
||||
if (scoreboardManager.teamManagers != null) {
|
||||
scoreboardManager.teamManagers.remove(this);
|
||||
}
|
||||
|
||||
for (Player player : players) {
|
||||
ScoreboardManagerProviderImpl.instance().teamManagerMap.remove(player);
|
||||
}
|
||||
players.clear(); // Prevent a memory leak
|
||||
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TeamManagerImpl{" +
|
||||
"teams=" + teams +
|
||||
", scoreboardManager=" + scoreboardManager +
|
||||
", players=" + players +
|
||||
", closed=" + closed +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(scoreboardManager, id);
|
||||
}
|
||||
|
||||
protected void checkDestroyed() {
|
||||
Preconditions.checkState(!closed, "Team manager is closed");
|
||||
}
|
||||
|
||||
protected void checkTeamName(String name) {
|
||||
Preconditions.checkNotNull(name, "Team name cannot be null");
|
||||
Preconditions.checkArgument(!name.isEmpty(), "Team name cannot be empty");
|
||||
}
|
||||
|
||||
protected void checkPlayer(Player player) {
|
||||
Preconditions.checkNotNull(player, "Player cannot be null");
|
||||
TeamManagerImpl teamManager = ScoreboardManagerProviderImpl.instance().teamManager(player);
|
||||
if (teamManager != this && teamManager != null)
|
||||
throw new IllegalArgumentException("Player already has a TeamManager which is owned by " + teamManager.scoreboardManager().plugin().getName());
|
||||
}
|
||||
protected void checkPlayer(Player player) {
|
||||
Preconditions.checkNotNull(player, "Player cannot be null");
|
||||
TeamManagerImpl teamManager = ScoreboardManagerProviderImpl.instance().teamManager(player);
|
||||
if (teamManager != this && teamManager != null)
|
||||
throw new IllegalArgumentException("Player already has a TeamManager which is owned by " + teamManager.scoreboardManager().plugin().getName());
|
||||
}
|
||||
}
|
||||
+18
-18
@@ -10,25 +10,25 @@ import java.util.logging.Logger;
|
||||
|
||||
public class TeamUpdaterTask extends BukkitRunnable {
|
||||
|
||||
private final Logger logger;
|
||||
private final Set<TeamManagerImpl> teamManagers;
|
||||
private final Logger logger;
|
||||
private final Set<TeamManagerImpl> teamManagers;
|
||||
|
||||
public TeamUpdaterTask(ScoreboardManagerImpl manager) {
|
||||
Preconditions.checkNotNull(manager);
|
||||
this.logger = manager.plugin().getLogger();
|
||||
this.teamManagers = manager.teamManagers;
|
||||
public TeamUpdaterTask(ScoreboardManagerImpl manager) {
|
||||
Preconditions.checkNotNull(manager);
|
||||
this.logger = manager.plugin().getLogger();
|
||||
this.teamManagers = manager.teamManagers;
|
||||
|
||||
runTaskTimerAsynchronously(manager.plugin(), 1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (TeamManagerImpl teamManager : teamManagers) {
|
||||
try {
|
||||
teamManager.update();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Exception caught when updating TeamManager", e);
|
||||
}
|
||||
}
|
||||
runTaskTimerAsynchronously(manager.plugin(), 1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (TeamManagerImpl teamManager : teamManagers) {
|
||||
try {
|
||||
teamManager.update();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Exception caught when updating TeamManager", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
}
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "scoreboard-library"
|
||||
@@ -18,4 +18,4 @@ include(":v1_18_R2")
|
||||
project(":v1_18_R2").projectDir = file("versions/v1_18_R2")
|
||||
|
||||
include(":v1_8_R3")
|
||||
project(":v1_8_R3").projectDir = file("versions/v1_8_R3")
|
||||
project(":v1_8_R3").projectDir = file("versions/v1_8_R3")
|
||||
@@ -1,26 +1,26 @@
|
||||
plugins {
|
||||
id("net.megavex.scoreboardlibrary.java-conventions")
|
||||
id("net.minecrell.plugin-yml.bukkit") version "0.5.0"
|
||||
id("com.github.johnrengelman.shadow") version "7.1.0"
|
||||
id("net.megavex.scoreboardlibrary.java-conventions")
|
||||
id("net.minecrell.plugin-yml.bukkit") version "0.5.0"
|
||||
id("com.github.johnrengelman.shadow") version "7.1.0"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":implementation"))
|
||||
api(project(":implementation"))
|
||||
|
||||
implementation(project(":v1_8_R3"))
|
||||
implementation(project(":v1_18_R2"))
|
||||
implementation(project(":v1_8_R3"))
|
||||
implementation(project(":v1_18_R2"))
|
||||
}
|
||||
|
||||
bukkit {
|
||||
name = "ScoreboardLibrary"
|
||||
main = "net.megavex.scoreboardlibrary.plugin.ScoreboardLibraryPlugin"
|
||||
apiVersion = "1.18"
|
||||
description = "https://github.com/MegavexNetwork/scoreboard-library"
|
||||
author = "VytskaLT"
|
||||
name = "ScoreboardLibrary"
|
||||
main = "net.megavex.scoreboardlibrary.plugin.ScoreboardLibraryPlugin"
|
||||
apiVersion = "1.18"
|
||||
description = "https://github.com/MegavexNetwork/scoreboard-library"
|
||||
author = "VytskaLT"
|
||||
}
|
||||
|
||||
tasks {
|
||||
build {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
build {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
}
|
||||
+12
-12
@@ -8,18 +8,18 @@ import java.util.logging.Level;
|
||||
|
||||
public class ScoreboardLibraryPlugin extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
try {
|
||||
ScoreboardLibraryImplementation.init();
|
||||
} catch (ScoreboardLibraryLoadException e) {
|
||||
getLogger().log(Level.SEVERE, "Couldn't load ScoreboardLibrary", e);
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
}
|
||||
@Override
|
||||
public void onEnable() {
|
||||
try {
|
||||
ScoreboardLibraryImplementation.init();
|
||||
} catch (ScoreboardLibraryLoadException e) {
|
||||
getLogger().log(Level.SEVERE, "Couldn't load ScoreboardLibrary", e);
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
ScoreboardLibraryImplementation.close();
|
||||
}
|
||||
@Override
|
||||
public void onDisable() {
|
||||
ScoreboardLibraryImplementation.close();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
plugins {
|
||||
id("net.megavex.scoreboardlibrary.publish-conventions")
|
||||
id("net.megavex.scoreboardlibrary.publish-conventions")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":api"))
|
||||
api(project(":api"))
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
options.compilerArgs.add("-XDignore.symbol.file")
|
||||
}
|
||||
options.compilerArgs.add("-XDignore.symbol.file")
|
||||
}
|
||||
+39
-39
@@ -10,47 +10,47 @@ import java.util.Collections;
|
||||
|
||||
public interface ImmutableTeamProperties<T> {
|
||||
|
||||
default Collection<String> entries() {
|
||||
return Collections.emptySet();
|
||||
default Collection<String> entries() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
T displayName();
|
||||
|
||||
T prefix();
|
||||
|
||||
T suffix();
|
||||
|
||||
default boolean friendlyFire() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean canSeeFriendlyInvisibles() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default NameTagVisibility nameTagVisibility() {
|
||||
return NameTagVisibility.ALWAYS;
|
||||
}
|
||||
|
||||
default CollisionRule collisionRule() {
|
||||
return CollisionRule.ALWAYS;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default NamedTextColor playerColor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default int packOptions() {
|
||||
int options = 0;
|
||||
if (this.friendlyFire()) {
|
||||
options |= 1;
|
||||
}
|
||||
|
||||
T displayName();
|
||||
|
||||
T prefix();
|
||||
|
||||
T suffix();
|
||||
|
||||
default boolean friendlyFire() {
|
||||
return false;
|
||||
if (this.canSeeFriendlyInvisibles()) {
|
||||
options |= 2;
|
||||
}
|
||||
|
||||
default boolean canSeeFriendlyInvisibles() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default NameTagVisibility nameTagVisibility() {
|
||||
return NameTagVisibility.ALWAYS;
|
||||
}
|
||||
|
||||
default CollisionRule collisionRule() {
|
||||
return CollisionRule.ALWAYS;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default NamedTextColor playerColor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default int packOptions() {
|
||||
int options = 0;
|
||||
if (this.friendlyFire()) {
|
||||
options |= 1;
|
||||
}
|
||||
|
||||
if (this.canSeeFriendlyInvisibles()) {
|
||||
options |= 2;
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
}
|
||||
+44
-44
@@ -14,64 +14,64 @@ import java.util.function.Function;
|
||||
|
||||
public abstract class ScoreboardManagerNMS<P> {
|
||||
|
||||
public static ScoreboardManagerNMS<?> INSTANCE;
|
||||
public final String objectiveName = "_s" + RandomStringUtils.randomAlphanumeric(5);
|
||||
public static ScoreboardManagerNMS<?> INSTANCE;
|
||||
public final String objectiveName = "_s" + RandomStringUtils.randomAlphanumeric(5);
|
||||
|
||||
public ScoreboardManagerNMS() {
|
||||
Preconditions.checkState(INSTANCE == null);
|
||||
INSTANCE = this;
|
||||
}
|
||||
public ScoreboardManagerNMS() {
|
||||
Preconditions.checkState(INSTANCE == null);
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
public static <P> void sendLocalePackets(
|
||||
Locale specificLocale,
|
||||
ScoreboardManagerNMS<P> nms,
|
||||
Collection<Player> players,
|
||||
Function<Locale, P> packetFunction
|
||||
) {
|
||||
if (players.isEmpty()) return;
|
||||
public static <P> void sendLocalePackets(
|
||||
Locale specificLocale,
|
||||
ScoreboardManagerNMS<P> nms,
|
||||
Collection<Player> players,
|
||||
Function<Locale, P> packetFunction
|
||||
) {
|
||||
if (players.isEmpty()) return;
|
||||
|
||||
if (specificLocale != null) {
|
||||
P packet = packetFunction.apply(specificLocale);
|
||||
nms.sendPacket(players, packet);
|
||||
} else if (players.size() == 1) {
|
||||
Player player = players.iterator().next();
|
||||
P packet = packetFunction.apply(LocaleUtilities.getLocaleOfPlayer(player));
|
||||
nms.sendPacket(player, packet);
|
||||
} else {
|
||||
Map<Locale, P> map = CollectionProvider.map(1);
|
||||
for (Player player : players) {
|
||||
Locale locale = LocaleUtilities.getLocaleOfPlayer(player);
|
||||
P packet = map.get(locale);
|
||||
if (packet == null) {
|
||||
map.put(locale, packetFunction.apply(locale));
|
||||
}
|
||||
|
||||
nms.sendPacket(player, packet);
|
||||
}
|
||||
if (specificLocale != null) {
|
||||
P packet = packetFunction.apply(specificLocale);
|
||||
nms.sendPacket(players, packet);
|
||||
} else if (players.size() == 1) {
|
||||
Player player = players.iterator().next();
|
||||
P packet = packetFunction.apply(LocaleUtilities.getLocaleOfPlayer(player));
|
||||
nms.sendPacket(player, packet);
|
||||
} else {
|
||||
Map<Locale, P> map = CollectionProvider.map(1);
|
||||
for (Player player : players) {
|
||||
Locale locale = LocaleUtilities.getLocaleOfPlayer(player);
|
||||
P packet = map.get(locale);
|
||||
if (packet == null) {
|
||||
map.put(locale, packetFunction.apply(locale));
|
||||
}
|
||||
|
||||
nms.sendPacket(player, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sidebar
|
||||
// Sidebar
|
||||
|
||||
public abstract SidebarNMS<P, ?> createSidebarNMS(Sidebar sidebar);
|
||||
public abstract SidebarNMS<P, ?> createSidebarNMS(Sidebar sidebar);
|
||||
|
||||
public abstract void displaySidebar(Iterable<Player> players);
|
||||
public abstract void displaySidebar(Iterable<Player> players);
|
||||
|
||||
public abstract void removeSidebar(Iterable<Player> players);
|
||||
public abstract void removeSidebar(Iterable<Player> players);
|
||||
|
||||
// Team
|
||||
// Team
|
||||
|
||||
public abstract TeamNMS<?, ?> createTeamNMS(String teamName);
|
||||
public abstract TeamNMS<?, ?> createTeamNMS(String teamName);
|
||||
|
||||
public abstract boolean isLegacy(Player player);
|
||||
public abstract boolean isLegacy(Player player);
|
||||
|
||||
// Packet
|
||||
// Packet
|
||||
|
||||
public abstract void sendPacket(Player players, P packet);
|
||||
public abstract void sendPacket(Player players, P packet);
|
||||
|
||||
public final void sendPacket(Iterable<Player> players, P packet) {
|
||||
for (Player player : players) {
|
||||
sendPacket(player, packet);
|
||||
}
|
||||
public final void sendPacket(Iterable<Player> players, P packet) {
|
||||
for (Player player : players) {
|
||||
sendPacket(player, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-16
@@ -8,27 +8,27 @@ import java.util.Collection;
|
||||
|
||||
public abstract class SidebarNMS<P, T extends ScoreboardManagerNMS<P>> {
|
||||
|
||||
protected final T impl;
|
||||
protected final Sidebar sidebar;
|
||||
protected final T impl;
|
||||
protected final Sidebar sidebar;
|
||||
|
||||
public SidebarNMS(T impl, Sidebar sidebar) {
|
||||
this.impl = impl;
|
||||
this.sidebar = sidebar;
|
||||
}
|
||||
public SidebarNMS(T impl, Sidebar sidebar) {
|
||||
this.impl = impl;
|
||||
this.sidebar = sidebar;
|
||||
}
|
||||
|
||||
public abstract void updateTitle(Component displayName);
|
||||
public abstract void updateTitle(Component displayName);
|
||||
|
||||
public void create(Collection<Player> players) {
|
||||
sendObjectivePacket(players, true);
|
||||
}
|
||||
public void create(Collection<Player> players) {
|
||||
sendObjectivePacket(players, true);
|
||||
}
|
||||
|
||||
public void update(Collection<Player> players) {
|
||||
sendObjectivePacket(players, false);
|
||||
}
|
||||
public void update(Collection<Player> players) {
|
||||
sendObjectivePacket(players, false);
|
||||
}
|
||||
|
||||
protected abstract void sendObjectivePacket(Collection<Player> players, boolean create);
|
||||
protected abstract void sendObjectivePacket(Collection<Player> players, boolean create);
|
||||
|
||||
public abstract void removeLine(Collection<Player> players, String line);
|
||||
public abstract void removeLine(Collection<Player> players, String line);
|
||||
|
||||
public abstract void score(Collection<Player> players, int score, String line);
|
||||
public abstract void score(Collection<Player> players, int score, String line);
|
||||
}
|
||||
+33
-33
@@ -8,47 +8,47 @@ import java.util.Collection;
|
||||
|
||||
public abstract class TeamNMS<P, T extends ScoreboardManagerNMS<P>> {
|
||||
|
||||
public static final byte LEGACY_CHARACTER_LIMIT = 16;
|
||||
public static final byte LEGACY_CHARACTER_LIMIT = 16;
|
||||
|
||||
public static final byte MODE_CREATE = 0,
|
||||
MODE_REMOVE = 1,
|
||||
MODE_UPDATE = 2,
|
||||
MODE_ADD_ENTRIES = 3,
|
||||
MODE_REMOVE_ENTRIES = 4;
|
||||
public static final byte MODE_CREATE = 0,
|
||||
MODE_REMOVE = 1,
|
||||
MODE_UPDATE = 2,
|
||||
MODE_ADD_ENTRIES = 3,
|
||||
MODE_REMOVE_ENTRIES = 4;
|
||||
|
||||
protected final T impl;
|
||||
protected final String teamName;
|
||||
protected final T impl;
|
||||
protected final String teamName;
|
||||
|
||||
public TeamNMS(T impl, String teamName) {
|
||||
this.impl = impl;
|
||||
this.teamName = teamName;
|
||||
public TeamNMS(T impl, String teamName) {
|
||||
this.impl = impl;
|
||||
this.teamName = teamName;
|
||||
}
|
||||
|
||||
public abstract void removeTeam(Iterable<Player> players);
|
||||
|
||||
public abstract TeamInfoNMS<Component> createTeamInfoNMS(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator);
|
||||
|
||||
public TeamInfoNMS<String> createLegacyTeamInfoNMS(ImmutableTeamProperties<String> properties) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public abstract static class TeamInfoNMS<C> {
|
||||
|
||||
protected final ImmutableTeamProperties<C> properties;
|
||||
|
||||
protected TeamInfoNMS(ImmutableTeamProperties<C> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public abstract void removeTeam(Iterable<Player> players);
|
||||
|
||||
public abstract TeamInfoNMS<Component> createTeamInfoNMS(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator);
|
||||
|
||||
public TeamInfoNMS<String> createLegacyTeamInfoNMS(ImmutableTeamProperties<String> properties) {
|
||||
throw new UnsupportedOperationException();
|
||||
public void updateTeamPackets(Collection<String> entries) {
|
||||
}
|
||||
|
||||
public abstract static class TeamInfoNMS<C> {
|
||||
public abstract void addEntries(Collection<Player> players, Collection<String> entries);
|
||||
|
||||
protected final ImmutableTeamProperties<C> properties;
|
||||
public abstract void removeEntries(Collection<Player> players, Collection<String> entries);
|
||||
|
||||
protected TeamInfoNMS(ImmutableTeamProperties<C> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
public abstract void createTeam(Collection<Player> players);
|
||||
|
||||
public void updateTeamPackets(Collection<String> entries) {
|
||||
}
|
||||
|
||||
public abstract void addEntries(Collection<Player> players, Collection<String> entries);
|
||||
|
||||
public abstract void removeEntries(Collection<Player> players, Collection<String> entries);
|
||||
|
||||
public abstract void createTeam(Collection<Player> players);
|
||||
|
||||
public abstract void updateTeam(Collection<Player> players);
|
||||
}
|
||||
public abstract void updateTeam(Collection<Player> players);
|
||||
}
|
||||
}
|
||||
+46
-46
@@ -9,60 +9,60 @@ import java.util.*;
|
||||
|
||||
public final class CollectionProvider {
|
||||
|
||||
private static final String FASTUTIL = "it.unimi.dsi.fastutil.objects.";
|
||||
private static final MethodHandle mapConstructor, setConstructor, listConstructor;
|
||||
private static final String FASTUTIL = "it.unimi.dsi.fastutil.objects.";
|
||||
private static final MethodHandle mapConstructor, setConstructor, listConstructor;
|
||||
|
||||
static {
|
||||
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
|
||||
MethodType parameters = MethodType.methodType(void.class, int.class);
|
||||
mapConstructor = getConstructor(lookup, FASTUTIL + "Object2ObjectOpenHashMap", HashMap.class, parameters);
|
||||
setConstructor = getConstructor(lookup, FASTUTIL + "ObjectOpenHashSet", HashSet.class, parameters);
|
||||
listConstructor = getConstructor(lookup, FASTUTIL + "ObjectArrayList", ArrayList.class, parameters);
|
||||
static {
|
||||
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
|
||||
MethodType parameters = MethodType.methodType(void.class, int.class);
|
||||
mapConstructor = getConstructor(lookup, FASTUTIL + "Object2ObjectOpenHashMap", HashMap.class, parameters);
|
||||
setConstructor = getConstructor(lookup, FASTUTIL + "ObjectOpenHashSet", HashSet.class, parameters);
|
||||
listConstructor = getConstructor(lookup, FASTUTIL + "ObjectArrayList", ArrayList.class, parameters);
|
||||
}
|
||||
|
||||
private CollectionProvider() {
|
||||
}
|
||||
|
||||
private static MethodHandle getConstructor(MethodHandles.Lookup lookup, String fastUtilClass, Class<?> fallback, MethodType parameters) {
|
||||
Class<?> clazz;
|
||||
try {
|
||||
clazz = Class.forName(fastUtilClass);
|
||||
ScoreboardLibraryLogger.logMessage("Using fastutil class " + clazz.getSimpleName());
|
||||
} catch (ClassNotFoundException e) {
|
||||
clazz = fallback;
|
||||
}
|
||||
|
||||
private CollectionProvider() {
|
||||
try {
|
||||
return lookup.findConstructor(clazz, parameters);
|
||||
} catch (NoSuchMethodException | IllegalAccessException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static MethodHandle getConstructor(MethodHandles.Lookup lookup, String fastUtilClass, Class<?> fallback, MethodType parameters) {
|
||||
Class<?> clazz;
|
||||
try {
|
||||
clazz = Class.forName(fastUtilClass);
|
||||
ScoreboardLibraryLogger.logMessage("Using fastutil class " + clazz.getSimpleName());
|
||||
} catch (ClassNotFoundException e) {
|
||||
clazz = fallback;
|
||||
}
|
||||
|
||||
try {
|
||||
return lookup.findConstructor(clazz, parameters);
|
||||
} catch (NoSuchMethodException | IllegalAccessException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
public static <K, V> Map<K, V> map(int capacity) {
|
||||
try {
|
||||
// noinspection unchecked
|
||||
return (Map<K, V>) mapConstructor.invokeWithArguments(capacity);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <K, V> Map<K, V> map(int capacity) {
|
||||
try {
|
||||
// noinspection unchecked
|
||||
return (Map<K, V>) mapConstructor.invokeWithArguments(capacity);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
public static <E> Set<E> set(int capacity) {
|
||||
try {
|
||||
// noinspection unchecked
|
||||
return (Set<E>) setConstructor.invokeWithArguments(capacity);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <E> Set<E> set(int capacity) {
|
||||
try {
|
||||
// noinspection unchecked
|
||||
return (Set<E>) setConstructor.invokeWithArguments(capacity);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <E> List<E> list(int capacity) {
|
||||
try {
|
||||
// noinspection unchecked
|
||||
return (List<E>) listConstructor.invokeWithArguments(capacity);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
public static <E> List<E> list(int capacity) {
|
||||
try {
|
||||
// noinspection unchecked
|
||||
return (List<E>) listConstructor.invokeWithArguments(capacity);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+31
-31
@@ -18,44 +18,44 @@ import static net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializ
|
||||
|
||||
public final class LegacyFormatUtil {
|
||||
|
||||
private static final Map<NamedTextColor, Character> legacyMap;
|
||||
private static final Map<NamedTextColor, Character> legacyMap;
|
||||
|
||||
static {
|
||||
ChatColor[] values = ChatColor.values();
|
||||
legacyMap = CollectionProvider.map(values.length);
|
||||
for (ChatColor value : values) {
|
||||
if (!value.isColor()) continue;
|
||||
static {
|
||||
ChatColor[] values = ChatColor.values();
|
||||
legacyMap = CollectionProvider.map(values.length);
|
||||
for (ChatColor value : values) {
|
||||
if (!value.isColor()) continue;
|
||||
|
||||
char c = value.getChar();
|
||||
LegacyFormat format = Objects.requireNonNull(parseChar(c));
|
||||
legacyMap.put((NamedTextColor) format.color(), c);
|
||||
}
|
||||
char c = value.getChar();
|
||||
LegacyFormat format = Objects.requireNonNull(parseChar(c));
|
||||
legacyMap.put((NamedTextColor) format.color(), c);
|
||||
}
|
||||
}
|
||||
|
||||
private LegacyFormatUtil() {
|
||||
}
|
||||
|
||||
public static String limitLegacyText(String text, int limit) {
|
||||
if (text.length() <= limit) {
|
||||
return text;
|
||||
}
|
||||
|
||||
private LegacyFormatUtil() {
|
||||
int lastNotColorCharIndex = limit - 1;
|
||||
while (text.charAt(lastNotColorCharIndex) == ChatColor.COLOR_CHAR) {
|
||||
lastNotColorCharIndex--;
|
||||
}
|
||||
return text.substring(0, lastNotColorCharIndex + 1);
|
||||
}
|
||||
|
||||
public static String limitLegacyText(String text, int limit) {
|
||||
if (text.length() <= limit) {
|
||||
return text;
|
||||
}
|
||||
public static String serialize(@NotNull ComponentTranslator componentTranslator, @Nullable Component component, Locale locale) {
|
||||
if (component == null || component == empty()) return "";
|
||||
|
||||
int lastNotColorCharIndex = limit - 1;
|
||||
while (text.charAt(lastNotColorCharIndex) == ChatColor.COLOR_CHAR) {
|
||||
lastNotColorCharIndex--;
|
||||
}
|
||||
return text.substring(0, lastNotColorCharIndex + 1);
|
||||
}
|
||||
return legacySection().serialize(componentTranslator.translate(component, locale));
|
||||
}
|
||||
|
||||
public static String serialize(@NotNull ComponentTranslator componentTranslator, @Nullable Component component, Locale locale) {
|
||||
if (component == null || component == empty()) return "";
|
||||
public static char getChar(NamedTextColor color) {
|
||||
if (color == null) return 'r';
|
||||
|
||||
return legacySection().serialize(componentTranslator.translate(component, locale));
|
||||
}
|
||||
|
||||
public static char getChar(NamedTextColor color) {
|
||||
if (color == null) return 'r';
|
||||
|
||||
return legacyMap.getOrDefault(color, '\0');
|
||||
}
|
||||
return legacyMap.getOrDefault(color, '\0');
|
||||
}
|
||||
}
|
||||
+32
-32
@@ -11,43 +11,43 @@ import java.util.Locale;
|
||||
|
||||
public final class LocaleUtilities {
|
||||
|
||||
private static MethodHandle adventureMethod, legacySpigotMethod, legacyMethod;
|
||||
private static MethodHandle adventureMethod, legacySpigotMethod, legacyMethod;
|
||||
|
||||
static {
|
||||
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
|
||||
static {
|
||||
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
|
||||
try {
|
||||
adventureMethod = lookup.findVirtual(Player.class, "locale", MethodType.methodType(Locale.class));
|
||||
} catch (IllegalAccessException | NoSuchMethodException e) {
|
||||
MethodType methodType = MethodType.methodType(String.class);
|
||||
try {
|
||||
legacySpigotMethod = lookup.findVirtual(Player.Spigot.class, "getLocale", methodType);
|
||||
} catch (IllegalAccessException | NoSuchMethodException ex) {
|
||||
try {
|
||||
adventureMethod = lookup.findVirtual(Player.class, "locale", MethodType.methodType(Locale.class));
|
||||
} catch (IllegalAccessException | NoSuchMethodException e) {
|
||||
MethodType methodType = MethodType.methodType(String.class);
|
||||
try {
|
||||
legacySpigotMethod = lookup.findVirtual(Player.Spigot.class, "getLocale", methodType);
|
||||
} catch (IllegalAccessException | NoSuchMethodException ex) {
|
||||
try {
|
||||
legacyMethod = lookup.findVirtual(Player.class, "getLocale", methodType);
|
||||
} catch (IllegalAccessException | NoSuchMethodException exc) {
|
||||
ScoreboardLibraryLogger.logMessage("No way of getting a player's locale was found");
|
||||
}
|
||||
}
|
||||
legacyMethod = lookup.findVirtual(Player.class, "getLocale", methodType);
|
||||
} catch (IllegalAccessException | NoSuchMethodException exc) {
|
||||
ScoreboardLibraryLogger.logMessage("No way of getting a player's locale was found");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private LocaleUtilities() {
|
||||
}
|
||||
private LocaleUtilities() {
|
||||
}
|
||||
|
||||
public static Locale getLocaleOfPlayer(Player player) {
|
||||
try {
|
||||
if (adventureMethod != null) {
|
||||
return (Locale) adventureMethod.invokeExact(player);
|
||||
} else if (legacySpigotMethod != null) {
|
||||
return Translator.parseLocale((String) legacySpigotMethod.invokeExact(player.spigot()));
|
||||
} else if (legacyMethod != null) {
|
||||
return Translator.parseLocale((String) legacyMethod.invokeExact(player));
|
||||
} else {
|
||||
return Locale.US;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
return Locale.US;
|
||||
}
|
||||
public static Locale getLocaleOfPlayer(Player player) {
|
||||
try {
|
||||
if (adventureMethod != null) {
|
||||
return (Locale) adventureMethod.invokeExact(player);
|
||||
} else if (legacySpigotMethod != null) {
|
||||
return Translator.parseLocale((String) legacySpigotMethod.invokeExact(player.spigot()));
|
||||
} else if (legacyMethod != null) {
|
||||
return Translator.parseLocale((String) legacyMethod.invokeExact(player));
|
||||
} else {
|
||||
return Locale.US;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
return Locale.US;
|
||||
}
|
||||
}
|
||||
}
|
||||
+58
-58
@@ -10,68 +10,68 @@ import java.util.Objects;
|
||||
|
||||
public class UnsafeUtilities {
|
||||
|
||||
public static final Unsafe UNSAFE;
|
||||
private static final MethodType VOID_METHOD_TYPE = MethodType.methodType(void.class);
|
||||
public static final Unsafe UNSAFE;
|
||||
private static final MethodType VOID_METHOD_TYPE = MethodType.methodType(void.class);
|
||||
|
||||
static {
|
||||
static {
|
||||
try {
|
||||
Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
theUnsafeField.setAccessible(true);
|
||||
UNSAFE = Objects.requireNonNull((Unsafe) theUnsafeField.get(null));
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private UnsafeUtilities() {
|
||||
}
|
||||
|
||||
public static Field getField(Class<?> clazz, String name) {
|
||||
try {
|
||||
return clazz.getDeclaredField(name);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setField(Field field, Object packet, Object value) {
|
||||
if (field == null || packet == null || value == null) {
|
||||
throw new NullPointerException();
|
||||
} else if (field.getDeclaringClass() != packet.getClass()) {
|
||||
throw new RuntimeException("Field class does not match the packet class!");
|
||||
} else if (!field.getType().isInstance(value)) {
|
||||
throw new RuntimeException("Field type does not match value type!");
|
||||
}
|
||||
|
||||
UNSAFE.putObject(packet, UNSAFE.objectFieldOffset(field), value);
|
||||
}
|
||||
|
||||
public static <T> PacketConstructor<T> findPacketConstructor(Class<T> packetClass, MethodHandles.Lookup lookup) {
|
||||
try {
|
||||
MethodHandle constructor = lookup.findConstructor(packetClass, VOID_METHOD_TYPE);
|
||||
return () -> {
|
||||
try {
|
||||
Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
theUnsafeField.setAccessible(true);
|
||||
UNSAFE = Objects.requireNonNull((Unsafe) theUnsafeField.get(null));
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
// noinspection unchecked
|
||||
return (T) constructor.invoke();
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
} catch (NoSuchMethodException | IllegalAccessException ignored) {
|
||||
}
|
||||
|
||||
private UnsafeUtilities() {
|
||||
}
|
||||
return () -> {
|
||||
try {
|
||||
// noinspection unchecked
|
||||
return (T) UNSAFE.allocateInstance(packetClass);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Field getField(Class<?> clazz, String name) {
|
||||
try {
|
||||
return clazz.getDeclaredField(name);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setField(Field field, Object packet, Object value) {
|
||||
if (field == null || packet == null || value == null) {
|
||||
throw new NullPointerException();
|
||||
} else if (field.getDeclaringClass() != packet.getClass()) {
|
||||
throw new RuntimeException("Field class does not match the packet class!");
|
||||
} else if (!field.getType().isInstance(value)) {
|
||||
throw new RuntimeException("Field type does not match value type!");
|
||||
}
|
||||
|
||||
UNSAFE.putObject(packet, UNSAFE.objectFieldOffset(field), value);
|
||||
}
|
||||
|
||||
public static <T> PacketConstructor<T> findPacketConstructor(Class<T> packetClass, MethodHandles.Lookup lookup) {
|
||||
try {
|
||||
MethodHandle constructor = lookup.findConstructor(packetClass, VOID_METHOD_TYPE);
|
||||
return () -> {
|
||||
try {
|
||||
// noinspection unchecked
|
||||
return (T) constructor.invoke();
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
} catch (NoSuchMethodException | IllegalAccessException ignored) {
|
||||
}
|
||||
|
||||
return () -> {
|
||||
try {
|
||||
// noinspection unchecked
|
||||
return (T) UNSAFE.allocateInstance(packetClass);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PacketConstructor<T> {
|
||||
T invoke();
|
||||
}
|
||||
@FunctionalInterface
|
||||
public interface PacketConstructor<T> {
|
||||
T invoke();
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,27 @@
|
||||
plugins {
|
||||
id("net.megavex.scoreboardlibrary.nms-conventions")
|
||||
id("io.papermc.paperweight.userdev") version "1.3.5"
|
||||
`maven-publish`
|
||||
id("net.megavex.scoreboardlibrary.nms-conventions")
|
||||
id("io.papermc.paperweight.userdev") version "1.3.5"
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url = uri("https://jitpack.io") }
|
||||
maven { url = uri("https://jitpack.io") }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
paperDevBundle("1.18.2-R0.1-SNAPSHOT")
|
||||
paperDevBundle("1.18.2-R0.1-SNAPSHOT")
|
||||
|
||||
compileOnly("com.github.ProtocolSupport:ProtocolSupport:05b7689664")
|
||||
compileOnly("com.github.ProtocolSupport:ProtocolSupport:05b7689664")
|
||||
}
|
||||
|
||||
tasks {
|
||||
assemble {
|
||||
dependsOn(reobfJar)
|
||||
}
|
||||
assemble {
|
||||
dependsOn(reobfJar)
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications.create<MavenPublication>("maven") {
|
||||
artifact(tasks.reobfJar)
|
||||
}
|
||||
}
|
||||
publications.create<MavenPublication>("maven") {
|
||||
artifact(tasks.reobfJar)
|
||||
}
|
||||
}
|
||||
+55
-55
@@ -32,72 +32,72 @@ import static net.megavex.scoreboardlibrary.internal.nms.base.util.UnsafeUtiliti
|
||||
|
||||
public class NMSImpl extends ScoreboardManagerNMS<Packet<?>> {
|
||||
|
||||
private final ClientboundSetDisplayObjectivePacket displayPacket = new ClientboundSetDisplayObjectivePacket(1, null);
|
||||
private final ClientboundSetObjectivePacket removePacket = UnsafeUtilities.findPacketConstructor(ClientboundSetObjectivePacket.class, MethodHandles.lookup()).invoke();
|
||||
private boolean nativeAdventure, protocolSupport;
|
||||
private final ClientboundSetDisplayObjectivePacket displayPacket = new ClientboundSetDisplayObjectivePacket(1, null);
|
||||
private final ClientboundSetObjectivePacket removePacket = UnsafeUtilities.findPacketConstructor(ClientboundSetObjectivePacket.class, MethodHandles.lookup()).invoke();
|
||||
private boolean nativeAdventure, protocolSupport;
|
||||
|
||||
public NMSImpl() {
|
||||
setField(getField(ClientboundSetDisplayObjectivePacket.class, "b"), displayPacket, objectiveName);
|
||||
setField(getField(ClientboundSetObjectivePacket.class, "d"), removePacket, objectiveName);
|
||||
UnsafeUtilities.UNSAFE.putInt(removePacket, UnsafeUtilities.UNSAFE.objectFieldOffset(getField(ClientboundSetDisplayObjectivePacket.class, "a")), 1);
|
||||
public NMSImpl() {
|
||||
setField(getField(ClientboundSetDisplayObjectivePacket.class, "b"), displayPacket, objectiveName);
|
||||
setField(getField(ClientboundSetObjectivePacket.class, "d"), removePacket, objectiveName);
|
||||
UnsafeUtilities.UNSAFE.putInt(removePacket, UnsafeUtilities.UNSAFE.objectFieldOffset(getField(ClientboundSetDisplayObjectivePacket.class, "a")), 1);
|
||||
|
||||
try {
|
||||
Class.forName("io.papermc.paper.adventure.PaperAdventure");
|
||||
nativeAdventure = true;
|
||||
ScoreboardLibraryLogger.logMessage("Detected native Adventure");
|
||||
} catch (ClassNotFoundException ignored) { // Imagine still using Spigot
|
||||
ScoreboardLibraryLogger.logMessage("Not using native Adventure");
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null) {
|
||||
var description = ScoreboardManagerProvider.loaderPlugin().getDescription();
|
||||
if (description.getDepend().contains("ProtocolSupport")
|
||||
|| description.getSoftDepend().contains("ProtocolSupport")) {
|
||||
protocolSupport = true;
|
||||
ScoreboardLibraryLogger.logMessage("Detected ProtocolSupport");
|
||||
}
|
||||
}
|
||||
try {
|
||||
Class.forName("io.papermc.paper.adventure.PaperAdventure");
|
||||
nativeAdventure = true;
|
||||
ScoreboardLibraryLogger.logMessage("Detected native Adventure");
|
||||
} catch (ClassNotFoundException ignored) { // Imagine still using Spigot
|
||||
ScoreboardLibraryLogger.logMessage("Not using native Adventure");
|
||||
}
|
||||
|
||||
public boolean protocolSupport() {
|
||||
return protocolSupport;
|
||||
if (Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null) {
|
||||
var description = ScoreboardManagerProvider.loaderPlugin().getDescription();
|
||||
if (description.getDepend().contains("ProtocolSupport")
|
||||
|| description.getSoftDepend().contains("ProtocolSupport")) {
|
||||
protocolSupport = true;
|
||||
ScoreboardLibraryLogger.logMessage("Detected ProtocolSupport");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SidebarNMS<Packet<?>, ?> createSidebarNMS(Sidebar sidebar) {
|
||||
return nativeAdventure ? new PaperSidebarNMSImpl(this, sidebar) : new SidebarNMSImpl(this, sidebar);
|
||||
}
|
||||
public boolean protocolSupport() {
|
||||
return protocolSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displaySidebar(Iterable<Player> players) {
|
||||
sendPacket(players, displayPacket);
|
||||
}
|
||||
@Override
|
||||
public SidebarNMS<Packet<?>, ?> createSidebarNMS(Sidebar sidebar) {
|
||||
return nativeAdventure ? new PaperSidebarNMSImpl(this, sidebar) : new SidebarNMSImpl(this, sidebar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSidebar(Iterable<Player> players) {
|
||||
sendPacket(players, removePacket);
|
||||
}
|
||||
@Override
|
||||
public void displaySidebar(Iterable<Player> players) {
|
||||
sendPacket(players, displayPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamNMS<?, ?> createTeamNMS(String teamName) {
|
||||
return nativeAdventure ? new PaperTeamNMSImpl(this, teamName) : new TeamNMSImpl(this, teamName);
|
||||
}
|
||||
@Override
|
||||
public void removeSidebar(Iterable<Player> players) {
|
||||
sendPacket(players, removePacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLegacy(Player player) {
|
||||
if (!protocolSupport) return false;
|
||||
return ProtocolSupportUtil.isLegacy(player);
|
||||
}
|
||||
@Override
|
||||
public TeamNMS<?, ?> createTeamNMS(String teamName) {
|
||||
return nativeAdventure ? new PaperTeamNMSImpl(this, teamName) : new TeamNMSImpl(this, teamName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Player player, Packet<?> packet) {
|
||||
((CraftPlayer) player).getHandle().connection.send(packet);
|
||||
}
|
||||
@Override
|
||||
public boolean isLegacy(Player player) {
|
||||
if (!protocolSupport) return false;
|
||||
return ProtocolSupportUtil.isLegacy(player);
|
||||
}
|
||||
|
||||
public net.minecraft.network.chat.Component fromAdventure(Component component, Locale locale, ComponentTranslator componentTranslator) {
|
||||
if (nativeAdventure) return NativeAdventureUtil.fromAdventureComponent(component);
|
||||
@Override
|
||||
public void sendPacket(Player player, Packet<?> packet) {
|
||||
((CraftPlayer) player).getHandle().connection.send(packet);
|
||||
}
|
||||
|
||||
component = componentTranslator.translate(component, Objects.requireNonNull(locale));
|
||||
return net.minecraft.network.chat.Component.Serializer.fromJson(gson().serializeToTree(component));
|
||||
}
|
||||
public net.minecraft.network.chat.Component fromAdventure(Component component, Locale locale, ComponentTranslator componentTranslator) {
|
||||
if (nativeAdventure) return NativeAdventureUtil.fromAdventureComponent(component);
|
||||
|
||||
component = componentTranslator.translate(component, Objects.requireNonNull(locale));
|
||||
return net.minecraft.network.chat.Component.Serializer.fromJson(gson().serializeToTree(component));
|
||||
}
|
||||
}
|
||||
+23
-23
@@ -19,31 +19,31 @@ import static net.megavex.scoreboardlibrary.internal.nms.base.util.UnsafeUtiliti
|
||||
|
||||
public abstract class AbstractSidebarImpl extends SidebarNMS<Packet<?>, NMSImpl> {
|
||||
|
||||
static final UnsafeUtilities.PacketConstructor<ClientboundSetObjectivePacket> objectivePacketConstructor = UnsafeUtilities
|
||||
.findPacketConstructor(ClientboundSetObjectivePacket.class, MethodHandles.lookup());
|
||||
static final Field objectiveNameField = UnsafeUtilities.getField(ClientboundSetObjectivePacket.class, "d"),
|
||||
objectiveDisplayNameField = UnsafeUtilities.getField(ClientboundSetObjectivePacket.class, "e"),
|
||||
objectiveRenderTypeField = UnsafeUtilities.getField(ClientboundSetObjectivePacket.class, "f");
|
||||
private static final Field objectiveModeField = getField(ClientboundSetObjectivePacket.class, "g");
|
||||
static final UnsafeUtilities.PacketConstructor<ClientboundSetObjectivePacket> objectivePacketConstructor = UnsafeUtilities
|
||||
.findPacketConstructor(ClientboundSetObjectivePacket.class, MethodHandles.lookup());
|
||||
static final Field objectiveNameField = UnsafeUtilities.getField(ClientboundSetObjectivePacket.class, "d"),
|
||||
objectiveDisplayNameField = UnsafeUtilities.getField(ClientboundSetObjectivePacket.class, "e"),
|
||||
objectiveRenderTypeField = UnsafeUtilities.getField(ClientboundSetObjectivePacket.class, "f");
|
||||
private static final Field objectiveModeField = getField(ClientboundSetObjectivePacket.class, "g");
|
||||
|
||||
public AbstractSidebarImpl(NMSImpl impl, Sidebar sidebar) {
|
||||
super(impl, sidebar);
|
||||
}
|
||||
public AbstractSidebarImpl(NMSImpl impl, Sidebar sidebar) {
|
||||
super(impl, sidebar);
|
||||
}
|
||||
|
||||
protected void createObjectivePacket(ClientboundSetObjectivePacket packet, int mode) {
|
||||
UnsafeUtilities.setField(objectiveNameField, packet, impl.objectiveName);
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(objectiveModeField), mode);
|
||||
UnsafeUtilities.setField(objectiveRenderTypeField, packet, ObjectiveCriteria.RenderType.INTEGER);
|
||||
}
|
||||
protected void createObjectivePacket(ClientboundSetObjectivePacket packet, int mode) {
|
||||
UnsafeUtilities.setField(objectiveNameField, packet, impl.objectiveName);
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(objectiveModeField), mode);
|
||||
UnsafeUtilities.setField(objectiveRenderTypeField, packet, ObjectiveCriteria.RenderType.INTEGER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLine(Collection<Player> players, String line) {
|
||||
impl.sendPacket(players, new ClientboundSetScorePacket(ServerScoreboard.Method.REMOVE, impl.objectiveName, line, 0));
|
||||
}
|
||||
@Override
|
||||
public void removeLine(Collection<Player> players, String line) {
|
||||
impl.sendPacket(players, new ClientboundSetScorePacket(ServerScoreboard.Method.REMOVE, impl.objectiveName, line, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void score(Collection<Player> players, int score, String line) {
|
||||
ClientboundSetScorePacket packet = new ClientboundSetScorePacket(ServerScoreboard.Method.CHANGE, impl.objectiveName, line, score);
|
||||
impl.sendPacket(players, packet);
|
||||
}
|
||||
@Override
|
||||
public void score(Collection<Player> players, int score, String line) {
|
||||
ClientboundSetScorePacket packet = new ClientboundSetScorePacket(ServerScoreboard.Method.CHANGE, impl.objectiveName, line, score);
|
||||
impl.sendPacket(players, packet);
|
||||
}
|
||||
}
|
||||
+30
-30
@@ -15,43 +15,43 @@ import java.util.Collection;
|
||||
*/
|
||||
public class PaperSidebarNMSImpl extends AbstractSidebarImpl {
|
||||
|
||||
private ClientboundSetObjectivePacket createPacket;
|
||||
private ClientboundSetObjectivePacket updatePacket;
|
||||
private ClientboundSetObjectivePacket createPacket;
|
||||
private ClientboundSetObjectivePacket updatePacket;
|
||||
|
||||
public PaperSidebarNMSImpl(NMSImpl impl, Sidebar sidebar) {
|
||||
super(impl, sidebar);
|
||||
}
|
||||
public PaperSidebarNMSImpl(NMSImpl impl, Sidebar sidebar) {
|
||||
super(impl, sidebar);
|
||||
}
|
||||
|
||||
private void initialisePackets() {
|
||||
private void initialisePackets() {
|
||||
if (createPacket == null || updatePacket == null) {
|
||||
synchronized (this) {
|
||||
if (createPacket == null || updatePacket == null) {
|
||||
synchronized (this) {
|
||||
if (createPacket == null || updatePacket == null) {
|
||||
createPacket = objectivePacketConstructor.invoke();
|
||||
updatePacket = objectivePacketConstructor.invoke();
|
||||
createObjectivePacket(createPacket, 0);
|
||||
createObjectivePacket(updatePacket, 2);
|
||||
updateTitle(sidebar.title());
|
||||
}
|
||||
}
|
||||
createPacket = objectivePacketConstructor.invoke();
|
||||
updatePacket = objectivePacketConstructor.invoke();
|
||||
createObjectivePacket(createPacket, 0);
|
||||
createObjectivePacket(updatePacket, 2);
|
||||
updateTitle(sidebar.title());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDisplayName(ClientboundSetObjectivePacket packet, net.minecraft.network.chat.Component displayName) {
|
||||
UnsafeUtilities.setField(objectiveDisplayNameField, packet, displayName);
|
||||
}
|
||||
private void updateDisplayName(ClientboundSetObjectivePacket packet, net.minecraft.network.chat.Component displayName) {
|
||||
UnsafeUtilities.setField(objectiveDisplayNameField, packet, displayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTitle(Component displayName) {
|
||||
if (createPacket != null && updatePacket != null) {
|
||||
net.minecraft.network.chat.Component vanilla = NativeAdventureUtil.fromAdventureComponent(displayName);
|
||||
updateDisplayName(createPacket, vanilla);
|
||||
updateDisplayName(updatePacket, vanilla);
|
||||
}
|
||||
@Override
|
||||
public void updateTitle(Component displayName) {
|
||||
if (createPacket != null && updatePacket != null) {
|
||||
net.minecraft.network.chat.Component vanilla = NativeAdventureUtil.fromAdventureComponent(displayName);
|
||||
updateDisplayName(createPacket, vanilla);
|
||||
updateDisplayName(updatePacket, vanilla);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendObjectivePacket(Collection<Player> players, boolean create) {
|
||||
initialisePackets();
|
||||
impl.sendPacket(players, create ? createPacket : updatePacket);
|
||||
}
|
||||
@Override
|
||||
protected void sendObjectivePacket(Collection<Player> players, boolean create) {
|
||||
initialisePackets();
|
||||
impl.sendPacket(players, create ? createPacket : updatePacket);
|
||||
}
|
||||
}
|
||||
+39
-39
@@ -13,52 +13,52 @@ import java.util.Locale;
|
||||
|
||||
public class SidebarNMSImpl extends AbstractSidebarImpl {
|
||||
|
||||
private final ClientboundSetObjectivePacket createPacket;
|
||||
private final ClientboundSetObjectivePacket updatePacket;
|
||||
private final ClientboundSetObjectivePacket createPacket;
|
||||
private final ClientboundSetObjectivePacket updatePacket;
|
||||
|
||||
public SidebarNMSImpl(NMSImpl impl, Sidebar sidebar) {
|
||||
super(impl, sidebar);
|
||||
public SidebarNMSImpl(NMSImpl impl, Sidebar sidebar) {
|
||||
super(impl, sidebar);
|
||||
|
||||
Locale locale = sidebar.locale();
|
||||
if (locale != null) {
|
||||
createPacket = objectivePacketConstructor.invoke();
|
||||
createObjectivePacket(createPacket, 0);
|
||||
updateDisplayName(createPacket, sidebar.title(), locale);
|
||||
Locale locale = sidebar.locale();
|
||||
if (locale != null) {
|
||||
createPacket = objectivePacketConstructor.invoke();
|
||||
createObjectivePacket(createPacket, 0);
|
||||
updateDisplayName(createPacket, sidebar.title(), locale);
|
||||
|
||||
updatePacket = objectivePacketConstructor.invoke();
|
||||
createObjectivePacket(updatePacket, 2);
|
||||
updateDisplayName(updatePacket, sidebar.title(), locale);
|
||||
} else {
|
||||
createPacket = null;
|
||||
updatePacket = null;
|
||||
}
|
||||
updatePacket = objectivePacketConstructor.invoke();
|
||||
createObjectivePacket(updatePacket, 2);
|
||||
updateDisplayName(updatePacket, sidebar.title(), locale);
|
||||
} else {
|
||||
createPacket = null;
|
||||
updatePacket = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDisplayName(ClientboundSetObjectivePacket packet, Component displayName, Locale locale) {
|
||||
net.minecraft.network.chat.Component vanilla = impl.fromAdventure(displayName, locale, sidebar.componentTranslator());
|
||||
UnsafeUtilities.setField(objectiveDisplayNameField, packet, vanilla);
|
||||
}
|
||||
private void updateDisplayName(ClientboundSetObjectivePacket packet, Component displayName, Locale locale) {
|
||||
net.minecraft.network.chat.Component vanilla = impl.fromAdventure(displayName, locale, sidebar.componentTranslator());
|
||||
UnsafeUtilities.setField(objectiveDisplayNameField, packet, vanilla);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTitle(Component displayName) {
|
||||
Locale locale = sidebar.locale();
|
||||
if (locale != null) {
|
||||
updateDisplayName(createPacket, displayName, locale);
|
||||
updateDisplayName(updatePacket, displayName, locale);
|
||||
}
|
||||
@Override
|
||||
public void updateTitle(Component displayName) {
|
||||
Locale locale = sidebar.locale();
|
||||
if (locale != null) {
|
||||
updateDisplayName(createPacket, displayName, locale);
|
||||
updateDisplayName(updatePacket, displayName, locale);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendObjectivePacket(Collection<Player> players, boolean create) {
|
||||
if (sidebar.locale() != null) {
|
||||
impl.sendPacket(players, create ? createPacket : updatePacket);
|
||||
} else {
|
||||
ScoreboardManagerNMS.sendLocalePackets(sidebar.locale(), impl, players, locale -> {
|
||||
ClientboundSetObjectivePacket packet = objectivePacketConstructor.invoke();
|
||||
createObjectivePacket(packet, create ? 0 : 2);
|
||||
updateDisplayName(packet, sidebar.title(), locale);
|
||||
return packet;
|
||||
});
|
||||
}
|
||||
@Override
|
||||
protected void sendObjectivePacket(Collection<Player> players, boolean create) {
|
||||
if (sidebar.locale() != null) {
|
||||
impl.sendPacket(players, create ? createPacket : updatePacket);
|
||||
} else {
|
||||
ScoreboardManagerNMS.sendLocalePackets(sidebar.locale(), impl, players, locale -> {
|
||||
ClientboundSetObjectivePacket packet = objectivePacketConstructor.invoke();
|
||||
createObjectivePacket(packet, create ? 0 : 2);
|
||||
updateDisplayName(packet, sidebar.title(), locale);
|
||||
return packet;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
+85
-85
@@ -25,104 +25,104 @@ import static net.megavex.scoreboardlibrary.internal.nms.base.util.UnsafeUtiliti
|
||||
|
||||
public abstract class AbstractTeamNMSImpl extends TeamNMS<Packet<?>, NMSImpl> {
|
||||
|
||||
protected static final Field displayNameField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "a"),
|
||||
prefixField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "b"),
|
||||
suffixField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "c"),
|
||||
entriesField = getField(ClientboundSetPlayerTeamPacket.class, "j"),
|
||||
nameTagVisibilityField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "d"),
|
||||
collisionRuleField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "e"),
|
||||
colorField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "f"),
|
||||
optionsField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "g");
|
||||
private static final Constructor<ClientboundSetPlayerTeamPacket> teamPacketConstructor;
|
||||
protected static final Field displayNameField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "a"),
|
||||
prefixField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "b"),
|
||||
suffixField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "c"),
|
||||
entriesField = getField(ClientboundSetPlayerTeamPacket.class, "j"),
|
||||
nameTagVisibilityField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "d"),
|
||||
collisionRuleField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "e"),
|
||||
colorField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "f"),
|
||||
optionsField = getField(ClientboundSetPlayerTeamPacket.Parameters.class, "g");
|
||||
private static final Constructor<ClientboundSetPlayerTeamPacket> teamPacketConstructor;
|
||||
|
||||
static {
|
||||
try {
|
||||
teamPacketConstructor = ClientboundSetPlayerTeamPacket.class.getDeclaredConstructor(String.class, int.class, Optional.class, Collection.class);
|
||||
teamPacketConstructor.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
static {
|
||||
try {
|
||||
teamPacketConstructor = ClientboundSetPlayerTeamPacket.class.getDeclaredConstructor(String.class, int.class, Optional.class, Collection.class);
|
||||
teamPacketConstructor.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected ClientboundSetPlayerTeamPacket removePacket;
|
||||
protected ClientboundSetPlayerTeamPacket removePacket;
|
||||
|
||||
AbstractTeamNMSImpl(NMSImpl impl, String teamName) {
|
||||
super(impl, teamName);
|
||||
AbstractTeamNMSImpl(NMSImpl impl, String teamName) {
|
||||
super(impl, teamName);
|
||||
}
|
||||
|
||||
public static ClientboundSetPlayerTeamPacket createTeamsPacket(
|
||||
int method,
|
||||
String name,
|
||||
ClientboundSetPlayerTeamPacket.Parameters parameters,
|
||||
Collection<String> entries
|
||||
) {
|
||||
try {
|
||||
return teamPacketConstructor.newInstance(name, method, Optional.ofNullable(parameters), entries == null ? ImmutableList.of() : entries);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ClientboundSetPlayerTeamPacket createTeamsPacket(
|
||||
int method,
|
||||
String name,
|
||||
ClientboundSetPlayerTeamPacket.Parameters parameters,
|
||||
Collection<String> entries
|
||||
) {
|
||||
try {
|
||||
return teamPacketConstructor.newInstance(name, method, Optional.ofNullable(parameters), entries == null ? ImmutableList.of() : entries);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@Override
|
||||
public void removeTeam(Iterable<Player> players) {
|
||||
if (removePacket == null) {
|
||||
removePacket = createTeamsPacket(MODE_REMOVE, teamName, null, null);
|
||||
}
|
||||
impl.sendPacket(players, removePacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamInfoNMS<String> createLegacyTeamInfoNMS(ImmutableTeamProperties<String> properties) {
|
||||
if (impl.protocolSupport()) return new LegacyTeamInfoNMS(properties, teamName);
|
||||
return super.createLegacyTeamInfoNMS(properties);
|
||||
}
|
||||
|
||||
abstract class TeamInfoNMSImpl extends TeamNMS.TeamInfoNMS<Component> {
|
||||
|
||||
static final UnsafeUtilities.PacketConstructor<ClientboundSetPlayerTeamPacket.Parameters> parametersConstructor =
|
||||
UnsafeUtilities.findPacketConstructor(ClientboundSetPlayerTeamPacket.Parameters.class, MethodHandles.lookup());
|
||||
|
||||
public TeamInfoNMSImpl(ImmutableTeamProperties<Component> properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTeam(Iterable<Player> players) {
|
||||
if (removePacket == null) {
|
||||
removePacket = createTeamsPacket(MODE_REMOVE, teamName, null, null);
|
||||
}
|
||||
impl.sendPacket(players, removePacket);
|
||||
public void addEntries(Collection<Player> players, Collection<String> entries) {
|
||||
teamEntry(players, entries, MODE_ADD_ENTRIES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamInfoNMS<String> createLegacyTeamInfoNMS(ImmutableTeamProperties<String> properties) {
|
||||
if (impl.protocolSupport()) return new LegacyTeamInfoNMS(properties, teamName);
|
||||
return super.createLegacyTeamInfoNMS(properties);
|
||||
public void removeEntries(Collection<Player> players, Collection<String> entries) {
|
||||
teamEntry(players, entries, MODE_REMOVE_ENTRIES);
|
||||
}
|
||||
|
||||
abstract class TeamInfoNMSImpl extends TeamNMS.TeamInfoNMS<Component> {
|
||||
|
||||
static final UnsafeUtilities.PacketConstructor<ClientboundSetPlayerTeamPacket.Parameters> parametersConstructor =
|
||||
UnsafeUtilities.findPacketConstructor(ClientboundSetPlayerTeamPacket.Parameters.class, MethodHandles.lookup());
|
||||
|
||||
public TeamInfoNMSImpl(ImmutableTeamProperties<Component> properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntries(Collection<Player> players, Collection<String> entries) {
|
||||
teamEntry(players, entries, MODE_ADD_ENTRIES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntries(Collection<Player> players, Collection<String> entries) {
|
||||
teamEntry(players, entries, MODE_REMOVE_ENTRIES);
|
||||
}
|
||||
|
||||
private void teamEntry(Collection<Player> players, Collection<String> entries, int action) {
|
||||
impl.sendPacket(players, createTeamsPacket(action, teamName, null, entries));
|
||||
}
|
||||
|
||||
protected void fillTeamPacket(ClientboundSetPlayerTeamPacket packet, Collection<String> entries) {
|
||||
if (packet.getPlayers() != entries) {
|
||||
UnsafeUtilities.setField(entriesField, packet, entries);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fillParameters(ClientboundSetPlayerTeamPacket.Parameters parameters, Locale locale) {
|
||||
String key = properties.nameTagVisibility().key();
|
||||
if (!Objects.equals(parameters.getNametagVisibility(), key)) {
|
||||
UnsafeUtilities.setField(nameTagVisibilityField, parameters, key);
|
||||
}
|
||||
|
||||
key = properties.collisionRule().key();
|
||||
if (!Objects.equals(parameters.getCollisionRule(), key))
|
||||
UnsafeUtilities.setField(collisionRuleField, parameters, key);
|
||||
|
||||
char c = LegacyFormatUtil.getChar(properties.playerColor());
|
||||
if (parameters.getColor() == null || parameters.getColor().code != c)
|
||||
UnsafeUtilities.setField(colorField, parameters, ChatFormatting.getByCode(c));
|
||||
|
||||
int options = properties.packOptions();
|
||||
if (parameters.getOptions() != options)
|
||||
UnsafeUtilities.UNSAFE.putInt(parameters, UnsafeUtilities.UNSAFE.objectFieldOffset(optionsField), options);
|
||||
}
|
||||
private void teamEntry(Collection<Player> players, Collection<String> entries, int action) {
|
||||
impl.sendPacket(players, createTeamsPacket(action, teamName, null, entries));
|
||||
}
|
||||
|
||||
protected void fillTeamPacket(ClientboundSetPlayerTeamPacket packet, Collection<String> entries) {
|
||||
if (packet.getPlayers() != entries) {
|
||||
UnsafeUtilities.setField(entriesField, packet, entries);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fillParameters(ClientboundSetPlayerTeamPacket.Parameters parameters, Locale locale) {
|
||||
String key = properties.nameTagVisibility().key();
|
||||
if (!Objects.equals(parameters.getNametagVisibility(), key)) {
|
||||
UnsafeUtilities.setField(nameTagVisibilityField, parameters, key);
|
||||
}
|
||||
|
||||
key = properties.collisionRule().key();
|
||||
if (!Objects.equals(parameters.getCollisionRule(), key))
|
||||
UnsafeUtilities.setField(collisionRuleField, parameters, key);
|
||||
|
||||
char c = LegacyFormatUtil.getChar(properties.playerColor());
|
||||
if (parameters.getColor() == null || parameters.getColor().code != c)
|
||||
UnsafeUtilities.setField(colorField, parameters, ChatFormatting.getByCode(c));
|
||||
|
||||
int options = properties.packOptions();
|
||||
if (parameters.getOptions() != options)
|
||||
UnsafeUtilities.UNSAFE.putInt(parameters, UnsafeUtilities.UNSAFE.objectFieldOffset(optionsField), options);
|
||||
}
|
||||
}
|
||||
}
|
||||
+67
-67
@@ -15,75 +15,75 @@ import java.util.Collection;
|
||||
|
||||
public class LegacyTeamInfoNMS extends TeamNMS.TeamInfoNMS<String> {
|
||||
|
||||
private final String teamName;
|
||||
private final String teamName;
|
||||
|
||||
public LegacyTeamInfoNMS(ImmutableTeamProperties<String> properties, String teamName) {
|
||||
super(properties);
|
||||
this.teamName = teamName;
|
||||
public LegacyTeamInfoNMS(ImmutableTeamProperties<String> properties, String teamName) {
|
||||
super(properties);
|
||||
this.teamName = teamName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntries(Collection<Player> players, Collection<String> entries) {
|
||||
sendPacket(players, createEntriesPacket(true, entries));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntries(Collection<Player> players, Collection<String> entries) {
|
||||
sendPacket(players, createEntriesPacket(false, entries));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTeam(Collection<Player> players) {
|
||||
sendPacket(players, createInfoPacket(true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTeam(Collection<Player> players) {
|
||||
sendPacket(players, createInfoPacket(false));
|
||||
}
|
||||
|
||||
private void sendPacket(Collection<Player> players, ClientBoundPacketData data) {
|
||||
for (Player player : players) {
|
||||
Connection connection = ProtocolSupportAPI.getConnection(player);
|
||||
if (connection == null) continue;
|
||||
((ConnectionImpl) connection).getPacketDataIO().writeClientbound(data);
|
||||
}
|
||||
}
|
||||
|
||||
private ClientBoundPacketData createPacket(int mode) {
|
||||
ClientBoundPacketData data = ClientBoundPacketData.create(ClientBoundPacketType.PLAY_SCOREBOARD_TEAM);
|
||||
StringCodec.writeVarIntUTF8String(data, teamName);
|
||||
data.writeByte(mode);
|
||||
return data;
|
||||
}
|
||||
|
||||
private ClientBoundPacketData createInfoPacket(boolean create) {
|
||||
ClientBoundPacketData data = createPacket(create ? TeamNMS.MODE_CREATE : TeamNMS.MODE_UPDATE);
|
||||
|
||||
StringCodec.writeVarIntUTF8String(data, properties.displayName());
|
||||
StringCodec.writeVarIntUTF8String(data, properties.prefix());
|
||||
StringCodec.writeVarIntUTF8String(data, properties.suffix());
|
||||
data.writeByte(properties.packOptions());
|
||||
StringCodec.writeVarIntUTF8String(data, properties.nameTagVisibility().key());
|
||||
data.writeByte(0);
|
||||
|
||||
if (create) {
|
||||
writeEntries(data, properties.entries());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntries(Collection<Player> players, Collection<String> entries) {
|
||||
sendPacket(players, createEntriesPacket(true, entries));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntries(Collection<Player> players, Collection<String> entries) {
|
||||
sendPacket(players, createEntriesPacket(false, entries));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTeam(Collection<Player> players) {
|
||||
sendPacket(players, createInfoPacket(true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTeam(Collection<Player> players) {
|
||||
sendPacket(players, createInfoPacket(false));
|
||||
}
|
||||
|
||||
private void sendPacket(Collection<Player> players, ClientBoundPacketData data) {
|
||||
for (Player player : players) {
|
||||
Connection connection = ProtocolSupportAPI.getConnection(player);
|
||||
if (connection == null) continue;
|
||||
((ConnectionImpl) connection).getPacketDataIO().writeClientbound(data);
|
||||
}
|
||||
}
|
||||
|
||||
private ClientBoundPacketData createPacket(int mode) {
|
||||
ClientBoundPacketData data = ClientBoundPacketData.create(ClientBoundPacketType.PLAY_SCOREBOARD_TEAM);
|
||||
StringCodec.writeVarIntUTF8String(data, teamName);
|
||||
data.writeByte(mode);
|
||||
return data;
|
||||
}
|
||||
|
||||
private ClientBoundPacketData createInfoPacket(boolean create) {
|
||||
ClientBoundPacketData data = createPacket(create ? TeamNMS.MODE_CREATE : TeamNMS.MODE_UPDATE);
|
||||
|
||||
StringCodec.writeVarIntUTF8String(data, properties.displayName());
|
||||
StringCodec.writeVarIntUTF8String(data, properties.prefix());
|
||||
StringCodec.writeVarIntUTF8String(data, properties.suffix());
|
||||
data.writeByte(properties.packOptions());
|
||||
StringCodec.writeVarIntUTF8String(data, properties.nameTagVisibility().key());
|
||||
data.writeByte(0);
|
||||
|
||||
if (create) {
|
||||
writeEntries(data, properties.entries());
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private ClientBoundPacketData createEntriesPacket(boolean add, Collection<String> entries) {
|
||||
ClientBoundPacketData data = createPacket(add ? TeamNMS.MODE_ADD_ENTRIES : TeamNMS.MODE_REMOVE_ENTRIES);
|
||||
writeEntries(data, entries);
|
||||
return data;
|
||||
}
|
||||
|
||||
private void writeEntries(ClientBoundPacketData data, Collection<String> entries) {
|
||||
VarNumberCodec.writeVarInt(data, entries.size());
|
||||
for (String entry : entries) {
|
||||
StringCodec.writeVarIntUTF8String(data, entry);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private ClientBoundPacketData createEntriesPacket(boolean add, Collection<String> entries) {
|
||||
ClientBoundPacketData data = createPacket(add ? TeamNMS.MODE_ADD_ENTRIES : TeamNMS.MODE_REMOVE_ENTRIES);
|
||||
writeEntries(data, entries);
|
||||
return data;
|
||||
}
|
||||
|
||||
private void writeEntries(ClientBoundPacketData data, Collection<String> entries) {
|
||||
VarNumberCodec.writeVarInt(data, entries.size());
|
||||
for (String entry : entries) {
|
||||
StringCodec.writeVarIntUTF8String(data, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
-51
@@ -15,61 +15,61 @@ import java.util.Locale;
|
||||
|
||||
public class PaperTeamNMSImpl extends AbstractTeamNMSImpl {
|
||||
|
||||
public PaperTeamNMSImpl(NMSImpl impl, String teamName) {
|
||||
super(impl, teamName);
|
||||
public PaperTeamNMSImpl(NMSImpl impl, String teamName) {
|
||||
super(impl, teamName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamInfoNMS<Component> createTeamInfoNMS(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator) {
|
||||
return new TeamInfoNMSImpl(properties);
|
||||
}
|
||||
|
||||
private class TeamInfoNMSImpl extends AbstractTeamNMSImpl.TeamInfoNMSImpl {
|
||||
|
||||
final ClientboundSetPlayerTeamPacket.Parameters parameters = parametersConstructor.invoke();
|
||||
protected final ClientboundSetPlayerTeamPacket createPacket = createTeamsPacket(TeamNMS.MODE_CREATE, teamName, parameters, null);
|
||||
protected final ClientboundSetPlayerTeamPacket updatePacket = createTeamsPacket(TeamNMS.MODE_UPDATE, teamName, parameters, null);
|
||||
private Component displayName, prefix, suffix;
|
||||
|
||||
public TeamInfoNMSImpl(ImmutableTeamProperties<Component> properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamInfoNMS<Component> createTeamInfoNMS(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator) {
|
||||
return new TeamInfoNMSImpl(properties);
|
||||
public void updateTeamPackets(Collection<String> entries) {
|
||||
fillParameters(parameters, null);
|
||||
fillTeamPacket(createPacket, entries);
|
||||
fillTeamPacket(updatePacket, entries);
|
||||
}
|
||||
|
||||
private class TeamInfoNMSImpl extends AbstractTeamNMSImpl.TeamInfoNMSImpl {
|
||||
|
||||
final ClientboundSetPlayerTeamPacket.Parameters parameters = parametersConstructor.invoke();
|
||||
protected final ClientboundSetPlayerTeamPacket createPacket = createTeamsPacket(TeamNMS.MODE_CREATE, teamName, parameters, null);
|
||||
protected final ClientboundSetPlayerTeamPacket updatePacket = createTeamsPacket(TeamNMS.MODE_UPDATE, teamName, parameters, null);
|
||||
private Component displayName, prefix, suffix;
|
||||
|
||||
public TeamInfoNMSImpl(ImmutableTeamProperties<Component> properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTeamPackets(Collection<String> entries) {
|
||||
fillParameters(parameters, null);
|
||||
fillTeamPacket(createPacket, entries);
|
||||
fillTeamPacket(updatePacket, entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTeam(Collection<Player> players) {
|
||||
impl.sendPacket(players, createPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTeam(Collection<Player> players) {
|
||||
impl.sendPacket(players, updatePacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillParameters(ClientboundSetPlayerTeamPacket.Parameters parameters, Locale locale) {
|
||||
super.fillParameters(parameters, locale);
|
||||
|
||||
if (properties.displayName() != displayName) {
|
||||
UnsafeUtilities.setField(displayNameField, parameters, NativeAdventureUtil.fromAdventureComponent(properties.displayName()));
|
||||
displayName = properties.displayName();
|
||||
}
|
||||
|
||||
if (properties.prefix() != prefix) {
|
||||
UnsafeUtilities.setField(prefixField, parameters, NativeAdventureUtil.fromAdventureComponent(properties.prefix()));
|
||||
prefix = properties.prefix();
|
||||
}
|
||||
|
||||
if (properties.suffix() != suffix) {
|
||||
UnsafeUtilities.setField(suffixField, parameters, NativeAdventureUtil.fromAdventureComponent(properties.suffix()));
|
||||
suffix = properties.suffix();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void createTeam(Collection<Player> players) {
|
||||
impl.sendPacket(players, createPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTeam(Collection<Player> players) {
|
||||
impl.sendPacket(players, updatePacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillParameters(ClientboundSetPlayerTeamPacket.Parameters parameters, Locale locale) {
|
||||
super.fillParameters(parameters, locale);
|
||||
|
||||
if (properties.displayName() != displayName) {
|
||||
UnsafeUtilities.setField(displayNameField, parameters, NativeAdventureUtil.fromAdventureComponent(properties.displayName()));
|
||||
displayName = properties.displayName();
|
||||
}
|
||||
|
||||
if (properties.prefix() != prefix) {
|
||||
UnsafeUtilities.setField(prefixField, parameters, NativeAdventureUtil.fromAdventureComponent(properties.prefix()));
|
||||
prefix = properties.prefix();
|
||||
}
|
||||
|
||||
if (properties.suffix() != suffix) {
|
||||
UnsafeUtilities.setField(suffixField, parameters, NativeAdventureUtil.fromAdventureComponent(properties.suffix()));
|
||||
suffix = properties.suffix();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
-44
@@ -14,54 +14,54 @@ import java.util.Locale;
|
||||
|
||||
public class TeamNMSImpl extends AbstractTeamNMSImpl {
|
||||
|
||||
public TeamNMSImpl(NMSImpl impl, String teamName) {
|
||||
super(impl, teamName);
|
||||
public TeamNMSImpl(NMSImpl impl, String teamName) {
|
||||
super(impl, teamName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamInfoNMS<Component> createTeamInfoNMS(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator) {
|
||||
return new TeamInfoNMSImpl(properties, componentTranslator);
|
||||
}
|
||||
|
||||
private class TeamInfoNMSImpl extends AbstractTeamNMSImpl.TeamInfoNMSImpl {
|
||||
|
||||
private final ComponentTranslator componentTranslator;
|
||||
|
||||
public TeamInfoNMSImpl(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator) {
|
||||
super(properties);
|
||||
this.componentTranslator = componentTranslator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamInfoNMS<Component> createTeamInfoNMS(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator) {
|
||||
return new TeamInfoNMSImpl(properties, componentTranslator);
|
||||
public void createTeam(Collection<Player> players) {
|
||||
sendTeamPacket(players, true);
|
||||
}
|
||||
|
||||
private class TeamInfoNMSImpl extends AbstractTeamNMSImpl.TeamInfoNMSImpl {
|
||||
|
||||
private final ComponentTranslator componentTranslator;
|
||||
|
||||
public TeamInfoNMSImpl(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator) {
|
||||
super(properties);
|
||||
this.componentTranslator = componentTranslator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTeam(Collection<Player> players) {
|
||||
sendTeamPacket(players, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTeam(Collection<Player> players) {
|
||||
sendTeamPacket(players, false);
|
||||
}
|
||||
|
||||
private void sendTeamPacket(Collection<Player> players, boolean create) {
|
||||
ScoreboardManagerNMS.sendLocalePackets(null, impl, players, locale -> {
|
||||
ClientboundSetPlayerTeamPacket.Parameters parameters = parametersConstructor.invoke();
|
||||
fillParameters(parameters, locale);
|
||||
return createTeamsPacket(create ? MODE_CREATE : MODE_UPDATE, teamName, parameters, properties.entries());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillParameters(ClientboundSetPlayerTeamPacket.Parameters parameters, Locale locale) {
|
||||
super.fillParameters(parameters, locale);
|
||||
|
||||
net.minecraft.network.chat.Component vanilla = impl.fromAdventure(properties.displayName(), locale, componentTranslator);
|
||||
UnsafeUtilities.setField(displayNameField, parameters, vanilla);
|
||||
|
||||
vanilla = impl.fromAdventure(properties.prefix(), locale, componentTranslator);
|
||||
UnsafeUtilities.setField(prefixField, parameters, vanilla);
|
||||
|
||||
vanilla = impl.fromAdventure(properties.suffix(), locale, componentTranslator);
|
||||
UnsafeUtilities.setField(suffixField, parameters, vanilla);
|
||||
}
|
||||
@Override
|
||||
public void updateTeam(Collection<Player> players) {
|
||||
sendTeamPacket(players, false);
|
||||
}
|
||||
|
||||
private void sendTeamPacket(Collection<Player> players, boolean create) {
|
||||
ScoreboardManagerNMS.sendLocalePackets(null, impl, players, locale -> {
|
||||
ClientboundSetPlayerTeamPacket.Parameters parameters = parametersConstructor.invoke();
|
||||
fillParameters(parameters, locale);
|
||||
return createTeamsPacket(create ? MODE_CREATE : MODE_UPDATE, teamName, parameters, properties.entries());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillParameters(ClientboundSetPlayerTeamPacket.Parameters parameters, Locale locale) {
|
||||
super.fillParameters(parameters, locale);
|
||||
|
||||
net.minecraft.network.chat.Component vanilla = impl.fromAdventure(properties.displayName(), locale, componentTranslator);
|
||||
UnsafeUtilities.setField(displayNameField, parameters, vanilla);
|
||||
|
||||
vanilla = impl.fromAdventure(properties.prefix(), locale, componentTranslator);
|
||||
UnsafeUtilities.setField(prefixField, parameters, vanilla);
|
||||
|
||||
vanilla = impl.fromAdventure(properties.suffix(), locale, componentTranslator);
|
||||
UnsafeUtilities.setField(suffixField, parameters, vanilla);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -5,10 +5,10 @@ import net.kyori.adventure.text.Component;
|
||||
|
||||
public final class NativeAdventureUtil {
|
||||
|
||||
private NativeAdventureUtil() {
|
||||
}
|
||||
private NativeAdventureUtil() {
|
||||
}
|
||||
|
||||
public static net.minecraft.network.chat.Component fromAdventureComponent(Component component) {
|
||||
return new AdventureComponent(component);
|
||||
}
|
||||
public static net.minecraft.network.chat.Component fromAdventureComponent(Component component) {
|
||||
return new AdventureComponent(component);
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -7,14 +7,14 @@ import protocolsupport.api.ProtocolVersion;
|
||||
|
||||
public final class ProtocolSupportUtil {
|
||||
|
||||
private ProtocolSupportUtil() {
|
||||
}
|
||||
private ProtocolSupportUtil() {
|
||||
}
|
||||
|
||||
public static boolean isLegacy(Player player) {
|
||||
Connection connection = ProtocolSupportAPI.getConnection(player);
|
||||
if (connection == null) return false;
|
||||
public static boolean isLegacy(Player player) {
|
||||
Connection connection = ProtocolSupportAPI.getConnection(player);
|
||||
if (connection == null) return false;
|
||||
|
||||
// TODO: may work on older versions, need to test that
|
||||
return connection.getVersion().isBetween(ProtocolVersion.MINECRAFT_1_12_2, ProtocolVersion.MINECRAFT_1_8);
|
||||
}
|
||||
// TODO: may work on older versions, need to test that
|
||||
return connection.getVersion().isBetween(ProtocolVersion.MINECRAFT_1_12_2, ProtocolVersion.MINECRAFT_1_8);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
plugins {
|
||||
id("net.megavex.scoreboardlibrary.publish-conventions")
|
||||
id("net.megavex.scoreboardlibrary.nms-conventions")
|
||||
id("net.megavex.scoreboardlibrary.publish-conventions")
|
||||
id("net.megavex.scoreboardlibrary.nms-conventions")
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "SportPaper"
|
||||
url = uri("https://repo.ashcon.app/nexus/content/repositories/snapshots/")
|
||||
}
|
||||
maven {
|
||||
name = "SportPaper"
|
||||
url = uri("https://repo.ashcon.app/nexus/content/repositories/snapshots/")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("app.ashcon:sportpaper:1.8.8-R0.1-SNAPSHOT")
|
||||
}
|
||||
compileOnly("app.ashcon:sportpaper:1.8.8-R0.1-SNAPSHOT")
|
||||
}
|
||||
+45
-45
@@ -15,59 +15,59 @@ import java.lang.reflect.Field;
|
||||
|
||||
public class NMSImpl extends ScoreboardManagerNMS<Packet<?>> {
|
||||
|
||||
static final Field objectiveModeField;
|
||||
static final Field objectiveModeField;
|
||||
|
||||
static {
|
||||
objectiveModeField = UnsafeUtilities.getField(PacketPlayOutScoreboardObjective.class, "d");
|
||||
}
|
||||
static {
|
||||
objectiveModeField = UnsafeUtilities.getField(PacketPlayOutScoreboardObjective.class, "d");
|
||||
}
|
||||
|
||||
private final PacketPlayOutScoreboardDisplayObjective displayPacket = new PacketPlayOutScoreboardDisplayObjective();
|
||||
private final PacketPlayOutScoreboardObjective removePacket = new PacketPlayOutScoreboardObjective();
|
||||
private final PacketPlayOutScoreboardDisplayObjective displayPacket = new PacketPlayOutScoreboardDisplayObjective();
|
||||
private final PacketPlayOutScoreboardObjective removePacket = new PacketPlayOutScoreboardObjective();
|
||||
|
||||
public NMSImpl() {
|
||||
// Setup static packets
|
||||
UnsafeUtilities.UNSAFE.putInt(
|
||||
displayPacket,
|
||||
UnsafeUtilities.UNSAFE.objectFieldOffset(UnsafeUtilities.getField(PacketPlayOutScoreboardDisplayObjective.class, "a")),
|
||||
1
|
||||
);
|
||||
UnsafeUtilities.setField(UnsafeUtilities.getField(PacketPlayOutScoreboardDisplayObjective.class, "b"), displayPacket, objectiveName);
|
||||
public NMSImpl() {
|
||||
// Setup static packets
|
||||
UnsafeUtilities.UNSAFE.putInt(
|
||||
displayPacket,
|
||||
UnsafeUtilities.UNSAFE.objectFieldOffset(UnsafeUtilities.getField(PacketPlayOutScoreboardDisplayObjective.class, "a")),
|
||||
1
|
||||
);
|
||||
UnsafeUtilities.setField(UnsafeUtilities.getField(PacketPlayOutScoreboardDisplayObjective.class, "b"), displayPacket, objectiveName);
|
||||
|
||||
UnsafeUtilities.setField(UnsafeUtilities.getField(PacketPlayOutScoreboardObjective.class, "a"), removePacket, objectiveName);
|
||||
UnsafeUtilities.UNSAFE.putInt(
|
||||
removePacket,
|
||||
UnsafeUtilities.UNSAFE.objectFieldOffset(objectiveModeField),
|
||||
1
|
||||
);
|
||||
}
|
||||
UnsafeUtilities.setField(UnsafeUtilities.getField(PacketPlayOutScoreboardObjective.class, "a"), removePacket, objectiveName);
|
||||
UnsafeUtilities.UNSAFE.putInt(
|
||||
removePacket,
|
||||
UnsafeUtilities.UNSAFE.objectFieldOffset(objectiveModeField),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SidebarNMS<Packet<?>, ?> createSidebarNMS(Sidebar sidebar) {
|
||||
return new SidebarNMSImpl(this, sidebar);
|
||||
}
|
||||
@Override
|
||||
public SidebarNMS<Packet<?>, ?> createSidebarNMS(Sidebar sidebar) {
|
||||
return new SidebarNMSImpl(this, sidebar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displaySidebar(Iterable<Player> players) {
|
||||
sendPacket(players, displayPacket);
|
||||
}
|
||||
@Override
|
||||
public void displaySidebar(Iterable<Player> players) {
|
||||
sendPacket(players, displayPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSidebar(Iterable<Player> players) {
|
||||
sendPacket(players, removePacket);
|
||||
}
|
||||
@Override
|
||||
public void removeSidebar(Iterable<Player> players) {
|
||||
sendPacket(players, removePacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamNMS<?, ?> createTeamNMS(String teamName) {
|
||||
return new TeamNMSImpl(this, teamName);
|
||||
}
|
||||
@Override
|
||||
public TeamNMS<?, ?> createTeamNMS(String teamName) {
|
||||
return new TeamNMSImpl(this, teamName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLegacy(Player player) {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean isLegacy(Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Player player, Packet<?> packet) {
|
||||
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
@Override
|
||||
public void sendPacket(Player player, Packet<?> packet) {
|
||||
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
+68
-68
@@ -20,82 +20,82 @@ import static net.kyori.adventure.text.Component.empty;
|
||||
|
||||
public class SidebarNMSImpl extends SidebarNMS<Packet<?>, NMSImpl> {
|
||||
|
||||
private static final Field objectiveNameField, objectiveDisplayNameField, objectiveHealthDisplayField, scoreNameField, scoreObjectiveNameField, scoreScoreField, scoreActionField;
|
||||
private static final Field objectiveNameField, objectiveDisplayNameField, objectiveHealthDisplayField, scoreNameField, scoreObjectiveNameField, scoreScoreField, scoreActionField;
|
||||
|
||||
static {
|
||||
objectiveNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardObjective.class, "a");
|
||||
objectiveDisplayNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardObjective.class, "b");
|
||||
objectiveHealthDisplayField = UnsafeUtilities.getField(PacketPlayOutScoreboardObjective.class, "c");
|
||||
scoreNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardScore.class, "a");
|
||||
scoreObjectiveNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardScore.class, "b");
|
||||
scoreScoreField = UnsafeUtilities.getField(PacketPlayOutScoreboardScore.class, "c");
|
||||
scoreActionField = UnsafeUtilities.getField(PacketPlayOutScoreboardScore.class, "d");
|
||||
static {
|
||||
objectiveNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardObjective.class, "a");
|
||||
objectiveDisplayNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardObjective.class, "b");
|
||||
objectiveHealthDisplayField = UnsafeUtilities.getField(PacketPlayOutScoreboardObjective.class, "c");
|
||||
scoreNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardScore.class, "a");
|
||||
scoreObjectiveNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardScore.class, "b");
|
||||
scoreScoreField = UnsafeUtilities.getField(PacketPlayOutScoreboardScore.class, "c");
|
||||
scoreActionField = UnsafeUtilities.getField(PacketPlayOutScoreboardScore.class, "d");
|
||||
}
|
||||
|
||||
private final PacketPlayOutScoreboardObjective createPacket;
|
||||
private final PacketPlayOutScoreboardObjective updatePacket;
|
||||
|
||||
SidebarNMSImpl(NMSImpl impl, Sidebar sidebar) {
|
||||
super(impl, sidebar);
|
||||
|
||||
Locale locale = sidebar.locale();
|
||||
if (locale != null) {
|
||||
createPacket = new PacketPlayOutScoreboardObjective();
|
||||
updatePacket = new PacketPlayOutScoreboardObjective();
|
||||
createObjectivePacket(createPacket, 0, empty(), locale);
|
||||
createObjectivePacket(updatePacket, 2, empty(), locale);
|
||||
} else {
|
||||
createPacket = null;
|
||||
updatePacket = null;
|
||||
}
|
||||
}
|
||||
|
||||
private final PacketPlayOutScoreboardObjective createPacket;
|
||||
private final PacketPlayOutScoreboardObjective updatePacket;
|
||||
private void createObjectivePacket(PacketPlayOutScoreboardObjective packet, int mode, Component displayName, Locale locale) {
|
||||
UnsafeUtilities.setField(objectiveNameField, packet, impl.objectiveName);
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(NMSImpl.objectiveModeField), mode);
|
||||
UnsafeUtilities.setField(objectiveHealthDisplayField, packet, IScoreboardCriteria.EnumScoreboardHealthDisplay.INTEGER);
|
||||
updateDisplayName(packet, displayName, locale);
|
||||
}
|
||||
|
||||
SidebarNMSImpl(NMSImpl impl, Sidebar sidebar) {
|
||||
super(impl, sidebar);
|
||||
private void updateDisplayName(PacketPlayOutScoreboardObjective packet, Component displayName, Locale locale) {
|
||||
String value = LegacyFormatUtil.serialize(sidebar.componentTranslator(), displayName, locale);
|
||||
UnsafeUtilities.setField(objectiveDisplayNameField, packet, value);
|
||||
}
|
||||
|
||||
Locale locale = sidebar.locale();
|
||||
if (locale != null) {
|
||||
createPacket = new PacketPlayOutScoreboardObjective();
|
||||
updatePacket = new PacketPlayOutScoreboardObjective();
|
||||
createObjectivePacket(createPacket, 0, empty(), locale);
|
||||
createObjectivePacket(updatePacket, 2, empty(), locale);
|
||||
} else {
|
||||
createPacket = null;
|
||||
updatePacket = null;
|
||||
}
|
||||
@Override
|
||||
public void updateTitle(Component displayName) {
|
||||
Locale locale = sidebar.locale();
|
||||
if (locale != null) {
|
||||
updateDisplayName(createPacket, displayName, locale);
|
||||
updateDisplayName(updatePacket, displayName, locale);
|
||||
}
|
||||
}
|
||||
|
||||
private void createObjectivePacket(PacketPlayOutScoreboardObjective packet, int mode, Component displayName, Locale locale) {
|
||||
UnsafeUtilities.setField(objectiveNameField, packet, impl.objectiveName);
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(NMSImpl.objectiveModeField), mode);
|
||||
UnsafeUtilities.setField(objectiveHealthDisplayField, packet, IScoreboardCriteria.EnumScoreboardHealthDisplay.INTEGER);
|
||||
updateDisplayName(packet, displayName, locale);
|
||||
@Override
|
||||
protected void sendObjectivePacket(Collection<Player> players, boolean create) {
|
||||
if (sidebar.locale() != null) {
|
||||
impl.sendPacket(players, create ? createPacket : updatePacket);
|
||||
} else {
|
||||
ScoreboardManagerNMS.sendLocalePackets(sidebar.locale(), impl, players, locale -> {
|
||||
PacketPlayOutScoreboardObjective packet = new PacketPlayOutScoreboardObjective();
|
||||
createObjectivePacket(packet, create ? 0 : 2, sidebar.title(), locale);
|
||||
return packet;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDisplayName(PacketPlayOutScoreboardObjective packet, Component displayName, Locale locale) {
|
||||
String value = LegacyFormatUtil.serialize(sidebar.componentTranslator(), displayName, locale);
|
||||
UnsafeUtilities.setField(objectiveDisplayNameField, packet, value);
|
||||
}
|
||||
@Override
|
||||
public void removeLine(Collection<Player> players, String line) {
|
||||
impl.sendPacket(players, new PacketPlayOutScoreboardScore(line));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTitle(Component displayName) {
|
||||
Locale locale = sidebar.locale();
|
||||
if (locale != null) {
|
||||
updateDisplayName(createPacket, displayName, locale);
|
||||
updateDisplayName(updatePacket, displayName, locale);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendObjectivePacket(Collection<Player> players, boolean create) {
|
||||
if (sidebar.locale() != null) {
|
||||
impl.sendPacket(players, create ? createPacket : updatePacket);
|
||||
} else {
|
||||
ScoreboardManagerNMS.sendLocalePackets(sidebar.locale(), impl, players, locale -> {
|
||||
PacketPlayOutScoreboardObjective packet = new PacketPlayOutScoreboardObjective();
|
||||
createObjectivePacket(packet, create ? 0 : 2, sidebar.title(), locale);
|
||||
return packet;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLine(Collection<Player> players, String line) {
|
||||
impl.sendPacket(players, new PacketPlayOutScoreboardScore(line));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void score(Collection<Player> players, int score, String line) {
|
||||
PacketPlayOutScoreboardScore packet = new PacketPlayOutScoreboardScore();
|
||||
UnsafeUtilities.setField(scoreNameField, packet, line);
|
||||
UnsafeUtilities.setField(scoreObjectiveNameField, packet, impl.objectiveName);
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(scoreScoreField), score);
|
||||
UnsafeUtilities.setField(scoreActionField, packet, PacketPlayOutScoreboardScore.EnumScoreboardAction.CHANGE);
|
||||
impl.sendPacket(players, packet);
|
||||
}
|
||||
@Override
|
||||
public void score(Collection<Player> players, int score, String line) {
|
||||
PacketPlayOutScoreboardScore packet = new PacketPlayOutScoreboardScore();
|
||||
UnsafeUtilities.setField(scoreNameField, packet, line);
|
||||
UnsafeUtilities.setField(scoreObjectiveNameField, packet, impl.objectiveName);
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(scoreScoreField), score);
|
||||
UnsafeUtilities.setField(scoreActionField, packet, PacketPlayOutScoreboardScore.EnumScoreboardAction.CHANGE);
|
||||
impl.sendPacket(players, packet);
|
||||
}
|
||||
}
|
||||
+97
-97
@@ -19,124 +19,124 @@ import static net.megavex.scoreboardlibrary.internal.nms.base.util.LegacyFormatU
|
||||
|
||||
public class TeamNMSImpl extends TeamNMS<Packet<?>, NMSImpl> {
|
||||
|
||||
private static final Field teamNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "a"),
|
||||
teamDisplayNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "b"),
|
||||
teamPrefixField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "c"),
|
||||
teamSuffixField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "d"),
|
||||
teamNameTagVisibilityField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "e"),
|
||||
teamEntriesField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "g"),
|
||||
teamModeField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "h"),
|
||||
teamRulesField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "i");
|
||||
private static final Field teamNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "a"),
|
||||
teamDisplayNameField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "b"),
|
||||
teamPrefixField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "c"),
|
||||
teamSuffixField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "d"),
|
||||
teamNameTagVisibilityField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "e"),
|
||||
teamEntriesField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "g"),
|
||||
teamModeField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "h"),
|
||||
teamRulesField = UnsafeUtilities.getField(PacketPlayOutScoreboardTeam.class, "i");
|
||||
|
||||
protected PacketPlayOutScoreboardTeam removePacket;
|
||||
protected PacketPlayOutScoreboardTeam removePacket;
|
||||
|
||||
public TeamNMSImpl(NMSImpl impl, String teamName) {
|
||||
super(impl, teamName);
|
||||
public TeamNMSImpl(NMSImpl impl, String teamName) {
|
||||
super(impl, teamName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTeam(Iterable<Player> players) {
|
||||
if (removePacket == null) {
|
||||
removePacket = new PacketPlayOutScoreboardTeam();
|
||||
UnsafeUtilities.setField(teamNameField, removePacket, teamName);
|
||||
UnsafeUtilities.UNSAFE.putInt(removePacket, UnsafeUtilities.UNSAFE.objectFieldOffset(teamModeField), MODE_REMOVE);
|
||||
}
|
||||
impl.sendPacket(players, removePacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamNMS.TeamInfoNMS<Component> createTeamInfoNMS(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator) {
|
||||
return new AdventureTeamInfoNMS(properties, componentTranslator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamInfoNMS<String> createLegacyTeamInfoNMS(ImmutableTeamProperties<String> properties) {
|
||||
return new LegacyTeamInfoNMS(properties);
|
||||
}
|
||||
|
||||
private abstract class AbstractTeamInfoNMS<C> extends TeamNMS.TeamInfoNMS<C> {
|
||||
|
||||
public AbstractTeamInfoNMS(ImmutableTeamProperties<C> properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTeam(Iterable<Player> players) {
|
||||
if (removePacket == null) {
|
||||
removePacket = new PacketPlayOutScoreboardTeam();
|
||||
UnsafeUtilities.setField(teamNameField, removePacket, teamName);
|
||||
UnsafeUtilities.UNSAFE.putInt(removePacket, UnsafeUtilities.UNSAFE.objectFieldOffset(teamModeField), MODE_REMOVE);
|
||||
}
|
||||
impl.sendPacket(players, removePacket);
|
||||
public void addEntries(Collection<Player> players, Collection<String> entries) {
|
||||
teamEntry(players, entries, MODE_ADD_ENTRIES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamNMS.TeamInfoNMS<Component> createTeamInfoNMS(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator) {
|
||||
return new AdventureTeamInfoNMS(properties, componentTranslator);
|
||||
public void removeEntries(Collection<Player> players, Collection<String> entries) {
|
||||
teamEntry(players, entries, MODE_REMOVE_ENTRIES);
|
||||
}
|
||||
|
||||
protected void teamEntry(Collection<Player> players, Collection<String> entries, int action) {
|
||||
PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam();
|
||||
UnsafeUtilities.setField(teamNameField, packet, teamName);
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(teamModeField), action);
|
||||
UnsafeUtilities.setField(teamEntriesField, packet, entries);
|
||||
impl.sendPacket(players, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamInfoNMS<String> createLegacyTeamInfoNMS(ImmutableTeamProperties<String> properties) {
|
||||
return new LegacyTeamInfoNMS(properties);
|
||||
public void createTeam(Collection<Player> players) {
|
||||
sendTeamPacket(false, players);
|
||||
}
|
||||
|
||||
private abstract class AbstractTeamInfoNMS<C> extends TeamNMS.TeamInfoNMS<C> {
|
||||
|
||||
public AbstractTeamInfoNMS(ImmutableTeamProperties<C> properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntries(Collection<Player> players, Collection<String> entries) {
|
||||
teamEntry(players, entries, MODE_ADD_ENTRIES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntries(Collection<Player> players, Collection<String> entries) {
|
||||
teamEntry(players, entries, MODE_REMOVE_ENTRIES);
|
||||
}
|
||||
|
||||
protected void teamEntry(Collection<Player> players, Collection<String> entries, int action) {
|
||||
PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam();
|
||||
UnsafeUtilities.setField(teamNameField, packet, teamName);
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(teamModeField), action);
|
||||
UnsafeUtilities.setField(teamEntriesField, packet, entries);
|
||||
impl.sendPacket(players, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTeam(Collection<Player> players) {
|
||||
sendTeamPacket(false, players);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTeam(Collection<Player> players) {
|
||||
sendTeamPacket(true, players);
|
||||
}
|
||||
|
||||
private void sendTeamPacket(boolean update, Collection<Player> players) {
|
||||
ScoreboardManagerNMS.sendLocalePackets(null, impl, players, locale -> {
|
||||
String displayName = limitLegacyText(toLegacy(properties.displayName(), locale), TeamNMS.LEGACY_CHARACTER_LIMIT);
|
||||
String prefix = limitLegacyText(toLegacy(properties.prefix(), locale), TeamNMS.LEGACY_CHARACTER_LIMIT);
|
||||
String suffix = limitLegacyText(toLegacy(properties.suffix(), locale), TeamNMS.LEGACY_CHARACTER_LIMIT);
|
||||
|
||||
PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam();
|
||||
UnsafeUtilities.setField(teamNameField, packet, teamName);
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(teamModeField), update ? MODE_UPDATE : MODE_CREATE);
|
||||
UnsafeUtilities.setField(teamDisplayNameField, packet, displayName);
|
||||
UnsafeUtilities.setField(teamPrefixField, packet, prefix);
|
||||
UnsafeUtilities.setField(teamSuffixField, packet, suffix);
|
||||
UnsafeUtilities.setField(teamNameTagVisibilityField, packet, properties.nameTagVisibility().key());
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(teamRulesField), properties.packOptions());
|
||||
if (!update) {
|
||||
UnsafeUtilities.setField(teamEntriesField, packet, properties.entries());
|
||||
}
|
||||
|
||||
return packet;
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract String toLegacy(C component, Locale locale);
|
||||
@Override
|
||||
public void updateTeam(Collection<Player> players) {
|
||||
sendTeamPacket(true, players);
|
||||
}
|
||||
|
||||
private class AdventureTeamInfoNMS extends AbstractTeamInfoNMS<Component> {
|
||||
private void sendTeamPacket(boolean update, Collection<Player> players) {
|
||||
ScoreboardManagerNMS.sendLocalePackets(null, impl, players, locale -> {
|
||||
String displayName = limitLegacyText(toLegacy(properties.displayName(), locale), TeamNMS.LEGACY_CHARACTER_LIMIT);
|
||||
String prefix = limitLegacyText(toLegacy(properties.prefix(), locale), TeamNMS.LEGACY_CHARACTER_LIMIT);
|
||||
String suffix = limitLegacyText(toLegacy(properties.suffix(), locale), TeamNMS.LEGACY_CHARACTER_LIMIT);
|
||||
|
||||
private final ComponentTranslator componentTranslator;
|
||||
|
||||
public AdventureTeamInfoNMS(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator) {
|
||||
super(properties);
|
||||
this.componentTranslator = componentTranslator;
|
||||
PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam();
|
||||
UnsafeUtilities.setField(teamNameField, packet, teamName);
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(teamModeField), update ? MODE_UPDATE : MODE_CREATE);
|
||||
UnsafeUtilities.setField(teamDisplayNameField, packet, displayName);
|
||||
UnsafeUtilities.setField(teamPrefixField, packet, prefix);
|
||||
UnsafeUtilities.setField(teamSuffixField, packet, suffix);
|
||||
UnsafeUtilities.setField(teamNameTagVisibilityField, packet, properties.nameTagVisibility().key());
|
||||
UnsafeUtilities.UNSAFE.putInt(packet, UnsafeUtilities.UNSAFE.objectFieldOffset(teamRulesField), properties.packOptions());
|
||||
if (!update) {
|
||||
UnsafeUtilities.setField(teamEntriesField, packet, properties.entries());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toLegacy(Component component, Locale locale) {
|
||||
return LegacyFormatUtil.serialize(componentTranslator, component, locale);
|
||||
}
|
||||
return packet;
|
||||
});
|
||||
}
|
||||
|
||||
private class LegacyTeamInfoNMS extends AbstractTeamInfoNMS<String> {
|
||||
protected abstract String toLegacy(C component, Locale locale);
|
||||
}
|
||||
|
||||
public LegacyTeamInfoNMS(ImmutableTeamProperties<String> properties) {
|
||||
super(properties);
|
||||
}
|
||||
private class AdventureTeamInfoNMS extends AbstractTeamInfoNMS<Component> {
|
||||
|
||||
@Override
|
||||
protected String toLegacy(String component, Locale locale) {
|
||||
return component;
|
||||
}
|
||||
private final ComponentTranslator componentTranslator;
|
||||
|
||||
public AdventureTeamInfoNMS(ImmutableTeamProperties<Component> properties, ComponentTranslator componentTranslator) {
|
||||
super(properties);
|
||||
this.componentTranslator = componentTranslator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toLegacy(Component component, Locale locale) {
|
||||
return LegacyFormatUtil.serialize(componentTranslator, component, locale);
|
||||
}
|
||||
}
|
||||
|
||||
private class LegacyTeamInfoNMS extends AbstractTeamInfoNMS<String> {
|
||||
|
||||
public LegacyTeamInfoNMS(ImmutableTeamProperties<String> properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toLegacy(String component, Locale locale) {
|
||||
return component;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user