r1.0发布啦!

1. 添加本地化支持
2. 修复 /perm 制定用户错误
3. 修复 UserTencent 不识别是否注册直接设置权限
4. 给 PermissionManager 加上了注解
This commit is contained in:
Taskeren 2019-06-26 23:32:23 +08:00
parent a3b81d4344
commit 7d5bcaa80f
16 changed files with 214 additions and 41 deletions

View File

@ -27,7 +27,7 @@
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/> <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/> <classpathentry kind="output" path="bin/default"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry sourcepath="C:/Users/Taskeren/.gradle/caches/modules-2/files-2.1/org.spigotmc/spigot-api/1.14.2-R0.1-SNAPSHOT/d4294c4d6776c74dd2334485c5034e482e08335c/spigot-api-1.14.2-R0.1-SNAPSHOT-sources.jar" kind="lib" path="C:/Users/Taskeren/.gradle/caches/modules-2/files-2.1/org.spigotmc/spigot-api/1.14.2-R0.1-SNAPSHOT/9510ee9e311b943f158fc720d7a50820b59a6fa1/spigot-api-1.14.2-R0.1-SNAPSHOT.jar"> <classpathentry sourcepath="C:/Users/Taskeren/.gradle/caches/modules-2/files-2.1/org.spigotmc/spigot-api/1.14.2-R0.1-SNAPSHOT/cccf9ead0e83de2bc2cc6c8a1ece9a76570ced0c/spigot-api-1.14.2-R0.1-SNAPSHOT-sources.jar" kind="lib" path="C:/Users/Taskeren/.gradle/caches/modules-2/files-2.1/org.spigotmc/spigot-api/1.14.2-R0.1-SNAPSHOT/c3e1b7c24c243bd4c1564c68a174e9a6d201a8e3/spigot-api-1.14.2-R0.1-SNAPSHOT.jar">
<attributes> <attributes>
<attribute name="gradle_used_by_scope" value=""/> <attribute name="gradle_used_by_scope" value=""/>
</attributes> </attributes>
@ -42,6 +42,11 @@
<attribute name="gradle_used_by_scope" value="main,test"/> <attribute name="gradle_used_by_scope" value="main,test"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry sourcepath="C:/Users/Taskeren/.gradle/caches/modules-2/files-2.1/com.github.nitu2003/T18n/1.1/3159ef858efdfa1afcf25e076ecf8579439d2979/T18n-1.1-sources.jar" kind="lib" path="C:/Users/Taskeren/.gradle/caches/modules-2/files-2.1/com.github.nitu2003/T18n/1.1/8dd2ca39a45a83f7c3061e7ede473a29987d63b8/T18n-1.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry sourcepath="C:/Users/Taskeren/.gradle/caches/modules-2/files-2.1/com.github.hydevelop/PicqBotX/4.10.1.928/25057cc91492b72d5642b1a5dd6ad99ed14e7fe9/PicqBotX-4.10.1.928-sources.jar" kind="lib" path="C:/Users/Taskeren/.gradle/caches/modules-2/files-2.1/com.github.hydevelop/PicqBotX/4.10.1.928/d1bc697e081dd129f1a82b6351fd9c7e2aa9a7a6/PicqBotX-4.10.1.928.jar"> <classpathentry sourcepath="C:/Users/Taskeren/.gradle/caches/modules-2/files-2.1/com.github.hydevelop/PicqBotX/4.10.1.928/25057cc91492b72d5642b1a5dd6ad99ed14e7fe9/PicqBotX-4.10.1.928-sources.jar" kind="lib" path="C:/Users/Taskeren/.gradle/caches/modules-2/files-2.1/com.github.hydevelop/PicqBotX/4.10.1.928/d1bc697e081dd129f1a82b6351fd9c7e2aa9a7a6/PicqBotX-4.10.1.928.jar">
<attributes> <attributes>
<attribute name="gradle_used_by_scope" value="main,test"/> <attribute name="gradle_used_by_scope" value="main,test"/>

View File

@ -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.debug.localVariable=generate
org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve

View File

@ -30,6 +30,7 @@ repositories {
dependencies { dependencies {
implementation 'com.github.nitu2003:TConfig:1.0' implementation 'com.github.nitu2003:TConfig:1.0'
implementation 'com.github.nitu2003:SimpleDataStorage:1.2' implementation 'com.github.nitu2003:SimpleDataStorage:1.2'
implementation 'com.github.nitu2003:T18n:1.1'
implementation 'com.github.hydevelop:PicqBotX:4.10.1.928' implementation 'com.github.hydevelop:PicqBotX:4.10.1.928'
implementation 'cn.hutool:hutool-all:4.5.10' implementation 'cn.hutool:hutool-all:4.5.10'
implementation 'com.github.hydevelop:HyCommonUtils:1.3.5.130' implementation 'com.github.hydevelop:HyCommonUtils:1.3.5.130'
@ -41,6 +42,7 @@ shadowJar {
dependencies { dependencies {
include(dependency("com.github.nitu2003:TConfig:1.0")) include(dependency("com.github.nitu2003:TConfig:1.0"))
include(dependency("com.github.nitu2003:SimpleDataStorage:1.2")) 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("commons-io:commons-io:2.4"))
include(dependency("com.github.hydevelop:PicqBotX:4.10.1.928")) include(dependency("com.github.hydevelop:PicqBotX:4.10.1.928"))
include(dependency("com.github.hydevelop:HyLogger:4.0.254")) include(dependency("com.github.hydevelop:HyLogger:4.0.254"))

View File

@ -1,13 +1,17 @@
package ren.taske.nativebot; package ren.taske.nativebot;
import java.util.logging.Logger;
import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import cc.moecraft.icq.event.events.message.EventMessage; 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.Chatting;
import ren.taske.nativebot.bot.chatting.MinecraftMessage; import ren.taske.nativebot.bot.chatting.MinecraftMessage;
import ren.taske.nativebot.bot.chatting.TencentMessage; import ren.taske.nativebot.bot.chatting.TencentMessage;
import ren.taske.nativebot.core.NativeBot; import ren.taske.nativebot.core.NativeBot;
import ren.taske.nativebot.i18n.I18nInit;
import ren.taske.nativebot.minecraft.command.CommandQQ; import ren.taske.nativebot.minecraft.command.CommandQQ;
public class MinecraftPlugin extends JavaPlugin { public class MinecraftPlugin extends JavaPlugin {
@ -24,6 +28,10 @@ public class MinecraftPlugin extends JavaPlugin {
public void onEnable() { public void onEnable() {
nativebotJavaPlugin = this; nativebotJavaPlugin = this;
I18nInit.init();
getLogger().info(I18n.format("message.common.welcome"));
nativebot.onEnable(); nativebot.onEnable();
getCommand("qq").setExecutor(cmdqq); getCommand("qq").setExecutor(cmdqq);
@ -53,4 +61,8 @@ public class MinecraftPlugin extends JavaPlugin {
public static JavaPlugin nativebotJavaPlugin; public static JavaPlugin nativebotJavaPlugin;
public static Logger logger() {
return nativebotJavaPlugin.getLogger();
}
} }

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import cc.moecraft.icq.event.events.message.EventMessage; import cc.moecraft.icq.event.events.message.EventMessage;
import cc.moecraft.icq.user.User; import cc.moecraft.icq.user.User;
import cn.glycol.t18n.I18n;
import ren.taske.nativebot.util.MessageUtils; import ren.taske.nativebot.util.MessageUtils;
public class CommandAbout extends CommandBase { public class CommandAbout extends CommandBase {
@ -14,13 +15,20 @@ public class CommandAbout extends CommandBase {
@Override @Override
public String execute(EventMessage evt, User user, long userid, String command, ArrayList<String> args) { public String execute(EventMessage evt, User user, long userid, String command, ArrayList<String> args) {
return MessageUtils.retAt(userid, "Yes, sir!", return MessageUtils.retAt(userid, I18n.format("command.about.message").replace("$", "\n"));
"(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");
} }
/*
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
*/
} }

View File

@ -9,6 +9,7 @@ import org.bukkit.command.CommandSender;
import cc.moecraft.icq.event.events.message.EventMessage; import cc.moecraft.icq.event.events.message.EventMessage;
import cc.moecraft.icq.user.User; import cc.moecraft.icq.user.User;
import cn.glycol.t18n.I18n;
import ren.taske.nativebot.MinecraftPlugin; import ren.taske.nativebot.MinecraftPlugin;
import ren.taske.nativebot.commons.Reference; import ren.taske.nativebot.commons.Reference;
@ -24,12 +25,12 @@ public class CommandConsole extends CommandBase {
String cmd = merge(args); String cmd = merge(args);
Boolean flag = callSyncDispatch(Bukkit.getServer().getConsoleSender(), cmd); Boolean flag = callSyncDispatch(Bukkit.getServer().getConsoleSender(), cmd);
if(flag == null) { if(flag == null) {
return "Exception!"; return I18n.format("command.common.exception");
} }
if(flag) { if(flag) {
message = "Done!"; message = I18n.format("command.common.done");
} else { } else {
message = "Fail!"; message = I18n.format("command.common.fail");
} }
return message; return message;
} }
@ -47,6 +48,7 @@ public class CommandConsole extends CommandBase {
return Bukkit.getScheduler().callSyncMethod(MinecraftPlugin.nativebotJavaPlugin, new Callable<Boolean>() { return Bukkit.getScheduler().callSyncMethod(MinecraftPlugin.nativebotJavaPlugin, new Callable<Boolean>() {
@Override @Override
public Boolean call() throws Exception { public Boolean call() throws Exception {
MinecraftPlugin.logger().info("[$] "+command);
return Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), command); return Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), command);
} }
}).get(); }).get();

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import cc.moecraft.icq.event.events.message.EventMessage; import cc.moecraft.icq.event.events.message.EventMessage;
import cc.moecraft.icq.user.User; import cc.moecraft.icq.user.User;
import cn.glycol.t18n.I18n;
import ren.taske.data.util.ParseUtil; import ren.taske.data.util.ParseUtil;
import ren.taske.nativebot.core.profile.UserTencent; import ren.taske.nativebot.core.profile.UserTencent;
import ren.taske.nativebot.util.MessageLib; import ren.taske.nativebot.util.MessageLib;
@ -25,7 +26,11 @@ public class CommandOperator extends CommandBase {
/* Mode: check */ /* Mode: check */
if(args.size() == 0) { if(args.size() == 0) {
boolean perm = u.hasPermission(OP_PERM_NODE); 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 */ /* Mode: set */
@ -38,13 +43,13 @@ public class CommandOperator extends CommandBase {
// Check if has OP_PERM_NODE // Check if has OP_PERM_NODE
if(u2.hasPermission(OP_PERM_NODE)) { if(u2.hasPermission(OP_PERM_NODE)) {
u2.setPermission(OP_PERM_NODE, false); u2.setPermission(OP_PERM_NODE, false);
message = "["+uid+"] now is NOT operator!"; message = I18n.format("command.operator.change.nope", uid);
} else { } else {
u2.setPermission(OP_PERM_NODE, true); u2.setPermission(OP_PERM_NODE, true);
message = "["+uid+"] now is operator!"; message = I18n.format("command.operator.change.yeap", uid);
} }
} else { } else {
message = "NumberFormatException!"; message = I18n.format("command.common.exception.math");
} }
} else { } else {
// Unauthorized // Unauthorized

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import cc.moecraft.icq.event.events.message.EventMessage; import cc.moecraft.icq.event.events.message.EventMessage;
import cc.moecraft.icq.user.User; import cc.moecraft.icq.user.User;
import cn.glycol.t18n.I18n;
import ren.taske.data.util.ParseUtil; import ren.taske.data.util.ParseUtil;
import ren.taske.nativebot.bot.permission.PermissionManager; import ren.taske.nativebot.bot.permission.PermissionManager;
import ren.taske.nativebot.commons.Reference; 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<String> args) { public String execute(EventMessage evt, User user, long userid, String command, ArrayList<String> args) {
String message = ""; String message = "";
if(args.size() < 2) { if(args.size() < 2) {
message = "Wrong Arguments!"; message = I18n.format("command.common.argument");
} }
if(args.size() >= 2) { if(args.size() >= 2) {
String username = args.get(0); String username = args.get(0);
String nodename = args.get(1); 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) { if(uid != null) {
UserTencent u = UserTencent.of(userid); UserTencent u = UserTencent.of(uid);
if(args.size() == 2) {
boolean exists = PermissionManager.has(nodename); boolean exists = PermissionManager.has(nodename);
if(exists) { if(exists) {
message = nodename + " = " + u.hasPermission(nodename); if(args.size() == 2) {
} else { message = I18n.format("command.permission.query", u.getUserId(), nodename, u.hasPermission(nodename));
message = nodename + " is NOT registered!";
}
} }
if(args.size() > 2) { if(args.size() > 2) {
boolean value = ParseUtil.parseBoolean(args.get(2)); boolean value = ParseUtil.parseBoolean(args.get(2));
u.setPermission(nodename, value); u.setPermission(nodename, value);
message = I18n.format("command.permission.set", u.getUserId(), nodename, value);
StringBuffer sb = new StringBuffer(); }
sb.append(nodename).append("(").append(uid).append(")"); } else {
sb.append(" set to ").append(value); message = I18n.format("command.permission.unregistered");
message = sb.toString();
} }
} else { } else {
message = "NumberFormatException!"; message = I18n.format("command.common.exception.math");
} }
} }

View File

@ -22,6 +22,11 @@ public class Permission {
this.def = def; this.def = def;
} }
/**
* <code>null</code>, if locked and un-registered
* @param name
* @return
*/
public static Permission of(String name) { public static Permission of(String name) {
return of(name, false); return of(name, false);
} }

View File

@ -5,14 +5,26 @@ import ren.taske.nativebot.commons.Reference;
public class PermissionManager { public class PermissionManager {
/**
* 注册一个权限节点
* @return 是否成功
*/
public static boolean add(String node) { public static boolean add(String node) {
return add(node, false); return add(node, false);
} }
/**
* 注册一个权限节点
* @param def 默认值
* @return 是否成功
*/
public static boolean add(String node, boolean def) { public static boolean add(String node, boolean def) {
return !(Permission.of(node, def) == null); return !(Permission.of(node, def) == null);
} }
/**
* 检测权限节点是否存在
*/
public static boolean has(String node) { public static boolean has(String node) {
return !(Permission.of(node) == null); return !(Permission.of(node) == null);
} }

View File

@ -21,6 +21,9 @@ public class Config {
public static long group_id; public static long group_id;
public static String[] chatting_prefixes; public static String[] chatting_prefixes;
// I18n Settings
public static boolean useJarLanguageFile;
public static void refresh() { public static void refresh() {
port_in = cfg.getInt("in", "constructor", 25560, 0, 65535, "The port for receiving messages"); 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); group_id = cfg.get("chatting", "group", "139971220").getLong(0L);
chatting_prefixes = cfg.getStringList("prefixes", "chatting", new String[] {"!", "\uff01"}, "The prefixes of chatting"); 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(); cfg.save();
} }

View File

@ -10,6 +10,8 @@ public class Reference {
public static final File FILE_CONFIGURATION = new File(DATA_FOLDER+"/config.cfg"); 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) { public static File getTencentProfile(long userid) {
return new File(DATA_FOLDER+"/tencent/"+userid+".profile"); return new File(DATA_FOLDER+"/tencent/"+userid+".profile");
} }

View File

@ -4,6 +4,7 @@ import java.util.HashMap;
import ren.taske.data.SimpleDataStorage; import ren.taske.data.SimpleDataStorage;
import ren.taske.nativebot.bot.permission.Permission; import ren.taske.nativebot.bot.permission.Permission;
import ren.taske.nativebot.bot.permission.PermissionManager;
import ren.taske.nativebot.commons.Reference; import ren.taske.nativebot.commons.Reference;
public class UserTencent extends User { public class UserTencent extends User {
@ -12,6 +13,7 @@ public class UserTencent extends User {
protected final SimpleDataStorage data; protected final SimpleDataStorage data;
/** 错误的用户,用于给 UserMinecraft 提供未绑定的用户 */
public static final UserTencent NONE = new UserTencent(-1L) { public static final UserTencent NONE = new UserTencent(-1L) {
@Override @Override
public boolean hasPermission(String node) { public boolean hasPermission(String node) {
@ -62,8 +64,10 @@ public class UserTencent extends User {
} }
public void setPermission(String node, boolean val) { public void setPermission(String node, boolean val) {
if(PermissionManager.has(node)) {
data.setBoolean(node, val); data.setBoolean(node, val);
data.save(); data.save();
} }
}
} }

View File

@ -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<String> getContextFromJar() {
InputStream is = I18nInit.class.getResourceAsStream("/i18n.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is, CHARSET));
String cache = "";
List<String> 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<String> 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());
}
}
}

View File

@ -1,12 +1,14 @@
package ren.taske.nativebot.util; package ren.taske.nativebot.util;
import cn.glycol.t18n.I18n;
public class MessageLib { public class MessageLib {
public static final String _NEWLINE = "\n"; public static final String _NEWLINE = "\n";
public static final String _UNAUTHORIZED = "You have no permission!"; /** 自动合成一个无权限回复 */
public static String getUnauthorizedMessage(Object user) { public static String getUnauthorizedMessage(Object user) {
return MessageUtils.at(user)+_NEWLINE+_UNAUTHORIZED; return MessageUtils.at(user)+_NEWLINE+I18n.format("command.common.unauthorized");
} }
} }

View File

@ -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