This commit is contained in:
坏黑
2018-05-08 23:31:26 +08:00
parent 674e993105
commit 19d318a610
89 changed files with 4664 additions and 2410 deletions

View File

@@ -14,10 +14,11 @@ public class ExampleMain extends JavaPlugin {
public void onEnable() {
update.addListener(((oldVal, newVal) -> {
Bukkit.getLogger().info("配置项 enableUpdate 的值由 " + oldVal + " 变为了 " + newVal);
if (newVal)
if (newVal) {
Updater.start();
else
} else {
Updater.stop();
}
}));
}

View File

@@ -16,10 +16,11 @@ public class Property<T> {
public void set(T value) {
if (value != this.value) {
if (consumers != null)
if (consumers != null) {
for (BiConsumer<T, T> consumer : consumers) {
consumer.accept(this.value, value);
}
}
this.value = value;
}
}
@@ -29,8 +30,9 @@ public class Property<T> {
}
public void addListener(BiConsumer<T, T> consumer) {
if (consumers == null)
if (consumers == null) {
consumers = new ArrayList<>();
}
consumers.add(consumer);
}

View File

@@ -0,0 +1,180 @@
package com.ilummc.tlib.bungee.api;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* Simplistic enumeration of all supported color values for chat.
* @author md_5
*/
public enum ChatColor {
/**
* Represents black.
*/
BLACK('0', "black"),
/**
* Represents dark blue.
*/
DARK_BLUE('1', "dark_blue"),
/**
* Represents dark green.
*/
DARK_GREEN('2', "dark_green"),
/**
* Represents dark blue (aqua).
*/
DARK_AQUA('3', "dark_aqua"),
/**
* Represents dark red.
*/
DARK_RED('4', "dark_red"),
/**
* Represents dark purple.
*/
DARK_PURPLE('5', "dark_purple"),
/**
* Represents gold.
*/
GOLD('6', "gold"),
/**
* Represents gray.
*/
GRAY('7', "gray"),
/**
* Represents dark gray.
*/
DARK_GRAY('8', "dark_gray"),
/**
* Represents blue.
*/
BLUE('9', "blue"),
/**
* Represents green.
*/
GREEN('a', "green"),
/**
* Represents aqua.
*/
AQUA('b', "aqua"),
/**
* Represents red.
*/
RED('c', "red"),
/**
* Represents light purple.
*/
LIGHT_PURPLE('d', "light_purple"),
/**
* Represents yellow.
*/
YELLOW('e', "yellow"),
/**
* Represents white.
*/
WHITE('f', "white"),
/**
* Represents magical characters that change around randomly.
*/
MAGIC('k', "obfuscated"),
/**
* Makes the text bold.
*/
BOLD('l', "bold"),
/**
* Makes a line appear through the text.
*/
STRIKETHROUGH('m', "strikethrough"),
/**
* Makes the text appear underlined.
*/
UNDERLINE('n', "underline"),
/**
* Makes the text italic.
*/
ITALIC('o', "italic"),
/**
* Resets all previous chat colors or formats.
*/
RESET('r', "reset");
/**
* The special character which prefixes all chat colour codes. Use this if
* you need to dynamically convert colour codes from your custom format.
*/
public static final char COLOR_CHAR = '\u00A7';
public static final String ALL_CODES = "0123456789AaBbCcDdEeFfKkLlMmNnOoRr";
/**
* Pattern to remove all colour codes.
*/
public static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf(COLOR_CHAR) + "[0-9A-FK-OR]");
/**
* Colour instances keyed by their active character.
*/
private static final Map<Character, ChatColor> BY_CHAR = new HashMap<Character, ChatColor>();
/**
* The code appended to {@link #COLOR_CHAR} to make usable colour.
*/
private final char code;
/**
* This colour's colour char prefixed by the {@link #COLOR_CHAR}.
*/
private final String toString;
private final String name;
public String getName() {
return name;
}
static {
for (ChatColor colour : values()) {
BY_CHAR.put(colour.code, colour);
}
}
ChatColor(char code, String name) {
this.code = code;
this.name = name;
this.toString = new String(new char[]{COLOR_CHAR, code});
}
@Override
public String toString() {
return toString;
}
/**
* Strips the given message of all color codes
*
* @param input String to strip of color
* @return A copy of the input string, without any coloring
*/
public static String stripColor(final String input) {
if (input == null) {
return null;
}
return STRIP_COLOR_PATTERN.matcher(input).replaceAll("");
}
public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) {
char[] b = textToTranslate.toCharArray();
for (int i = 0; i < b.length - 1; i++) {
if (b[i] == altColorChar && ALL_CODES.indexOf(b[i + 1]) > -1) {
b[i] = ChatColor.COLOR_CHAR;
b[i + 1] = Character.toLowerCase(b[i + 1]);
}
}
return new String(b);
}
/**
* Get the colour represented by the specified code.
*
* @param code the code to search for
* @return the mapped colour, or null if non exists
*/
public static ChatColor getByChar(char code) {
return BY_CHAR.get(code);
}
}

View File

@@ -0,0 +1,12 @@
package com.ilummc.tlib.bungee.api;
/**
* Represents the position on the screen where a message will appear.
* @author md_5
*/
public enum ChatMessageType {
CHAT,
SYSTEM,
ACTION_BAR
}

View File

@@ -0,0 +1,493 @@
package com.ilummc.tlib.bungee.api.chat;
import com.ilummc.tlib.bungee.api.ChatColor;
import com.ilummc.tlib.bungee.api.chat.ComponentBuilder.FormatRetention;
import java.util.ArrayList;
import java.util.List;
/**
* @author md_5
*/
public abstract class BaseComponent {
BaseComponent parent;
/**
* The color of this component and any child components (unless overridden)
*/
private ChatColor color;
/**
* Whether this component and any child components (unless overridden) is
* bold
*/
private Boolean bold;
/**
* Whether this component and any child components (unless overridden) is
* italic
*/
private Boolean italic;
/**
* Whether this component and any child components (unless overridden) is
* underlined
*/
private Boolean underlined;
/**
* Whether this component and any child components (unless overridden) is
* strikethrough
*/
private Boolean strikethrough;
/**
* Whether this component and any child components (unless overridden) is
* obfuscated
*/
private Boolean obfuscated;
/**
* The text to insert into the chat when this component (and child
* components) are clicked while pressing the shift key
*/
private String insertion;
/**
* Appended components that inherit this component's formatting and events
*/
private List<BaseComponent> extra;
/**
* The action to perform when this component (and child components) are
* clicked
*/
private ClickEvent clickEvent;
/**
* The action to perform when this component (and child components) are
* hovered over
*/
private HoverEvent hoverEvent;
public String getInsertion() {
return insertion;
}
public List<BaseComponent> getExtra() {
return extra;
}
public ClickEvent getClickEvent() {
return clickEvent;
}
public HoverEvent getHoverEvent() {
return hoverEvent;
}
public void setParent(BaseComponent parent) {
this.parent = parent;
}
public void setColor(ChatColor color) {
this.color = color;
}
public void setBold(Boolean bold) {
this.bold = bold;
}
public void setItalic(Boolean italic) {
this.italic = italic;
}
public void setUnderlined(Boolean underlined) {
this.underlined = underlined;
}
public void setStrikethrough(Boolean strikethrough) {
this.strikethrough = strikethrough;
}
public void setObfuscated(Boolean obfuscated) {
this.obfuscated = obfuscated;
}
public void setInsertion(String insertion) {
this.insertion = insertion;
}
public void setClickEvent(ClickEvent clickEvent) {
this.clickEvent = clickEvent;
}
public void setHoverEvent(HoverEvent hoverEvent) {
this.hoverEvent = hoverEvent;
}
@Override
public String toString() {
return "parent=" + "BaseComponent{" + parent + ", color=" + color + ", bold=" + bold + ", italic=" + italic + ", underlined=" + underlined + ", strikethrough=" + strikethrough + ", obfuscated=" + obfuscated + ", insertion='" + insertion + '\'' + ", extra=" + extra + ", clickEvent=" + clickEvent + ", hoverEvent=" + hoverEvent + '}';
}
BaseComponent() {
}
BaseComponent(BaseComponent old) {
copyFormatting(old, FormatRetention.ALL, true);
if (old.getExtra() != null) {
for (BaseComponent extra : old.getExtra()) {
addExtra(extra.duplicate());
}
}
}
/**
* Copies the events and formatting of a BaseComponent. Already set
* formatting will be replaced.
*
* @param component the component to copy from
*/
public void copyFormatting(BaseComponent component) {
copyFormatting(component, FormatRetention.ALL, true);
}
/**
* Copies the events and formatting of a BaseComponent.
*
* @param component the component to copy from
* @param replace if already set formatting should be replaced by the new
* component
*/
public void copyFormatting(BaseComponent component, boolean replace) {
copyFormatting(component, FormatRetention.ALL, replace);
}
/**
* Copies the specified formatting of a BaseComponent.
*
* @param component the component to copy from
* @param retention the formatting to copy
* @param replace if already set formatting should be replaced by the new
* component
*/
public void copyFormatting(BaseComponent component, FormatRetention retention, boolean replace) {
if (retention == FormatRetention.EVENTS || retention == FormatRetention.ALL) {
if (replace || clickEvent == null) {
setClickEvent(component.getClickEvent());
}
if (replace || hoverEvent == null) {
setHoverEvent(component.getHoverEvent());
}
}
if (retention == FormatRetention.FORMATTING || retention == FormatRetention.ALL) {
if (replace || color == null) {
setColor(component.getColorRaw());
}
if (replace || bold == null) {
setBold(component.isBoldRaw());
}
if (replace || italic == null) {
setItalic(component.isItalicRaw());
}
if (replace || underlined == null) {
setUnderlined(component.isUnderlinedRaw());
}
if (replace || strikethrough == null) {
setStrikethrough(component.isStrikethroughRaw());
}
if (replace || obfuscated == null) {
setObfuscated(component.isObfuscatedRaw());
}
if (replace || insertion == null) {
setInsertion(component.getInsertion());
}
}
}
/**
* Retains only the specified formatting.
*
* @param retention the formatting to retain
*/
public void retain(FormatRetention retention) {
if (retention == FormatRetention.FORMATTING || retention == FormatRetention.NONE) {
setClickEvent(null);
setHoverEvent(null);
}
if (retention == FormatRetention.EVENTS || retention == FormatRetention.NONE) {
setColor(null);
setBold(null);
setItalic(null);
setUnderlined(null);
setStrikethrough(null);
setObfuscated(null);
setInsertion(null);
}
}
/**
* Clones the BaseComponent and returns the clone.
*
* @return The duplicate of this BaseComponent
*/
public abstract BaseComponent duplicate();
/**
* Clones the BaseComponent without formatting and returns the clone.
*
* @return The duplicate of this BaseComponent
* @deprecated API use discouraged, use traditional duplicate
*/
@Deprecated
public BaseComponent duplicateWithoutFormatting() {
BaseComponent component = duplicate();
component.retain(FormatRetention.NONE);
return component;
}
/**
* Converts the components to a string that uses the old formatting codes
* ({@link ChatColor#COLOR_CHAR}
*
* @param components the components to convert
* @return the string in the old format
*/
public static String toLegacyText(BaseComponent... components) {
StringBuilder builder = new StringBuilder();
for (BaseComponent msg : components) {
builder.append(msg.toLegacyText());
}
return builder.toString();
}
/**
* Converts the components into a string without any formatting
*
* @param components the components to convert
* @return the string as plain text
*/
public static String toPlainText(BaseComponent... components) {
StringBuilder builder = new StringBuilder();
for (BaseComponent msg : components) {
builder.append(msg.toPlainText());
}
return builder.toString();
}
/**
* Returns the color of this component. This uses the parent's color if this
* component doesn't have one. {@link ChatColor#WHITE}
* is returned if no color is found.
*
* @return the color of this component
*/
public ChatColor getColor() {
if (color == null) {
if (parent == null) {
return ChatColor.WHITE;
}
return parent.getColor();
}
return color;
}
/**
* Returns the color of this component without checking the parents color.
* May return null
*
* @return the color of this component
*/
public ChatColor getColorRaw() {
return color;
}
/**
* Returns whether this component is bold. This uses the parent's setting if
* this component hasn't been set. false is returned if none of the parent
* chain has been set.
*
* @return whether the component is bold
*/
public boolean isBold() {
if (bold == null) {
return parent != null && parent.isBold();
}
return bold;
}
/**
* Returns whether this component is bold without checking the parents
* setting. May return null
*
* @return whether the component is bold
*/
public Boolean isBoldRaw() {
return bold;
}
/**
* Returns whether this component is italic. This uses the parent's setting
* if this component hasn't been set. false is returned if none of the
* parent chain has been set.
*
* @return whether the component is italic
*/
public boolean isItalic() {
if (italic == null) {
return parent != null && parent.isItalic();
}
return italic;
}
/**
* Returns whether this component is italic without checking the parents
* setting. May return null
*
* @return whether the component is italic
*/
public Boolean isItalicRaw() {
return italic;
}
/**
* Returns whether this component is underlined. This uses the parent's
* setting if this component hasn't been set. false is returned if none of
* the parent chain has been set.
*
* @return whether the component is underlined
*/
public boolean isUnderlined() {
if (underlined == null) {
return parent != null && parent.isUnderlined();
}
return underlined;
}
/**
* Returns whether this component is underlined without checking the parents
* setting. May return null
*
* @return whether the component is underlined
*/
public Boolean isUnderlinedRaw() {
return underlined;
}
/**
* Returns whether this component is strikethrough. This uses the parent's
* setting if this component hasn't been set. false is returned if none of
* the parent chain has been set.
*
* @return whether the component is strikethrough
*/
public boolean isStrikethrough() {
if (strikethrough == null) {
return parent != null && parent.isStrikethrough();
}
return strikethrough;
}
/**
* Returns whether this component is strikethrough without checking the
* parents setting. May return null
*
* @return whether the component is strikethrough
*/
public Boolean isStrikethroughRaw() {
return strikethrough;
}
/**
* Returns whether this component is obfuscated. This uses the parent's
* setting if this component hasn't been set. false is returned if none of
* the parent chain has been set.
*
* @return whether the component is obfuscated
*/
public boolean isObfuscated() {
if (obfuscated == null) {
return parent != null && parent.isObfuscated();
}
return obfuscated;
}
/**
* Returns whether this component is obfuscated without checking the parents
* setting. May return null
*
* @return whether the component is obfuscated
*/
public Boolean isObfuscatedRaw() {
return obfuscated;
}
public void setExtra(List<BaseComponent> components) {
components.forEach(component -> component.parent = this);
extra = components;
}
/**
* Appends a text element to the component. The text will inherit this
* component's formatting
*
* @param text the text to append
*/
public void addExtra(String text) {
addExtra(new TextComponent(text));
}
/**
* Appends a component to the component. The text will inherit this
* component's formatting
*
* @param component the component to append
*/
public void addExtra(BaseComponent component) {
if (extra == null) {
extra = new ArrayList<>();
}
component.parent = this;
extra.add(component);
}
/**
* Returns whether the component has any formatting or events applied to it
*
* @return Whether any formatting or events are applied
*/
public boolean hasFormatting() {
return color != null || italic != null || bold != null || underlined != null || strikethrough != null || obfuscated != null || insertion != null || hoverEvent != null || clickEvent != null;
}
/**
* Converts the component into a string without any formatting
*
* @return the string as plain text
*/
public String toPlainText() {
StringBuilder builder = new StringBuilder();
toPlainText(builder);
return builder.toString();
}
void toPlainText(StringBuilder builder) {
if (extra != null) {
extra.forEach(e -> e.toPlainText(builder));
}
}
/**
* Converts the component to a string that uses the old formatting codes
* ({@link ChatColor#COLOR_CHAR}
*
* @return the string in the old format
*/
public String toLegacyText() {
StringBuilder builder = new StringBuilder();
toLegacyText(builder);
return builder.toString();
}
void toLegacyText(StringBuilder builder) {
if (extra != null) {
extra.forEach(e -> e.toLegacyText(builder));
}
}
}

View File

@@ -0,0 +1,61 @@
package com.ilummc.tlib.bungee.api.chat;
/**
* @author md_5
*/
public final class ClickEvent {
/**
* The type of action to perform on click
*/
private final Action action;
/**
* Depends on action
*
* @see Action
*/
private final String value;
public ClickEvent(Action action, String value) {
this.action = action;
this.value = value;
}
public Action getAction() {
return action;
}
public String getValue() {
return value;
}
public enum Action {
/**
* Open a url at the path given by
* {@link ClickEvent#value}
*/
OPEN_URL,
/**
* Open a file at the path given by
* {@link ClickEvent#value}
*/
OPEN_FILE,
/**
* Run the command given by
* {@link ClickEvent#value}
*/
RUN_COMMAND,
/**
* Inserts the string given by
* {@link ClickEvent#value} into the players
* text box
*/
SUGGEST_COMMAND,
/**
* Change to the page number given by
* {@link ClickEvent#value} in a book
*/
CHANGE_PAGE
}
}

View File

@@ -0,0 +1,311 @@
package com.ilummc.tlib.bungee.api.chat;
import com.google.common.base.Preconditions;
import com.ilummc.tlib.bungee.api.ChatColor;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* ComponentBuilder simplifies creating basic messages by allowing the use of a
* chainable builder.
* </p>
* <pre>
* new ComponentBuilder("Hello ").color(ChatColor.RED).
* append("World").color(ChatColor.BLUE). append("!").bold(true).create();
* </pre>
* <p>
* All methods (excluding {@link #append(String)} and {@link #create()} work on
* the last part appended to the builder, so in the example above "Hello " would
* be {@link ChatColor#RED} and "World" would be
* {@link ChatColor#BLUE} but "!" would be bold and
* {@link ChatColor#BLUE} because append copies the previous
* part's formatting
* </p>
*
* @author md_5
*/
public final class ComponentBuilder {
private BaseComponent current;
private final List<BaseComponent> parts = new ArrayList<>();
/**
* Creates a ComponentBuilder from the other given ComponentBuilder to clone
* it.
*
* @param original the original for the new ComponentBuilder.
*/
public ComponentBuilder(ComponentBuilder original) {
current = original.current.duplicate();
original.parts.stream().map(BaseComponent::duplicate).forEach(parts::add);
}
/**
* Creates a ComponentBuilder with the given text as the first part.
*
* @param text the first text element
*/
public ComponentBuilder(String text) {
current = new TextComponent(text);
}
/**
* Creates a ComponentBuilder with the given component as the first part.
*
* @param component the first component element
*/
public ComponentBuilder(BaseComponent component) {
current = component.duplicate();
}
/**
* Appends a component to the builder and makes it the current target for
* formatting. The component will have all the formatting from previous
* part.
*
* @param component the component to append
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(BaseComponent component) {
return append(component, FormatRetention.ALL);
}
/**
* Appends a component to the builder and makes it the current target for
* formatting. You can specify the amount of formatting retained from
* previous part.
*
* @param component the component to append
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(BaseComponent component, FormatRetention retention) {
parts.add(current);
BaseComponent previous = current;
current = component.duplicate();
current.copyFormatting(previous, retention, false);
return this;
}
/**
* Appends the components to the builder and makes the last element the
* current target for formatting. The components will have all the
* formatting from previous part.
*
* @param components the components to append
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(BaseComponent[] components) {
return append(components, FormatRetention.ALL);
}
/**
* Appends the components to the builder and makes the last element the
* current target for formatting. You can specify the amount of formatting
* retained from previous part.
*
* @param components the components to append
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(BaseComponent[] components, FormatRetention retention) {
Preconditions.checkArgument(components.length != 0, "No components to append");
BaseComponent previous = current;
for (BaseComponent component : components) {
parts.add(current);
current = component.duplicate();
current.copyFormatting(previous, retention, false);
}
return this;
}
/**
* Appends the text to the builder and makes it the current target for
* formatting. The text will have all the formatting from previous part.
*
* @param text the text to append
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(String text) {
return append(text, FormatRetention.ALL);
}
/**
* Appends the text to the builder and makes it the current target for
* formatting. You can specify the amount of formatting retained from
* previous part.
*
* @param text the text to append
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder append(String text, FormatRetention retention) {
parts.add(current);
BaseComponent old = current;
current = new TextComponent(text);
current.copyFormatting(old, retention, false);
return this;
}
/**
* Sets the color of the current part.
*
* @param color the new color
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder color(ChatColor color) {
current.setColor(color);
return this;
}
/**
* Sets whether the current part is bold.
*
* @param bold whether this part is bold
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder bold(boolean bold) {
current.setBold(bold);
return this;
}
/**
* Sets whether the current part is italic.
*
* @param italic whether this part is italic
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder italic(boolean italic) {
current.setItalic(italic);
return this;
}
/**
* Sets whether the current part is underlined.
*
* @param underlined whether this part is underlined
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder underlined(boolean underlined) {
current.setUnderlined(underlined);
return this;
}
/**
* Sets whether the current part is strikethrough.
*
* @param strikethrough whether this part is strikethrough
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder strikethrough(boolean strikethrough) {
current.setStrikethrough(strikethrough);
return this;
}
/**
* Sets whether the current part is obfuscated.
*
* @param obfuscated whether this part is obfuscated
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder obfuscated(boolean obfuscated) {
current.setObfuscated(obfuscated);
return this;
}
/**
* Sets the insertion text for the current part.
*
* @param insertion the insertion text
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder insertion(String insertion) {
current.setInsertion(insertion);
return this;
}
/**
* Sets the click event for the current part.
*
* @param clickEvent the click event
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder event(ClickEvent clickEvent) {
current.setClickEvent(clickEvent);
return this;
}
/**
* Sets the hover event for the current part.
*
* @param hoverEvent the hover event
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder event(HoverEvent hoverEvent) {
current.setHoverEvent(hoverEvent);
return this;
}
/**
* Sets the current part back to normal settings. Only text is kept.
*
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder reset() {
return retain(FormatRetention.NONE);
}
/**
* Retains only the specified formatting. Text is not modified.
*
* @param retention the formatting to retain
* @return this ComponentBuilder for chaining
*/
public ComponentBuilder retain(FormatRetention retention) {
current.retain(retention);
return this;
}
/**
* Returns the components needed to display the message created by this
* builder.
*
* @return the created components
*/
public BaseComponent[] create() {
BaseComponent[] result = parts.toArray(new BaseComponent[parts.size() + 1]);
result[parts.size()] = current;
return result;
}
public enum FormatRetention {
/**
* Specify that we do not want to retain anything from the previous
* component.
*/
NONE,
/**
* Specify that we want the formatting retained from the previous
* component.
*/
FORMATTING,
/**
* Specify that we want the events retained from the previous component.
*/
EVENTS,
/**
* Specify that we want to retain everything from the previous
* component.
*/
ALL
}
}

View File

@@ -0,0 +1,38 @@
package com.ilummc.tlib.bungee.api.chat;
import java.util.Arrays;
/**
* @author md_5
*/
public final class HoverEvent {
private final Action action;
private final BaseComponent[] value;
public HoverEvent(Action action, BaseComponent[] value) {
this.action = action;
this.value = value;
}
public Action getAction() {
return action;
}
public BaseComponent[] getValue() {
return value;
}
@Override
public String toString() {
return "action=" + "HoverEvent{" + action + ", value=" + Arrays.toString(value) + '}';
}
public enum Action {
SHOW_TEXT,
SHOW_ACHIEVEMENT,
SHOW_ITEM,
SHOW_ENTITY
}
}

View File

@@ -0,0 +1,184 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.ilummc.tlib.bungee.api.chat;
import com.ilummc.tlib.bungee.api.*;
import java.beans.ConstructorProperties;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author md_5
*/
public class TextComponent extends BaseComponent {
private static final Pattern url = Pattern.compile("^(?:(https?)://)?([-\\w_\\.]{2,}\\.[a-z]{2,4})(/\\S*)?$");
private String text;
public static BaseComponent[] fromLegacyText(String message) {
ArrayList<BaseComponent> components = new ArrayList();
StringBuilder builder = new StringBuilder();
TextComponent component = new TextComponent();
Matcher matcher = url.matcher(message);
for(int i = 0; i < message.length(); ++i) {
char c = message.charAt(i);
TextComponent old;
if (c == 167) {
++i;
c = message.charAt(i);
if (c >= 'A' && c <= 'Z') {
c = (char)(c + 32);
}
ChatColor format = ChatColor.getByChar(c);
if (format != null) {
if (builder.length() > 0) {
old = component;
component = new TextComponent(component);
old.setText(builder.toString());
builder = new StringBuilder();
components.add(old);
}
switch(format) {
case BOLD:
component.setBold(true);
break;
case ITALIC:
component.setItalic(true);
break;
case UNDERLINE:
component.setUnderlined(true);
break;
case STRIKETHROUGH:
component.setStrikethrough(true);
break;
case MAGIC:
component.setObfuscated(true);
break;
case RESET:
format = ChatColor.WHITE;
default:
component = new TextComponent();
component.setColor(format);
break;
}
}
} else {
int pos = message.indexOf(32, i);
if (pos == -1) {
pos = message.length();
}
if (matcher.region(i, pos).find()) {
if (builder.length() > 0) {
old = component;
component = new TextComponent(component);
old.setText(builder.toString());
builder = new StringBuilder();
components.add(old);
}
old = component;
component = new TextComponent(component);
String urlString = message.substring(i, pos);
component.setText(urlString);
component.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, urlString.startsWith("http") ? urlString : "http://" + urlString));
components.add(component);
i += pos - i - 1;
component = old;
} else {
builder.append(c);
}
}
}
if (builder.length() > 0) {
component.setText(builder.toString());
components.add(component);
}
if (components.isEmpty()) {
components.add(new TextComponent(""));
}
return components.toArray(new BaseComponent[0]);
}
public TextComponent() {
this.text = "";
}
public TextComponent(TextComponent textComponent) {
super(textComponent);
this.setText(textComponent.getText());
}
public TextComponent(BaseComponent... extras) {
this.setText("");
this.setExtra(new ArrayList(Arrays.asList(extras)));
}
@Override
public BaseComponent duplicate() {
return new TextComponent(this);
}
@Override
protected void toPlainText(StringBuilder builder) {
builder.append(this.text);
super.toPlainText(builder);
}
@Override
protected void toLegacyText(StringBuilder builder) {
builder.append(this.getColor());
if (this.isBold()) {
builder.append(ChatColor.BOLD);
}
if (this.isItalic()) {
builder.append(ChatColor.ITALIC);
}
if (this.isUnderlined()) {
builder.append(ChatColor.UNDERLINE);
}
if (this.isStrikethrough()) {
builder.append(ChatColor.STRIKETHROUGH);
}
if (this.isObfuscated()) {
builder.append(ChatColor.MAGIC);
}
builder.append(this.text);
super.toLegacyText(builder);
}
@Override
public String toString() {
return String.format("TextComponent{text=%s, %s}", this.text, super.toString());
}
public String getText() {
return this.text;
}
public void setText(String text) {
this.text = text;
}
@ConstructorProperties({"text"})
public TextComponent(String text) {
this.text = text;
}
}

View File

@@ -0,0 +1,242 @@
package com.ilummc.tlib.bungee.api.chat;
import com.ilummc.tlib.bungee.api.ChatColor;
import java.util.ArrayList;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* @author md_5
*/
public final class TranslatableComponent extends BaseComponent {
private final ResourceBundle locales = ResourceBundle.getBundle("mojang-translations/en_US");
private final Pattern format = Pattern.compile("%(?:(\\d+)\\$)?([A-Za-z%]|$)");
/**
* The key into the Minecraft locale files to use for the translation. The
* text depends on the client's locale setting. The console is always en_US
*/
private String translate;
/**
* The components to substitute into the translation
*/
private List<BaseComponent> with;
public ResourceBundle getLocales() {
return locales;
}
public Pattern getFormat() {
return format;
}
public String getTranslate() {
return translate;
}
public void setTranslate(String translate) {
this.translate = translate;
}
public List<BaseComponent> getWith() {
return with;
}
public TranslatableComponent() {
}
/**
* Creates a translatable component from the original to clone it.
*
* @param original the original for the new translatable component.
*/
public TranslatableComponent(TranslatableComponent original) {
super(original);
setTranslate(original.getTranslate());
if (original.getWith() != null) {
setWith(original.getWith().stream().map(BaseComponent::duplicate).collect(Collectors.toList()));
}
}
/**
* Creates a translatable component with the passed substitutions
*
* @param translate the translation key
* @param with the {@link java.lang.String}s and
* {@link BaseComponent}s to use into the
* translation
* @see #translate
* @see #setWith(java.util.List)
*/
public TranslatableComponent(String translate, Object... with) {
setTranslate(translate);
if (with != null && with.length != 0) {
List<BaseComponent> temp = new ArrayList<>();
for (Object w : with) {
if (w instanceof String) {
temp.add(new TextComponent((String) w));
} else {
temp.add((BaseComponent) w);
}
}
setWith(temp);
}
}
/**
* Creates a duplicate of this TranslatableComponent.
*
* @return the duplicate of this TranslatableComponent.
*/
@Override
public BaseComponent duplicate() {
return new TranslatableComponent(this);
}
@Override
public String toString() {
return "locales=" + "TranslatableComponent{" + locales + ", format=" + format + ", translate='" + translate + '\'' + ", with=" + with + '}';
}
/**
* Sets the translation substitutions to be used in this component. Removes
* any previously set substitutions
*
* @param components the components to substitute
*/
public void setWith(List<BaseComponent> components) {
components.forEach(component -> component.parent = this);
with = components;
}
/**
* Adds a text substitution to the component. The text will inherit this
* component's formatting
*
* @param text the text to substitute
*/
public void addWith(String text) {
addWith(new TextComponent(text));
}
/**
* Adds a component substitution to the component. The text will inherit
* this component's formatting
*
* @param component the component to substitute
*/
public void addWith(BaseComponent component) {
if (with == null) {
with = new ArrayList<>();
}
component.parent = this;
with.add(component);
}
@Override
protected void toPlainText(StringBuilder builder) {
String trans;
try {
trans = locales.getString(translate);
} catch (MissingResourceException ex) {
trans = translate;
}
Matcher matcher = format.matcher(trans);
int position = 0;
int i = 0;
while (matcher.find(position)) {
int pos = matcher.start();
if (pos != position) {
builder.append(trans, position, pos);
}
position = matcher.end();
String formatCode = matcher.group(2);
switch (formatCode.charAt(0)) {
case 's':
case 'd':
String withIndex = matcher.group(1);
with.get(withIndex != null ? Integer.parseInt(withIndex) - 1 : i++).toPlainText(builder);
break;
case '%':
builder.append('%');
break;
default:
break;
}
}
if (trans.length() != position) {
builder.append(trans, position, trans.length());
}
super.toPlainText(builder);
}
@Override
protected void toLegacyText(StringBuilder builder) {
String trans;
try {
trans = locales.getString(translate);
} catch (MissingResourceException e) {
trans = translate;
}
Matcher matcher = format.matcher(trans);
int position = 0;
int i = 0;
while (matcher.find(position)) {
int pos = matcher.start();
if (pos != position) {
addFormat(builder);
builder.append(trans, position, pos);
}
position = matcher.end();
String formatCode = matcher.group(2);
switch (formatCode.charAt(0)) {
case 's':
case 'd':
String withIndex = matcher.group(1);
with.get(withIndex != null ? Integer.parseInt(withIndex) - 1 : i++).toLegacyText(builder);
break;
case '%':
addFormat(builder);
builder.append('%');
break;
default:
break;
}
}
if (trans.length() != position) {
addFormat(builder);
builder.append(trans, position, trans.length());
}
super.toLegacyText(builder);
}
private void addFormat(StringBuilder builder) {
builder.append(getColor());
if (isBold()) {
builder.append(ChatColor.BOLD);
}
if (isItalic()) {
builder.append(ChatColor.ITALIC);
}
if (isUnderlined()) {
builder.append(ChatColor.UNDERLINE);
}
if (isStrikethrough()) {
builder.append(ChatColor.STRIKETHROUGH);
}
if (isObfuscated()) {
builder.append(ChatColor.MAGIC);
}
}
}

View File

@@ -0,0 +1,121 @@
package com.ilummc.tlib.bungee.chat;
import com.google.common.base.Preconditions;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.ilummc.tlib.bungee.api.ChatColor;
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
import com.ilummc.tlib.bungee.api.chat.ClickEvent;
import com.ilummc.tlib.bungee.api.chat.HoverEvent;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
/**
* @author md_5
*/
public class BaseComponentSerializer {
protected void deserialize(JsonObject object, BaseComponent component, JsonDeserializationContext context) {
if (object.has("color")) {
component.setColor(ChatColor.valueOf(object.get("color").getAsString().toUpperCase(Locale.ROOT)));
}
if (object.has("bold")) {
component.setBold(object.get("bold").getAsBoolean());
}
if (object.has("italic")) {
component.setItalic(object.get("italic").getAsBoolean());
}
if (object.has("underlined")) {
component.setUnderlined(object.get("underlined").getAsBoolean());
}
if (object.has("strikethrough")) {
component.setStrikethrough(object.get("strikethrough").getAsBoolean());
}
if (object.has("obfuscated")) {
component.setObfuscated(object.get("obfuscated").getAsBoolean());
}
if (object.has("insertion")) {
component.setInsertion(object.get("insertion").getAsString());
}
if (object.has("extra")) {
component.setExtra(Arrays.asList(context.<BaseComponent[]>deserialize(object.get("extra"), BaseComponent[].class)));
}
//Events
if (object.has("clickEvent")) {
JsonObject event = object.getAsJsonObject("clickEvent");
component.setClickEvent(new ClickEvent(
ClickEvent.Action.valueOf(event.get("action").getAsString().toUpperCase(Locale.ROOT)),
event.get("value").getAsString()));
}
if (object.has("hoverEvent")) {
JsonObject event = object.getAsJsonObject("hoverEvent");
BaseComponent[] res;
if (event.get("value").isJsonArray()) {
res = context.deserialize(event.get("value"), BaseComponent[].class);
} else {
res = new BaseComponent[]{context.deserialize(event.get("value"), BaseComponent.class)};
}
component.setHoverEvent(new HoverEvent(HoverEvent.Action.valueOf(event.get("action").getAsString().toUpperCase(Locale.ROOT)), res));
}
}
protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context) {
boolean first = false;
if (ComponentSerializer.serializedComponents.get() == null) {
first = true;
ComponentSerializer.serializedComponents.set(new HashSet<>());
}
try {
Preconditions.checkArgument(!ComponentSerializer.serializedComponents.get().contains(component), "Component loop");
ComponentSerializer.serializedComponents.get().add(component);
if (component.getColorRaw() != null) {
object.addProperty("color", component.getColorRaw().getName());
}
if (component.isBoldRaw() != null) {
object.addProperty("bold", component.isBoldRaw());
}
if (component.isItalicRaw() != null) {
object.addProperty("italic", component.isItalicRaw());
}
if (component.isUnderlinedRaw() != null) {
object.addProperty("underlined", component.isUnderlinedRaw());
}
if (component.isStrikethroughRaw() != null) {
object.addProperty("strikethrough", component.isStrikethroughRaw());
}
if (component.isObfuscatedRaw() != null) {
object.addProperty("obfuscated", component.isObfuscatedRaw());
}
if (component.getInsertion() != null) {
object.addProperty("insertion", component.getInsertion());
}
if (component.getExtra() != null) {
object.add("extra", context.serialize(component.getExtra()));
}
//Events
if (component.getClickEvent() != null) {
JsonObject clickEvent = new JsonObject();
clickEvent.addProperty("action", component.getClickEvent().getAction().toString().toLowerCase(Locale.ROOT));
clickEvent.addProperty("value", component.getClickEvent().getValue());
object.add("clickEvent", clickEvent);
}
if (component.getHoverEvent() != null) {
JsonObject hoverEvent = new JsonObject();
hoverEvent.addProperty("action", component.getHoverEvent().getAction().toString().toLowerCase(Locale.ROOT));
hoverEvent.add("value", context.serialize(component.getHoverEvent().getValue()));
object.add("hoverEvent", hoverEvent);
}
} finally {
ComponentSerializer.serializedComponents.get().remove(component);
if (first) {
ComponentSerializer.serializedComponents.set(null);
}
}
}
}

View File

@@ -0,0 +1,58 @@
package com.ilummc.tlib.bungee.chat;
import com.google.gson.*;
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
import com.ilummc.tlib.bungee.api.chat.TextComponent;
import com.ilummc.tlib.bungee.api.chat.TranslatableComponent;
import java.lang.reflect.Type;
import java.util.HashSet;
/**
* @author md_5
*/
public class ComponentSerializer implements JsonDeserializer<BaseComponent> {
private final static JsonParser JSON_PARSER = new JsonParser();
private final static Gson gson = new GsonBuilder().
registerTypeAdapter(BaseComponent.class, new ComponentSerializer()).
registerTypeAdapter(TextComponent.class, new TextComponentSerializer()).
registerTypeAdapter(TranslatableComponent.class, new TranslatableComponentSerializer()).
create();
public final static ThreadLocal<HashSet<BaseComponent>> serializedComponents = new ThreadLocal<>();
public static BaseComponent[] parse(String json) {
JsonElement jsonElement = JSON_PARSER.parse(json);
if (jsonElement.isJsonArray()) {
return gson.fromJson(jsonElement, BaseComponent[].class);
} else {
return new BaseComponent[]{gson.fromJson(jsonElement, BaseComponent.class)};
}
}
public static String toString(BaseComponent component) {
return gson.toJson(component);
}
public static String toString(BaseComponent... components) {
if (components.length == 1) {
return gson.toJson(components[0]);
} else {
return gson.toJson(new TextComponent(components));
}
}
@Override
public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonPrimitive()) {
return new TextComponent(json.getAsString());
}
JsonObject object = json.getAsJsonObject();
if (object.has("translate")) {
return context.deserialize(json, TranslatableComponent.class);
}
return context.deserialize(json, TextComponent.class);
}
}

View File

@@ -0,0 +1,47 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.ilummc.tlib.bungee.chat;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.ilummc.tlib.bungee.api.chat.*;
import java.lang.reflect.Type;
import java.util.List;
/**
* @author md_5
*/
public class TextComponentSerializer extends BaseComponentSerializer implements JsonSerializer<TextComponent>, JsonDeserializer<TextComponent> {
public TextComponentSerializer() {
}
@Override
public TextComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
TextComponent component = new TextComponent();
JsonObject object = json.getAsJsonObject();
this.deserialize(object, component, context);
component.setText(object.get("text").getAsString());
return component;
}
@Override
public JsonElement serialize(TextComponent src, Type typeOfSrc, JsonSerializationContext context) {
List<BaseComponent> extra = src.getExtra();
JsonObject object = new JsonObject();
if (src.hasFormatting() || extra != null && !extra.isEmpty()) {
this.serialize(object, src, context);
}
object.addProperty("text", src.getText());
return object;
}
}

View File

@@ -0,0 +1,46 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.ilummc.tlib.bungee.chat;
import com.google.gson.*;
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
import com.ilummc.tlib.bungee.api.chat.TranslatableComponent;
import java.lang.reflect.Type;
import java.util.Arrays;
/**
* @author md_5
*/
public class TranslatableComponentSerializer extends BaseComponentSerializer implements JsonSerializer<TranslatableComponent>, JsonDeserializer<TranslatableComponent> {
public TranslatableComponentSerializer() {
}
@Override
public TranslatableComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
TranslatableComponent component = new TranslatableComponent();
JsonObject object = json.getAsJsonObject();
this.deserialize(object, component, context);
component.setTranslate(object.get("translate").getAsString());
if (object.has("with")) {
component.setWith(Arrays.asList((BaseComponent[]) context.deserialize(object.get("with"), BaseComponent[].class)));
}
return component;
}
@Override
public JsonElement serialize(TranslatableComponent src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject object = new JsonObject();
this.serialize(object, src, context);
object.addProperty("translate", src.getTranslate());
if (src.getWith() != null) {
object.add("with", context.serialize(src.getWith()));
}
return object;
}
}

View File

@@ -11,9 +11,11 @@ public abstract class PlaceholderHook {
private static PlaceholderHook impl;
public static void init() {
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null)
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
impl = new PlaceholderImpl();
else impl = new AbstractImpl();
} else {
impl = new AbstractImpl();
}
}
public static String replace(CommandSender sender, String text) {

View File

@@ -55,7 +55,9 @@ public final class Pool extends ThreadPoolExecutor {
@Override
protected void afterExecute(Runnable r, Throwable t) {
if (t != null) Base.close();
if (t != null) {
Base.close();
}
}
}

View File

@@ -1,11 +1,11 @@
package com.ilummc.tlib.filter;
import org.bukkit.Bukkit;
import java.util.Arrays;
import java.util.logging.Filter;
import java.util.logging.LogRecord;
import org.bukkit.Bukkit;
/**
* @author Bkm016
* @since 2018-04-22
@@ -27,6 +27,9 @@ public class TLoggerFilter implements Filter {
}
return false;
}
else if (e.getMessage().contains("Enabled plugin with unregistered PluginClassLoader")) {
return false;
}
return true;
}
}

View File

@@ -55,10 +55,17 @@ public class TConfigInjector {
TConfig config = clazz.getAnnotation(TConfig.class);
Validate.notNull(config);
File file = new File(plugin.getDataFolder(), config.name());
if (!file.exists()) if (config.fromJar()) plugin.saveResource(config.name(), true);
else saveConfig(plugin, clazz.newInstance());
if (!file.exists()) {
if (config.fromJar()) {
plugin.saveResource(config.name(), true);
} else {
saveConfig(plugin, clazz.newInstance());
}
}
Object obj = unserialize(plugin, clazz);
if (config.readOnly()) saveConfig(plugin, obj);
if (config.readOnly()) {
saveConfig(plugin, obj);
}
return obj;
} catch (NullPointerException e) {
TLocale.Logger.warn("CONFIG.LOAD-FAIL-NO-ANNOTATION", plugin.toString(), clazz.getSimpleName());
@@ -75,7 +82,9 @@ public class TConfigInjector {
File file = new File(plugin.getDataFolder(), config.name());
Map<String, Object> map = ConfigUtils.confToMap(ConfigUtils.loadYaml(plugin, file));
Object obj = ConfigUtils.mapToObj(map, object);
if (config.readOnly()) saveConfig(plugin, obj);
if (config.readOnly()) {
saveConfig(plugin, obj);
}
} catch (NullPointerException e) {
TLocale.Logger.warn("CONFIG.LOAD-FAIL-NO-ANNOTATION", plugin.toString(), object.getClass().getSimpleName());
} catch (Exception e) {
@@ -124,7 +133,9 @@ public class TConfigInjector {
Map map = gson.fromJson(gson.toJson(object), HashMap.class);
YamlConfiguration configuration = (YamlConfiguration) ConfigUtils.mapToConf(map);
File target = new File(plugin.getDataFolder(), config.name());
if (!target.exists()) target.createNewFile();
if (!target.exists()) {
target.createNewFile();
}
byte[] arr = configuration.saveToString().getBytes(config.charset());
Files.write(arr, target);
}

View File

@@ -1,5 +1,6 @@
package com.ilummc.tlib.inject;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.commons.lang3.tuple.Triple;
import java.io.File;
@@ -10,12 +11,16 @@ import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
/**
* @author lzzelAliz
*/
public class TConfigWatcher {
private final ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
private final ScheduledExecutorService service = Executors.newScheduledThreadPool(1, new BasicThreadFactory.Builder().namingPattern("tconfig-watcher-schedule-pool-%d").daemon(true).build());
private final Map<WatchService, Triple<File, Object, Consumer<Object>>> map = new HashMap<>();
@@ -24,8 +29,9 @@ public class TConfigWatcher {
WatchKey key;
while ((key = service.poll()) != null) {
for (WatchEvent<?> watchEvent : key.pollEvents()) {
if (triple.getLeft().getName().equals(Objects.toString(watchEvent.context())))
if (triple.getLeft().getName().equals(Objects.toString(watchEvent.context()))) {
triple.getRight().accept(triple.getMiddle());
}
}
key.reset();
}

View File

@@ -96,8 +96,9 @@ public class TDependencyInjector {
if ((logger = field.getAnnotation(Logger.class)) != null) {
field.getType().asSubclass(com.ilummc.tlib.logger.TLogger.class);
com.ilummc.tlib.logger.TLogger tLogger = new com.ilummc.tlib.logger.TLogger(logger.value(), plugin, logger.level());
if (!field.isAccessible())
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.set(o, tLogger);
TLoggerManager.setDefaultLogger(plugin, tLogger);
}
@@ -111,8 +112,9 @@ public class TDependencyInjector {
try {
PluginInstance instance;
if ((instance = field.getAnnotation(PluginInstance.class)) != null) {
if (!field.isAccessible())
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.getType().asSubclass(JavaPlugin.class);
Plugin pl;
if ((pl = Bukkit.getPluginManager().getPlugin(instance.value())) == null) {
@@ -123,8 +125,9 @@ public class TDependencyInjector {
pl = Bukkit.getPluginManager().getPlugin(instance.value());
}
}
if (pl != null)
if (pl != null) {
field.set(o, pl);
}
}
} catch (Exception ignored) {
}

View File

@@ -104,7 +104,9 @@ public class TPluginManager implements PluginManager {
@Override
public void disablePlugins() {
for (Plugin plugin : getPlugins()) {
if (plugin != main) disablePlugin(plugin);
if (plugin != main) {
disablePlugin(plugin);
}
}
disablePlugin(main);
}

View File

@@ -42,38 +42,45 @@ public class TLogger {
}
public void verbose(String msg) {
if (level <= VERBOSE)
if (level <= VERBOSE) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", ChatColor.translateAlternateColorCodes('&', msg)));
}
}
public void finest(String msg) {
if (level <= FINEST)
if (level <= FINEST) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", ChatColor.translateAlternateColorCodes('&', msg)));
}
}
public void fine(String msg) {
if (level <= FINE)
if (level <= FINE) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", ChatColor.translateAlternateColorCodes('&', msg)));
}
}
public void info(String msg) {
if (level <= INFO)
if (level <= INFO) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", ChatColor.translateAlternateColorCodes('&', msg)));
}
}
public void warn(String msg) {
if (level <= WARN)
if (level <= WARN) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", "§6" + ChatColor.translateAlternateColorCodes('&', msg)));
}
}
public void error(String msg) {
if (level <= ERROR)
if (level <= ERROR) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", "§c" + ChatColor.translateAlternateColorCodes('&', msg)));
}
}
public void fatal(String msg) {
if (level <= FATAL)
if (level <= FATAL) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", "§4" + ChatColor.translateAlternateColorCodes('&', msg)));
}
}
public static TLogger getUnformatted(Plugin plugin) {

View File

@@ -47,8 +47,8 @@ public class TLocale {
try {
return asString(path, Ref.getCallerClassNotOptional(3), args);
} catch (Exception e) {
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getTLib().getInternalLanguage().getString("FETCH-LOCALE-ERROR"), path));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getTLib().getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.getMessage()));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("FETCH-LOCALE-ERROR"), path));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.getMessage()));
return "§4<" + path + "§4>";
}
}
@@ -57,8 +57,8 @@ public class TLocale {
try {
return asStringList(path, Ref.getCallerClassNotOptional(3), args);
} catch (Exception e) {
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getTLib().getInternalLanguage().getString("FETCH-LOCALE-ERROR"), path));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getTLib().getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.getMessage()));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("FETCH-LOCALE-ERROR"), path));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.getMessage()));
return Collections.singletonList("§4<" + path + "§4>");
}
}

View File

@@ -62,8 +62,8 @@ class TLocaleInstance {
}
});
} catch (Exception | Error e) {
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getTLib().getInternalLanguage().getString("SEND-LOCALE-ERROR"), path));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getTLib().getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.toString()));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("SEND-LOCALE-ERROR"), path));
TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("LOCALE-ERROR-REASON"), e.toString()));
e.printStackTrace();
}
}

View File

@@ -37,10 +37,12 @@ public class TLocaleLoader {
}
public static void sendTo(Plugin plugin, String path, CommandSender sender, String... args) {
if (Bukkit.isPrimaryThread())
Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender, args));
else synchronized (TLocaleLoader.class) {
if (Bukkit.isPrimaryThread()) {
Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender, args));
} else {
synchronized (TLocaleLoader.class) {
Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender, args));
}
}
}

View File

@@ -35,8 +35,9 @@ public class TLocaleActionBar implements TLocaleSendable, ConfigurationSerializa
@Override
public void sendTo(CommandSender sender, String... args) {
if (sender instanceof Player)
if (sender instanceof Player) {
ActionBar.sendActionBar(((Player) sender), replace(sender, text, args));
}
}
private String replace(CommandSender sender, String text, String[] args) {

View File

@@ -4,13 +4,13 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ilummc.tlib.TLib;
import com.ilummc.tlib.bungee.api.chat.*;
import com.ilummc.tlib.bungee.chat.ComponentSerializer;
import com.ilummc.tlib.compat.PlaceholderHook;
import com.ilummc.tlib.resources.TLocaleSendable;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.jsonformatter.JSONFormatter;
import net.md_5.bungee.api.chat.*;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
@@ -52,7 +52,9 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable {
List<BaseComponent> builder = template.length > index ? new ArrayList<>(Arrays.asList(TextComponent.fromLegacyText(template[index++]))) : new ArrayList<>();
while (matcher.find()) {
String replace = matcher.group();
if (replace.length() <= 2) continue;
if (replace.length() <= 2) {
continue;
}
replace = replace.substring(1, replace.length() - 1);
String[] split = replace.split("@");
String text = split.length > 1 ? split[0] : "";
@@ -73,7 +75,7 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable {
builder.addAll(Arrays.asList(component));
} else {
builder.addAll(Arrays.asList(TextComponent.fromLegacyText(text)));
TLib.getTLib().getLogger().warn(Strings.replaceWithOrder(TLib.getTLib().getInternalLanguage().getString("MISSING-ARGUMENT"), node));
TLib.getTLib().getLogger().warn(Strings.replaceWithOrder(TLib.getInternalLanguage().getString("MISSING-ARGUMENT"), node));
}
if (index < template.length) {
builder.addAll(Arrays.asList(TextComponent.fromLegacyText(template[index++])));

View File

@@ -37,11 +37,14 @@ public class Ref {
try {
// 特殊判断
if (clazz == TLib.class)
if (clazz == TLib.class) {
return Arrays.asList(clazz.getDeclaredFields());
}
List<Field> fields;
if ((fields = cachedFields.get(clazz.getName())) != null) return fields;
if ((fields = cachedFields.get(clazz.getName())) != null) {
return fields;
}
ClassReader classReader = new ClassReader(clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class"));
AsmAnalyser analyser = new AsmAnalyser(new ClassWriter(ClassWriter.COMPUTE_MAXS), excludeModifiers);
classReader.accept(analyser, ClassReader.SKIP_DEBUG);
@@ -52,7 +55,9 @@ public class Ref {
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toList());
if (cache) cachedFields.putIfAbsent(clazz.getName(), fields);
if (cache) {
cachedFields.putIfAbsent(clazz.getName(), fields);
}
return fields;
} catch (Exception | Error e) {
try {
@@ -80,9 +85,13 @@ public class Ref {
public static Optional<Field> getFieldBySerializedName(Class<?> clazz, String name) {
for (Field field : Ref.getDeclaredFields(clazz, 0, false)) {
if (field.isAnnotationPresent(SerializedName.class))
if (field.getAnnotation(SerializedName.class).value().equals(name)) return Optional.of(field);
else if (field.getName().equals(name)) return Optional.of(field);
if (field.isAnnotationPresent(SerializedName.class)) {
if (field.getAnnotation(SerializedName.class).value().equals(name)) {
return Optional.of(field);
} else if (field.getName().equals(name)) {
return Optional.of(field);
}
}
}
return Optional.empty();
}

View File

@@ -9,8 +9,10 @@ public class Strings {
* @param args 替换的参数
* @return 替换好的字符串
*/
public static String replaceWithOrder(String template, String... args) {
if (args.length == 0 || template.length() == 0) return template;
public static String replaceWithOrder(String template, Object... args) {
if (args.length == 0 || template.length() == 0) {
return template;
}
char[] arr = template.toCharArray();
StringBuilder stringBuilder = new StringBuilder(template.length());
for (int i = 0; i < arr.length; i++) {
@@ -19,8 +21,9 @@ public class Strings {
&& arr[Math.min(i + 2, arr.length - 1)] == '}') {
stringBuilder.append(args[arr[i + 1] - '0']);
i += 2;
} else
} else {
stringBuilder.append(arr[i]);
}
}
return stringBuilder.toString();
}

View File

@@ -20,8 +20,9 @@ public class AsmAnalyser extends ClassVisitor implements Opcodes {
@Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
if ((access & excludeModifier) == 0)
if ((access & excludeModifier) == 0) {
fields.add(name);
}
return super.visitField(access, name, descriptor, signature, value);
}

View File

@@ -68,11 +68,13 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
}
private String replace(String text) {
if (text != null)
if (text != null) {
return text.replace("net/minecraft/server/" + fromVer, "net/minecraft/server/" + toVer)
.replace("org/bukkit/craftbukkit/" + fromVer, "org/bukkit/craftbukkit/" + toVer)
.replace(prevName, newClassName.replace('.', '/'));
else return null;
} else {
return null;
}
}
private String[] replace(String[] text) {
@@ -81,7 +83,9 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
text[i] = replace(text[i]);
}
return text;
} else return null;
} else {
return null;
}
}
@Override
@@ -103,9 +107,11 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
@Override
public void visitLdcInsn(Object value) {
if (value instanceof String)
if (value instanceof String) {
super.visitLdcInsn(replace((String) value));
else super.visitLdcInsn(value);
} else {
super.visitLdcInsn(value);
}
}
@Override