diff --git a/.idea/dictionaries/csh20.xml b/.idea/dictionaries/csh20.xml index 0dc0321..5412187 100644 --- a/.idea/dictionaries/csh20.xml +++ b/.idea/dictionaries/csh20.xml @@ -3,6 +3,7 @@ autoload craftbukkit + ilummc mvdw papi sendable diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 97626ba..c0bce70 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,6 +1,7 @@ + \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 5434d67..b00594d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,13 +1,61 @@ # TabooLib -> 开发工具库 +> Bukkit 开发工具库 + +[![](http://ci.pcd.ac.cn/job/TabooLibDev/badge/icon)](http://ci.pcd.ac.cn/job/TabooLibDev) +[![](https://img.shields.io/github/downloads/Bkm016/TabooLib/total.svg)](https://github.com/Bkm016/TabooLib/releases) +[![](https://img.shields.io/github/release/Bkm016/TabooLib.svg)](https://github.com/Bkm016/TabooLib/tags) +[![](https://img.shields.io/github/stars/Bkm016/TabooLib.svg?style=flat-square&label=Stars)](https://github.com/Bkm016/TabooLib) +[![](https://jitpack.io/v/Bkm016/TabooLib.svg)](https://jitpack.io/#Bkm016/TabooLib) ## 目录 + +* [TLocale](tlocale.md) + +## 添加 TabooLib 为库 + +### Maven + +```xml + + + + jitpack.io + https://jitpack.io + + + + com.github.Bkm016 + TabooLib + JitPack版本 + + +``` + +### Gradle + +```groovy +repositories { + maven { url 'https://jitpack.io' } +} +dependencies { + compile 'com.github.Bkm016:TabooLib:JitPack版本' +} +``` + +### sbt + +```scala +resolvers += "jitpack" at "https://jitpack.io" +libraryDependencies += "com.github.Bkm016" % "TabooLib" % "JitPack版本" +``` + +在添加依赖后,你还需要在 `plugin.yml` 中添加 `softdepend` 或者 `depend` 才能享受到 TabooLib 的全部功能。 + --- **3.56** 版本开始 `com.sun.tools.jar` 不再和插件一起发布。 如果需要启用 *JavaShell* 功能请将 [com.sun.tools.jar](http://skymc.oss-cn-shanghai.aliyuncs.com/plugins/com.sun.tools.jar) 放入 *"TabooLib/JavaShell/lib"* 文件夹中。   --- -暂时停更,等待 dev 分支测试完成后合并。(2018-4-7) -感谢海螺(@IzzelAliz)大佬的指导和更新。 +**3.832** 版本后开源协议更改为 `MIT` \ No newline at end of file diff --git a/docs/_coverpage.md b/docs/_coverpage.md index 715639d..8150eb7 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -4,7 +4,7 @@ * TLocale 语言文本 API * 自动依赖下载 -* 注释 * N +* Annotation Development [GitHub](https://github.com/Bkm016/TabooLib/) [开始](#目录) \ No newline at end of file diff --git a/docs/_sidebar.md b/docs/_sidebar.md index e69de29..867e4f1 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -0,0 +1,7 @@ +* [TabooLib](README.md) +* [TLocale](tlocale.md) +* [TDependency](dependency.md) + +* 实用工具 Utilities + +* [Ref](ref.md) \ No newline at end of file diff --git a/docs/dependency.md b/docs/dependency.md index e69de29..1dce06a 100644 --- a/docs/dependency.md +++ b/docs/dependency.md @@ -0,0 +1,40 @@ +# TDependency + +几个简单的注解轻松使用第三方库 + +## 请求一个第三方库 + +你只需要在你的主类上加上 `@Dependency` 注解。 + +比如,假如你要用 Scala 或者 Kotlin,那么可以: + +```java +@Dependency(type = Dependency.Type.LIBRARY, maven = "org.scala-lang:scala-library:2.12.6") +@Dependency(type = Dependency.Type.LIBRARY, maven = "org.jetbrains.kotlin:kotlin-stdlib:1.2.31") +public class TestMain extends JavaPlugin { + // ... +} +``` + +然后这些第三方将在 `onEnable` 调用之前可用。如果需要更早可用,你需要在使用任意第三方库之前调用一次 `TDependencyInjector.inject(instance, instance)`, +`instance` 为你的插件主类实例。 + +## 使用自定义仓库的库 + +在 `@Dependency` 里加入 `mavenRepo` 即可,如 + +```java +@Dependency(type = Dependency.Type.LIBRARY, maven = "com.github.Bkm016:TabooLib:dev-SNAPSHOT", mavenRepo = "https://jitpack.io/") +public class TestMain extends JavaPlugin { + // ... +} +``` + +## 使用指定的 URL 的 jar 文件作为库 + +```java +@Dependency(type = Dependency.Type.LIBRARY, maven = "com.sun:tools:1.8.0_151", url = "http://skymc.oss-cn-shanghai.aliyuncs.com/plugins/com.sun.tools.jar") +public class TestMain extends JavaPlugin { + // ... +} +``` \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 76c9e42..eccbf45 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,54 +1,56 @@ - + - - Document - - - - - - - + + TabooLib 文档 + + + + -
Loading ...
- - - - - + + + + + + + + + diff --git a/docs/ref.md b/docs/ref.md index e69de29..f96bc9d 100644 --- a/docs/ref.md +++ b/docs/ref.md @@ -0,0 +1,15 @@ +`com.ilummc.tlib.util.Ref` + +## getDeclaredFields + +众所周知(~~啥你竟然不知道~~) `Class#getDeclaredFields` 方法在获取时,如果该类的某个字段的类不在 classpath 里面,那么就会抛出一个 `NoClassDefFoundError` 异常。 + +而在 Ref 类中的几个 getDeclaredFields 方法解决了这个问题:返回一个 `List` 实例,只包含在 classpath 中的类。 + +## getCallerClass + +众所周知(~~啥你竟然不知道~~) Oracle 正在对内部包比如 `sun.misc` 这样的包动手脚,并且这些包可能在未来的版本里被删除(我们的 `Unsafe` 已经没了)。 + +而某个 Reflection 类就很好用,特别是 `Reflection#getCallerClass(int)` 这个方法。于是 Ref 中的 getCallerClass 方法解决了这个问题:通过分析栈调用来获取 caller class,并且在 Reflection 这个类还存在的时候用原来的方法调用。 + +在某个方法中调用 Ref.getCallerClass(3) 会返回调用这个方法的类。 \ No newline at end of file diff --git a/docs/tlocale.md b/docs/tlocale.md index e69de29..bfc469d 100644 --- a/docs/tlocale.md +++ b/docs/tlocale.md @@ -0,0 +1,207 @@ +# TLocale + +通过简单的 yml 文件自定义你的所有信息 + +## 添加一个语言文件 + +TLocale 的语言文件是自动加载的,你可以在 TabooLib 初始化你的插件完毕后任意的调用来发送,前提是你在 `plugin.yml` 添加了 TabooLib 为 `depend` 或 `softdepend` + +语言文件应该放在 `/lang/xx_XX.yml` 中,TabooLib 默认会加载 `zh_CN` 和 `en_US` 的语言文件。 + +在添加了语言文件后,你就应该可以使用 `com.ilummc.tlib.resources.TLocale` 类的所有静态方法了。 + +在 `/TaabooLib/config.yml` 中有 `LOCALE` 下的几个选项可以设置加载的语言和是否默认启用 PlaceholderAPI + +## 发送一条消息 + +`/lang/zh_CN.yml` +```yaml +TEST: '{0} 加入服务器' +TITLE_TEST: + ==: TITLE + title: '&b{0} 加入了服务器' + subtitle: '&a{0} 太强了以至于他还有 subtitle 显示' +``` + +代码部分 +```java +package com.ilummc.tlib; + +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.event.player.PlayerJoinEvent; +import com.ilummc.tlib.resources.TLocale; + +public class ExampleMain extends JavaPlugin implements Listener { + + @Override + public void onEnable() { + Bukkit.getPluginManager().registerEvents(this, this); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + TLocale.sendTo(event.getPlayer(), "TEST", event.getPlayer().getName()); + TLocale.sendTo(event.getPlayer(), "TITLE_TEST", event.getPlayer().getName()); + } +} +``` + +## 语言文本格式 + +TLocale 的语言文本采用 yml 存储,每一个键对应一个或多个值、 + +以下的格式都是可以的: +```yaml +normal: '一条普通的测试信息' +multiline: |- + 多行的测试信息 + 这是 YAML 表示带有换行符字符串的方法 +typeMessage: + ==: TITLE + title: 这是带有类型的语言文本 + subtitle: 在下方你可以看到所有可用的类型 +combinedTypeMessage: + - ==: TEXT + text: + - '这也是一条普通的测试信息' + - '但是他有很多行' + - '还有可替换的文本 {0}' + - ==: ACTION + text: '一条 ActionBar 消息' + - ==: JSON + text: + - '这条消息仍然可以使用 TLocale.sendTo(sender, "combinedTypeMessage") 来发送' + - '玩家会收到一条聊天栏消息' + - '一条 ActionBar 的消息' + - '和一条 JSON 文本,比如<§a§n点击这里就会执行一条命令@cmd>' + args: + cmd: + hover: |- + 命令是 /tp ~ ~50 ~ + 这一条消息展示了 TLocale 的所有特性 + command: '/tp ~ ~50 ~' + - '最后,这个消息也能混着普通字符串用' +``` + +TLocale 可以发送普通的聊天消息和其他复杂的消息,比如 ActionBar 和 Title 消息。 + +为了方便起见,我们将如下的配置 +```yaml +==: 种类 +参数1: xxxx +参数2: yyyy +``` +称为一个 `语言对象`。 + +每个语言对象可以有以下几种排列方式: +```yaml +文本1: 语言对象 +文本2: + - 语言对象 + - 语言对象 +节点1: + 文本3: 语言对象 +``` + +TLocale 的文本都支持替换,如 `{N}` ,替换的文本是 `TLocale` 的方法调用时传入的对应字符串。 + +!> 因为写这个功能的人是程序员,所以 **N 从 0 开始** + +以下内容列举了所有的语言对象种类 + +### TEXT + +`TEXT` 类型代表一条普通的聊天栏文本,有以下几种表示方法: +```yaml +node1: '文本' +node2: + - '文本' + - '文本' +node3: + ==: TEXT + text: '文本' +node4: + ==: TEXT + text: + - '文本' + - 'Placeholder API 测试 %vault_eco_balance%' + papi: true +``` +你可以在任意一个 `TEXT` 中添加 `papi: true` 来启用对 PlaceholderAPI 的支持,如果不添加,默认值为 `/TaabooLib/config.yml` 中的 `LOCALE.USE_PAPI` 设置的值。 + +所有的选项都是**可选的** 。 + +### TITLE + +`TITLE` 类型代表一条 title 消息,可以含有淡入淡出的时间选项。所有的选项都是**可选的** 。 + +```yaml +node: + ==: TITLE + title: '显示在屏幕正中的 title 文本' + subtitle: 'subtitle 文本' + fadein: 10 + fadeout: 10 + stay: 20 + papi: false +``` + +### ACTION + +`ACTION` 类型代表一条 ActionBar 消息。所有的选项都是**可选的** 。 + +```yaml +node: + ==: ACTION + text: '&6ActionBar &e文本' + papi: false +``` + +### JSON + +`JSON` 类型代表一条可以点击和可以含有悬浮文字的消息。 + +消息的文本在 `text` 中指定。 + +可以点击、鼠标停留的文本需要使用 `<可选的文本@参数名称>` 来表示,然后在 `args` 参数中添加你指定的参数名称并添加点击和悬浮的文本。 + +全部 JSON 的任何地方都可以启用替换功能,包括内置的替换和 PAPI 。 + +所有的选项都是**可选的** 。 + +```yaml +node: + ==: JSON + text: + - '<点击建议命令@test1>' + - '<点击执行命令@test2>' + - '<鼠标停留查看悬浮字@test3>' + - '<@test4>' + - '<又可以点击又可以悬浮的信息@combined>' + - '替换测试1 {0}' + - '<@test6>' + papi: true + args: + test1: + suggest: '/say 建议执行的命令' + test2: + command: '/say 点击直接执行的命令' + test3: + hover: |- + &6鼠标悬浮显示的文字 + &9可以是单行,也可以是多行 + test4: + text: '你可以在参数中指定显示的文本,比如这一条' + test5: + command: '/say Hello World.' + hover: '点击说一句 &cHello World' + test6: + text: 'JSON 文本也有参数替换的功能,比如 {1}' + hover: |- + 悬浮字中也可以替换 {1} + 甚至可以加入 PAPI 变量如 %player_name% + command: '点击文本也可以替换,不做演示' +``` \ No newline at end of file diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java index b0863a1..8e32bed 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java @@ -6,6 +6,7 @@ import com.ilummc.tlib.nms.ActionBar; import com.ilummc.tlib.resources.TLocaleSendable; import com.ilummc.tlib.util.Strings; import me.skymc.taboolib.Main; +import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.SerializableAs; @@ -28,7 +29,7 @@ public class TLocaleActionBar implements TLocaleSendable, ConfigurationSerializa } public static TLocaleActionBar valueOf(Map map) { - String text = String.valueOf(map.getOrDefault("text", "Empty Action bar message.")); + String text = ChatColor.translateAlternateColorCodes('&', String.valueOf(map.getOrDefault("text", "Empty Action bar message."))); boolean papi = (boolean) map.getOrDefault("papi", Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false)); return new TLocaleActionBar(text, papi); } diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java index 82dbeac..58defe3 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java @@ -9,16 +9,14 @@ import com.ilummc.tlib.resources.TLocaleSendable; import com.ilummc.tlib.util.Strings; import me.skymc.taboolib.Main; import net.md_5.bungee.api.chat.*; +import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.entity.Player; import javax.annotation.concurrent.ThreadSafe; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -40,13 +38,16 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable { public static TLocaleJson valueOf(Map map) { Object textObj = map.getOrDefault("text", "Empty Node"); - List textList = textObj instanceof String ? Lists.newArrayList(((String) textObj)) : + List textList = textObj instanceof String ? Lists.newArrayList(ChatColor.translateAlternateColorCodes('&', (String) textObj)) : (textObj instanceof List && !((List) textObj).isEmpty()) ? - ((List) textObj).stream().map(Object::toString).collect(Collectors.toList()) : Lists.newArrayList(String.valueOf(textObj)); + ((List) textObj).stream().map(Object::toString) + .map(s -> ChatColor.translateAlternateColorCodes('&', s)) + .collect(Collectors.toList()) : Lists.newArrayList(String.valueOf(textObj)); boolean papi = (boolean) map.getOrDefault("papi", Main.getInst().getConfig().getBoolean("LOCALE.USE_PAPI", false)); Object argsObj = map.get("args"); if (argsObj instanceof Map) { - Map section = ((Map) argsObj); + Map section = new HashMap<>(((Map) argsObj).size()); + ((Map) argsObj).forEach((k, v) -> section.put(String.valueOf(k), v)); List collect = textList.stream().map(s -> { String[] template = pattern.split(s); int index = 0; @@ -65,7 +66,7 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable { if (section.containsKey(node)) { @SuppressWarnings("unchecked") Map arg = (Map) section.get(node); - text = (String) arg.getOrDefault("text", text); + text = ChatColor.translateAlternateColorCodes('&', String.valueOf(arg.getOrDefault("text", text))); BaseComponent[] component = TextComponent.fromLegacyText(text); arg.forEach((key, value) -> { switch (key) { @@ -81,7 +82,8 @@ public class TLocaleJson implements TLocaleSendable, ConfigurationSerializable { break; case "hover": for (BaseComponent baseComponent : component) { - baseComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(String.valueOf(value)).create())); + baseComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new ComponentBuilder(ChatColor.translateAlternateColorCodes('&', String.valueOf(value))).create())); } break; default: