diff --git a/.classpath b/.classpath index 237f831..864abc2 100644 --- a/.classpath +++ b/.classpath @@ -27,7 +27,7 @@ - + @@ -42,6 +42,11 @@ + + + + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 87bb602..2b18aa9 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,5 @@ # -#Thu Jun 06 20:38:13 CST 2019 +#Wed Jun 26 17:15:22 CST 2019 org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve diff --git a/build.gradle b/build.gradle index 58ccae3..66be6fe 100644 --- a/build.gradle +++ b/build.gradle @@ -30,6 +30,7 @@ repositories { dependencies { implementation 'com.github.nitu2003:TConfig:1.0' implementation 'com.github.nitu2003:SimpleDataStorage:1.2' + implementation 'com.github.nitu2003:T18n:1.1' implementation 'com.github.hydevelop:PicqBotX:4.10.1.928' implementation 'cn.hutool:hutool-all:4.5.10' implementation 'com.github.hydevelop:HyCommonUtils:1.3.5.130' @@ -41,6 +42,7 @@ shadowJar { dependencies { include(dependency("com.github.nitu2003:TConfig:1.0")) include(dependency("com.github.nitu2003:SimpleDataStorage:1.2")) + include(dependency("com.github.nitu2003:T18n:1.1")) include(dependency("commons-io:commons-io:2.4")) include(dependency("com.github.hydevelop:PicqBotX:4.10.1.928")) include(dependency("com.github.hydevelop:HyLogger:4.0.254")) diff --git a/src/main/java/ren/taske/nativebot/MinecraftPlugin.java b/src/main/java/ren/taske/nativebot/MinecraftPlugin.java index 8e96a06..daf6e07 100644 --- a/src/main/java/ren/taske/nativebot/MinecraftPlugin.java +++ b/src/main/java/ren/taske/nativebot/MinecraftPlugin.java @@ -1,17 +1,21 @@ package ren.taske.nativebot; +import java.util.logging.Logger; + import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.plugin.java.JavaPlugin; import cc.moecraft.icq.event.events.message.EventMessage; +import cn.glycol.t18n.I18n; import ren.taske.nativebot.bot.chatting.Chatting; import ren.taske.nativebot.bot.chatting.MinecraftMessage; import ren.taske.nativebot.bot.chatting.TencentMessage; import ren.taske.nativebot.core.NativeBot; +import ren.taske.nativebot.i18n.I18nInit; import ren.taske.nativebot.minecraft.command.CommandQQ; public class MinecraftPlugin extends JavaPlugin { - + protected final NativeBot nativebot = new NativeBot(this); protected final Chatting chatting = new Chatting(this); @@ -24,6 +28,10 @@ public class MinecraftPlugin extends JavaPlugin { public void onEnable() { nativebotJavaPlugin = this; + I18nInit.init(); + + getLogger().info(I18n.format("message.common.welcome")); + nativebot.onEnable(); getCommand("qq").setExecutor(cmdqq); @@ -53,4 +61,8 @@ public class MinecraftPlugin extends JavaPlugin { public static JavaPlugin nativebotJavaPlugin; + public static Logger logger() { + return nativebotJavaPlugin.getLogger(); + } + } diff --git a/src/main/java/ren/taske/nativebot/bot/command/CommandAbout.java b/src/main/java/ren/taske/nativebot/bot/command/CommandAbout.java index a72d41a..b848512 100644 --- a/src/main/java/ren/taske/nativebot/bot/command/CommandAbout.java +++ b/src/main/java/ren/taske/nativebot/bot/command/CommandAbout.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import cc.moecraft.icq.event.events.message.EventMessage; import cc.moecraft.icq.user.User; +import cn.glycol.t18n.I18n; import ren.taske.nativebot.util.MessageUtils; public class CommandAbout extends CommandBase { @@ -14,13 +15,20 @@ public class CommandAbout extends CommandBase { @Override public String execute(EventMessage evt, User user, long userid, String command, ArrayList args) { - return MessageUtils.retAt(userid, "Yes, sir!", - "(command with * requires OP_PERMISSION_NODE)", - "/about[/bot|/help] - show this notice", - "/op - query if you're operator", - "/op* [uid] - set user as operator", - "/perm* [uid] [node] - get the value of the node", - "/perm* [uid] [node] [true/false] - set the value of the node"); + return MessageUtils.retAt(userid, I18n.format("command.about.message").replace("$", "\n")); } +/* + +Yes, sir! +(command with * requires OP_PERMISSION_NODE) +/about[/bot|/help] - show this notice +/op - query if you're operator +/op* [uid] - set user as operator +/perm* [uid] [node] - get the value of the node +/perm* [uid] [node] [true/false] - set the value of the node +/console* [cmd] - to execute command as Console + +*/ + } diff --git a/src/main/java/ren/taske/nativebot/bot/command/CommandConsole.java b/src/main/java/ren/taske/nativebot/bot/command/CommandConsole.java index 67460b8..7f73ae8 100644 --- a/src/main/java/ren/taske/nativebot/bot/command/CommandConsole.java +++ b/src/main/java/ren/taske/nativebot/bot/command/CommandConsole.java @@ -9,6 +9,7 @@ import org.bukkit.command.CommandSender; import cc.moecraft.icq.event.events.message.EventMessage; import cc.moecraft.icq.user.User; +import cn.glycol.t18n.I18n; import ren.taske.nativebot.MinecraftPlugin; import ren.taske.nativebot.commons.Reference; @@ -24,12 +25,12 @@ public class CommandConsole extends CommandBase { String cmd = merge(args); Boolean flag = callSyncDispatch(Bukkit.getServer().getConsoleSender(), cmd); if(flag == null) { - return "Exception!"; + return I18n.format("command.common.exception"); } if(flag) { - message = "Done!"; + message = I18n.format("command.common.done"); } else { - message = "Fail!"; + message = I18n.format("command.common.fail"); } return message; } @@ -47,6 +48,7 @@ public class CommandConsole extends CommandBase { return Bukkit.getScheduler().callSyncMethod(MinecraftPlugin.nativebotJavaPlugin, new Callable() { @Override public Boolean call() throws Exception { + MinecraftPlugin.logger().info("[$] "+command); return Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), command); } }).get(); diff --git a/src/main/java/ren/taske/nativebot/bot/command/CommandOperator.java b/src/main/java/ren/taske/nativebot/bot/command/CommandOperator.java index 5c8fa5e..1a151e6 100644 --- a/src/main/java/ren/taske/nativebot/bot/command/CommandOperator.java +++ b/src/main/java/ren/taske/nativebot/bot/command/CommandOperator.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import cc.moecraft.icq.event.events.message.EventMessage; import cc.moecraft.icq.user.User; +import cn.glycol.t18n.I18n; import ren.taske.data.util.ParseUtil; import ren.taske.nativebot.core.profile.UserTencent; import ren.taske.nativebot.util.MessageLib; @@ -25,7 +26,11 @@ public class CommandOperator extends CommandBase { /* Mode: check */ if(args.size() == 0) { boolean perm = u.hasPermission(OP_PERM_NODE); - message = "You're "+(perm?"an operator!":"not an operator"); + if(perm) { + message = I18n.format("command.operator.yeap"); + } else { + message = I18n.format("command.operator.nope"); + } } /* Mode: set */ @@ -38,13 +43,13 @@ public class CommandOperator extends CommandBase { // Check if has OP_PERM_NODE if(u2.hasPermission(OP_PERM_NODE)) { u2.setPermission(OP_PERM_NODE, false); - message = "["+uid+"] now is NOT operator!"; + message = I18n.format("command.operator.change.nope", uid); } else { u2.setPermission(OP_PERM_NODE, true); - message = "["+uid+"] now is operator!"; + message = I18n.format("command.operator.change.yeap", uid); } } else { - message = "NumberFormatException!"; + message = I18n.format("command.common.exception.math"); } } else { // Unauthorized diff --git a/src/main/java/ren/taske/nativebot/bot/command/CommandPermission.java b/src/main/java/ren/taske/nativebot/bot/command/CommandPermission.java index 1dd37ed..9ce5376 100644 --- a/src/main/java/ren/taske/nativebot/bot/command/CommandPermission.java +++ b/src/main/java/ren/taske/nativebot/bot/command/CommandPermission.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import cc.moecraft.icq.event.events.message.EventMessage; import cc.moecraft.icq.user.User; +import cn.glycol.t18n.I18n; import ren.taske.data.util.ParseUtil; import ren.taske.nativebot.bot.permission.PermissionManager; import ren.taske.nativebot.commons.Reference; @@ -20,40 +21,41 @@ public class CommandPermission extends CommandBase { public String execute(EventMessage evt, User user, long userid, String command, ArrayList args) { String message = ""; if(args.size() < 2) { - message = "Wrong Arguments!"; + message = I18n.format("command.common.argument"); } if(args.size() >= 2) { String username = args.get(0); String nodename = args.get(1); - Long uid = ParseUtil.parseLong(username); + Long uid; + + if(username.equals("*")) { + uid = userid; + } else { + uid = ParseUtil.parseLong(username); + } if(uid != null) { - UserTencent u = UserTencent.of(userid); + UserTencent u = UserTencent.of(uid); + boolean exists = PermissionManager.has(nodename); - if(args.size() == 2) { - boolean exists = PermissionManager.has(nodename); - if(exists) { - message = nodename + " = " + u.hasPermission(nodename); - } else { - message = nodename + " is NOT registered!"; + if(exists) { + if(args.size() == 2) { + message = I18n.format("command.permission.query", u.getUserId(), nodename, u.hasPermission(nodename)); } - } - - if(args.size() > 2) { - boolean value = ParseUtil.parseBoolean(args.get(2)); - u.setPermission(nodename, value); - StringBuffer sb = new StringBuffer(); - sb.append(nodename).append("(").append(uid).append(")"); - sb.append(" set to ").append(value); - - message = sb.toString(); + if(args.size() > 2) { + boolean value = ParseUtil.parseBoolean(args.get(2)); + u.setPermission(nodename, value); + message = I18n.format("command.permission.set", u.getUserId(), nodename, value); + } + } else { + message = I18n.format("command.permission.unregistered"); } } else { - message = "NumberFormatException!"; + message = I18n.format("command.common.exception.math"); } } diff --git a/src/main/java/ren/taske/nativebot/bot/permission/Permission.java b/src/main/java/ren/taske/nativebot/bot/permission/Permission.java index a4e8cf2..ab73a4c 100644 --- a/src/main/java/ren/taske/nativebot/bot/permission/Permission.java +++ b/src/main/java/ren/taske/nativebot/bot/permission/Permission.java @@ -22,6 +22,11 @@ public class Permission { this.def = def; } + /** + * null, if locked and un-registered + * @param name + * @return + */ public static Permission of(String name) { return of(name, false); } diff --git a/src/main/java/ren/taske/nativebot/bot/permission/PermissionManager.java b/src/main/java/ren/taske/nativebot/bot/permission/PermissionManager.java index ab77d88..ed6299c 100644 --- a/src/main/java/ren/taske/nativebot/bot/permission/PermissionManager.java +++ b/src/main/java/ren/taske/nativebot/bot/permission/PermissionManager.java @@ -5,14 +5,26 @@ import ren.taske.nativebot.commons.Reference; public class PermissionManager { + /** + * 注册一个权限节点 + * @return 是否成功 + */ public static boolean add(String node) { return add(node, false); } + /** + * 注册一个权限节点 + * @param def 默认值 + * @return 是否成功 + */ public static boolean add(String node, boolean def) { return !(Permission.of(node, def) == null); } + /** + * 检测权限节点是否存在 + */ public static boolean has(String node) { return !(Permission.of(node) == null); } diff --git a/src/main/java/ren/taske/nativebot/commons/Config.java b/src/main/java/ren/taske/nativebot/commons/Config.java index 7b95ca7..ec53e04 100644 --- a/src/main/java/ren/taske/nativebot/commons/Config.java +++ b/src/main/java/ren/taske/nativebot/commons/Config.java @@ -21,6 +21,9 @@ public class Config { public static long group_id; public static String[] chatting_prefixes; + // I18n Settings + public static boolean useJarLanguageFile; + public static void refresh() { port_in = cfg.getInt("in", "constructor", 25560, 0, 65535, "The port for receiving messages"); @@ -31,6 +34,8 @@ public class Config { group_id = cfg.get("chatting", "group", "139971220").getLong(0L); chatting_prefixes = cfg.getStringList("prefixes", "chatting", new String[] {"!", "\uff01"}, "The prefixes of chatting"); + useJarLanguageFile = cfg.getBoolean("lang_refresh", "lang", false, "True if want use the language file in jar"); + cfg.save(); } diff --git a/src/main/java/ren/taske/nativebot/commons/Reference.java b/src/main/java/ren/taske/nativebot/commons/Reference.java index 70678d8..18cce53 100644 --- a/src/main/java/ren/taske/nativebot/commons/Reference.java +++ b/src/main/java/ren/taske/nativebot/commons/Reference.java @@ -10,6 +10,8 @@ public class Reference { public static final File FILE_CONFIGURATION = new File(DATA_FOLDER+"/config.cfg"); + public static final File FILE_I18N = new File(DATA_FOLDER+"/i18n.txt"); + public static File getTencentProfile(long userid) { return new File(DATA_FOLDER+"/tencent/"+userid+".profile"); } diff --git a/src/main/java/ren/taske/nativebot/core/profile/UserTencent.java b/src/main/java/ren/taske/nativebot/core/profile/UserTencent.java index 23f2fe4..ddf4954 100644 --- a/src/main/java/ren/taske/nativebot/core/profile/UserTencent.java +++ b/src/main/java/ren/taske/nativebot/core/profile/UserTencent.java @@ -4,6 +4,7 @@ import java.util.HashMap; import ren.taske.data.SimpleDataStorage; import ren.taske.nativebot.bot.permission.Permission; +import ren.taske.nativebot.bot.permission.PermissionManager; import ren.taske.nativebot.commons.Reference; public class UserTencent extends User { @@ -12,6 +13,7 @@ public class UserTencent extends User { protected final SimpleDataStorage data; + /** 错误的用户,用于给 UserMinecraft 提供未绑定的用户 */ public static final UserTencent NONE = new UserTencent(-1L) { @Override public boolean hasPermission(String node) { @@ -62,8 +64,10 @@ public class UserTencent extends User { } public void setPermission(String node, boolean val) { - data.setBoolean(node, val); - data.save(); + if(PermissionManager.has(node)) { + data.setBoolean(node, val); + data.save(); + } } } diff --git a/src/main/java/ren/taske/nativebot/i18n/I18nInit.java b/src/main/java/ren/taske/nativebot/i18n/I18nInit.java new file mode 100644 index 0000000..36a7ee9 --- /dev/null +++ b/src/main/java/ren/taske/nativebot/i18n/I18nInit.java @@ -0,0 +1,78 @@ +package ren.taske.nativebot.i18n; + +import static ren.taske.nativebot.commons.Reference.FILE_I18N; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.List; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +import com.google.common.collect.Lists; + +import cn.glycol.t18n.I18n; +import cn.glycol.t18n.LanguageMap; +import cn.glycol.t18n.LanguageMapBuilder; +import cn.hutool.core.io.file.FileWriter; +import ren.taske.nativebot.commons.Config; + +public class I18nInit { + + private static final Logger LOGGER = LogManager.getLogManager().getLogger("NativeBot-I18nInit"); + + private static final Charset CHARSET = Charset.forName("utf-8"); + + public static void init() { + + if(!FILE_I18N.exists() || Config.useJarLanguageFile) { + writeContextToFile(getContextFromJar()); + } + + LanguageMap lm = LanguageMapBuilder.fromFile(FILE_I18N); + I18n.setLanguageMap(lm); + + } + + /** 从 Jar 里提取文件,文件是根目录的i18n.txt */ + static List getContextFromJar() { + + InputStream is = I18nInit.class.getResourceAsStream("/i18n.txt"); + BufferedReader br = new BufferedReader(new InputStreamReader(is, CHARSET)); + + String cache = ""; + List context = Lists.newArrayList(); + + while(true) { + try { + if((cache = br.readLine()) == null) { + break; + } else { + context.add(cache); + } + } catch(IOException e) { + + } + } + + return context; + + } + + /** 将文件写入到配置文件夹 */ + static void writeContextToFile(List context) { + + FileWriter fw = FileWriter.create(FILE_I18N, CHARSET); + + try { + fw.writeLines(context); + } catch(Exception e) { + LOGGER.warning("Unable to write i18n to file!"); + LOGGER.warning(e.getMessage()); + } + + } + +} diff --git a/src/main/java/ren/taske/nativebot/util/MessageLib.java b/src/main/java/ren/taske/nativebot/util/MessageLib.java index 8aa91e1..dfc18d0 100644 --- a/src/main/java/ren/taske/nativebot/util/MessageLib.java +++ b/src/main/java/ren/taske/nativebot/util/MessageLib.java @@ -1,12 +1,14 @@ package ren.taske.nativebot.util; +import cn.glycol.t18n.I18n; + public class MessageLib { public static final String _NEWLINE = "\n"; - public static final String _UNAUTHORIZED = "You have no permission!"; + /** 自动合成一个无权限回复 */ public static String getUnauthorizedMessage(Object user) { - return MessageUtils.at(user)+_NEWLINE+_UNAUTHORIZED; + return MessageUtils.at(user)+_NEWLINE+I18n.format("command.common.unauthorized"); } } diff --git a/src/main/resources/i18n.txt b/src/main/resources/i18n.txt new file mode 100644 index 0000000..9fb4c90 --- /dev/null +++ b/src/main/resources/i18n.txt @@ -0,0 +1,29 @@ +message.common.welcome=欢迎使用! + +command.common.done=完成! +command.common.fail=失败! +command.common.argument=参数错误! +command.common.exception=错误! +command.common.exception.math=数字转换错误(NumberFormatException)! +command.common.unauthorized=无权执行! + +# '$' as new line +# Yes, sir! +# (command with * requires OP_PERMISSION_NODE) +# /about[/bot|/help] - show this notice +# /op - query if you're operator +# /op* [uid] - set user as operator +# /perm* [uid] [node] - get the value of the node +# /perm* [uid] [node] [true/false] - set the value of the node +# /console* [cmd] - to execute command as Console +command.about.message=Yes, sir!$(command with * requires OP_PERMISSION_NODE)$/about[/bot|/help] - show this notice$/op - query if you're operator$/op* [uid] - set user as operator$/perm* [uid] [node] - get the value of the node$/perm* [uid] [node] [true/false] - set the value of the node$/console* [cmd] - to execute command as Console + +command.operator.yeap=您是管理员! +command.operator.nope=您不是管理员! +command.operator.change.yeap=[%s]现在是管理员了! +command.operator.change.nope=[%s]现在不是管理员了! + +command.permission.query=[%s]的%s权限状态为%s。 +command.permission.set=成功设置[%s]的%s权限状态为%s。 +command.permission.unregistered=莫得这种权限,你在抓梦jio? +