feat: 完善BukkitDev的搜索和下载功能

Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
502647092 2016-07-19 12:53:32 +08:00
parent 340718446b
commit e1b72c1b60
4 changed files with 226 additions and 27 deletions

View File

@ -417,6 +417,18 @@ public class YumAPI {
} }
/** /**
* 更新或安装插件
*
* @param sender
* 命令发送者
*/
public static void upgrade(final CommandSender sender) {
plugman.upgrade(sender);
}
/**
* 更新或安装指定插件
*
* @param sender * @param sender
* 命令发送者 * 命令发送者
* @param plugin * @param plugin

View File

@ -1,5 +1,7 @@
package pw.yumc.Yum.commands; package pw.yumc.Yum.commands;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -16,17 +18,21 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import cn.citycraft.PluginHelper.callback.CallBack.One;
import cn.citycraft.PluginHelper.commands.HandlerCommand; import cn.citycraft.PluginHelper.commands.HandlerCommand;
import cn.citycraft.PluginHelper.commands.HandlerCommands; import cn.citycraft.PluginHelper.commands.HandlerCommands;
import cn.citycraft.PluginHelper.commands.InvokeCommandEvent; import cn.citycraft.PluginHelper.commands.InvokeCommandEvent;
import cn.citycraft.PluginHelper.commands.InvokeSubCommand; import cn.citycraft.PluginHelper.commands.InvokeSubCommand;
import cn.citycraft.PluginHelper.jsonresult.JsonHandle; import cn.citycraft.PluginHelper.kit.PluginKit;
import cn.citycraft.PluginHelper.kit.ZipKit;
import cn.citycraft.PluginHelper.tellraw.FancyMessage;
import cn.citycraft.PluginHelper.utils.IOUtil; import cn.citycraft.PluginHelper.utils.IOUtil;
import cn.citycraft.PluginHelper.utils.StrKit; import cn.citycraft.PluginHelper.utils.StrKit;
import pw.yumc.Yum.Yum; import pw.yumc.Yum.Yum;
import pw.yumc.Yum.api.YumAPI; import pw.yumc.Yum.api.YumAPI;
import pw.yumc.Yum.managers.ConfigManager; import pw.yumc.Yum.managers.ConfigManager;
import pw.yumc.Yum.models.BukkitDev; import pw.yumc.Yum.models.BukkitDev;
import pw.yumc.Yum.models.BukkitDev.Files;
import pw.yumc.Yum.models.BukkitDev.Projects; import pw.yumc.Yum.models.BukkitDev.Projects;
import pw.yumc.Yum.models.RepoSerialization.Repositories; import pw.yumc.Yum.models.RepoSerialization.Repositories;
@ -39,8 +45,27 @@ import pw.yumc.Yum.models.RepoSerialization.Repositories;
public class YumCommand implements HandlerCommands, Listener { public class YumCommand implements HandlerCommands, Listener {
private final String prefix = "§6[§bYum §a插件管理§6] "; private final String prefix = "§6[§bYum §a插件管理§6] ";
private final String not_found_from_bukkit = prefix + "§c未在BukkitDev搜索到 %s 的相关插件!"; private final String not_found_from_bukkit = prefix + "§c未在BukkitDev搜索到 %s 的相关插件!";
private final String bukkitlistprefix = " §6插件名称 §d发布类型"; private final String not_found_id_from_bukkit = prefix + "§c未在BukkitDev搜索到ID为 %s 的相关插件!";
private final String bukkitlist = "§6- §b&s §d%s";
private final String searchlimit = prefix + "§c为保证搜索速度和准确性 关键词必须大于 3 个字符!";
private final String searching = prefix + "§a正在从BukkitDev获取 §b%s §a的相关数据...";
private final String result = prefix + "§6关键词 §b%s §6的搜索结果如下:";
private final String bukkitlistprefix = " §6插件ID §3插件名称 §d发布类型 §a操作";
private final String bukkitlist = "§6- §e%-6s §b%-25s §d%-10s";
private final String fsearching = prefix + "§a正在从BukkitDev获取ID §b%s §a的文件列表...";
private final String filelistprefix = " §6插件名称 §3游戏版本 §d发布类型 §a操作";
private final String filelist = "§6- §b%-20s §3%-15s §d%-10s";
private final String look = "§6查看";
private final String install = "§a安装";
private final String update = "§a更新";
private final String unload = "§d卸载";
private final String reload = "§6重载";
private final String delete = "§c删除";
private final String unzip_error = prefix + "ZIP文件解压错误!";
Yum main; Yum main;
public YumCommand(final Yum yum) { public YumCommand(final Yum yum) {
@ -52,6 +77,58 @@ public class YumCommand implements HandlerCommands, Listener {
cmdhandler.registerCommands(PluginTabComplete.instence); cmdhandler.registerCommands(PluginTabComplete.instence);
} }
@HandlerCommand(name = "bukkitrepo", aliases = "br", minimumArguments = 2, description = "从BukkitDev查看安装插件", possibleArguments = "<操作符> <项目ID|项目名称> [地址]")
public void bukkitrepo(final InvokeCommandEvent e) {
final String[] args = e.getArgs();
final CommandSender sender = e.getSender();
PluginKit.runTaskAsync(new Runnable() {
@Override
public void run() {
final String id = args[1];
switch (args[0]) {
case "look":
sender.sendMessage(String.format(fsearching, id));
final List<Files> lf = Files.parseList(IOUtil.getData(String.format(BukkitDev.PLUGIN, id)));
if (lf.isEmpty()) {
sender.sendMessage(String.format(not_found_id_from_bukkit, id));
}
sender.sendMessage(filelistprefix);
for (int i = 0; i < lf.size() || i < 8; i++) {
final Files f = lf.get(i);
final FancyMessage fm = FancyMessage.newFM();
fm.text(String.format(filelist, f.name, f.gameVersion, f.releaseType));
fm.then(" ");
fm.then(install).command(String.format("yum br install %s %s", f.name, f.downloadUrl));
fm.send(sender);
}
break;
case "install":
if (args.length < 3) {
return;
}
final String url = args[2];
final File file = new File(Bukkit.getUpdateFolderFile(), YumAPI.getDownload().getFileName(url));
YumAPI.getDownload().run(e.getSender(), url, file, new One<File>() {
@Override
public void run(final File file) {
if (file.getName().endsWith(".zip")) {
try {
ZipKit.unzip(file, Bukkit.getUpdateFolderFile(), ".jar");
} catch (final IOException e) {
sender.sendMessage(unzip_error);
}
}
YumAPI.upgrade(sender);
}
});
break;
default:
break;
}
}
});
}
@HandlerCommand(name = "delete", aliases = { "del" }, minimumArguments = 1, description = "删除插件", possibleArguments = "<插件名称>") @HandlerCommand(name = "delete", aliases = { "del" }, minimumArguments = 1, description = "删除插件", possibleArguments = "<插件名称>")
public void delete(final InvokeCommandEvent e) { public void delete(final InvokeCommandEvent e) {
final String pluginname = e.getArgs()[0]; final String pluginname = e.getArgs()[0];
@ -167,7 +244,16 @@ public class YumCommand implements HandlerCommands, Listener {
final CommandSender sender = e.getSender(); final CommandSender sender = e.getSender();
sender.sendMessage("§6[Yum仓库]§3服务器已安装插件: "); sender.sendMessage("§6[Yum仓库]§3服务器已安装插件: ");
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) { for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
sender.sendMessage("§6- " + YumAPI.getPlugman().getFormattedName(plugin, true)); final String pname = plugin.getName();
final FancyMessage fm = FancyMessage.newFM();
fm.text(String.format("§6- %-25s", YumAPI.getPlugman().getFormattedName(plugin, true)));
fm.then(" ");
fm.then(update).command("yum u " + pname);
fm.then(" ");
fm.then(unload).command("yum unload " + pname);
fm.then(" ");
fm.then(reload).command("yum re " + pname);
fm.then(delete).command("yum del " + pname);
} }
} }
@ -272,17 +358,32 @@ public class YumCommand implements HandlerCommands, Listener {
@HandlerCommand(name = "search", aliases = "s", minimumArguments = 1, description = "从BukkitDev搜索插件", possibleArguments = "插件名称") @HandlerCommand(name = "search", aliases = "s", minimumArguments = 1, description = "从BukkitDev搜索插件", possibleArguments = "插件名称")
public void search(final InvokeCommandEvent e) { public void search(final InvokeCommandEvent e) {
final String pname = e.getArgs()[0]; PluginKit.runTaskAsync(new Runnable() {
final CommandSender sender = e.getSender(); @Override
final BukkitDev bd = JsonHandle.fromJson(IOUtil.getData(String.format(BukkitDev.SEARCH, pname)), BukkitDev.class); public void run() {
if (bd.projects.isEmpty()) { final String pname = e.getArgs()[0];
sender.sendMessage(String.format(not_found_from_bukkit, pname)); final CommandSender sender = e.getSender();
return; if (pname.length() < 3) {
} sender.sendMessage(searchlimit);
sender.sendMessage(bukkitlistprefix); return;
for (final Projects p : bd.projects) { }
sender.sendMessage(String.format(bukkitlist, p.name, p.stage)); sender.sendMessage(String.format(searching, pname));
} final List<Projects> list = Projects.parseList(IOUtil.getData(String.format(BukkitDev.SEARCH, pname.toLowerCase())));
if (list.isEmpty()) {
sender.sendMessage(String.format(not_found_from_bukkit, pname));
return;
}
sender.sendMessage(String.format(result, pname));
sender.sendMessage(bukkitlistprefix);
for (final Projects p : list) {
final FancyMessage fm = FancyMessage.newFM();
fm.text(String.format(bukkitlist, p.id, p.name, p.stage));
fm.then(" ");
fm.then(look).command("yum br look " + p.id);
fm.send(sender);
}
}
});
} }
/** /**

View File

@ -12,6 +12,8 @@ import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import cn.citycraft.PluginHelper.callback.CallBack.One;
/** /**
* 下载管理类 * 下载管理类
* *
@ -58,7 +60,7 @@ public class DownloadManager {
* @return 是否成功 * @return 是否成功
*/ */
public boolean run(final CommandSender sender, final String urlstring) { public boolean run(final CommandSender sender, final String urlstring) {
return run(sender, urlstring, new File("plugins", getFileName(urlstring))); return run(sender, urlstring, new File("plugins", getFileName(urlstring)), null);
} }
/** /**
@ -83,6 +85,30 @@ public class DownloadManager {
} }
} }
/**
* 从网络下载文件
*
* @param sender
* - 命令发送者
* @param urlstring
* - 下载地址
* @param file
* - 保存文件
* @param callback
* -回调函数
* @return 是否成功
*/
public boolean run(final CommandSender sender, final String urlstring, final File file, final One<File> callback) {
try {
final URL url = new URL(urlstring);
return run(sender, url, file, callback);
} catch (final MalformedURLException e) {
sender.sendMessage("§4错误: §c无法识别的URL地址...");
sender.sendMessage("§4地址: §c" + urlstring);
return false;
}
}
/** /**
* 从网络下载文件 * 从网络下载文件
* *
@ -94,7 +120,24 @@ public class DownloadManager {
* - 保存文件 * - 保存文件
* @return 是否成功 * @return 是否成功
*/ */
public boolean run(CommandSender sender, final URL url, final File file) { public boolean run(final CommandSender sender, final URL url, final File file) {
return run(sender, url, file, null);
}
/**
* 从网络下载文件
*
* @param sender
* - 命令发送者
* @param url
* - 下载地址
* @param file
* - 保存文件
* @param callback
* -回调函数
* @return 是否成功
*/
public boolean run(CommandSender sender, final URL url, final File file, final One<File> callback) {
BufferedInputStream in = null; BufferedInputStream in = null;
FileOutputStream fout = null; FileOutputStream fout = null;
if (sender == null) { if (sender == null) {
@ -144,7 +187,6 @@ public class DownloadManager {
pVer = ""; pVer = "";
} }
sender.sendMessage("§6" + (pVer.isEmpty() ? "文件" : "插件") + ": §b" + file.getName() + (pVer.isEmpty() ? "" : " §a版本 §e" + pVer) + " §a下载完成!"); sender.sendMessage("§6" + (pVer.isEmpty() ? "文件" : "插件") + ": §b" + file.getName() + (pVer.isEmpty() ? "" : " §a版本 §e" + pVer) + " §a下载完成!");
return true;
} catch (final Exception ex) { } catch (final Exception ex) {
sender.sendMessage("§6异常: §c" + ex.getMessage()); sender.sendMessage("§6异常: §c" + ex.getMessage());
sender.sendMessage("§6文件: §c" + file.getName() + " 下载失败!"); sender.sendMessage("§6文件: §c" + file.getName() + " 下载失败!");
@ -160,6 +202,10 @@ public class DownloadManager {
} catch (final Exception ex) { } catch (final Exception ex) {
} }
} }
if (callback != null) {
callback.run(file);
}
return true;
} }
/** /**
@ -183,7 +229,7 @@ public class DownloadManager {
* @return 是否成功 * @return 是否成功
*/ */
public boolean run(final String urlstring, final File file) { public boolean run(final String urlstring, final File file) {
return run(null, urlstring, file); return run(null, urlstring, file, null);
} }
/** /**
@ -196,7 +242,7 @@ public class DownloadManager {
* @return 是否成功 * @return 是否成功
*/ */
public boolean run(final URL url, final File file) { public boolean run(final URL url, final File file) {
return run(null, url, file); return run(null, url, file, null);
} }
private String getPer(final int per) { private String getPer(final int per) {

View File

@ -1,16 +1,19 @@
package pw.yumc.Yum.models; package pw.yumc.Yum.models;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
public class BukkitDev implements Serializable { import org.json.simple.JSONArray;
public volatile static String HOST = "https://api.curseforge.com"; import org.json.simple.JSONObject;
public volatile static String MODULE = "/servermods"; import org.json.simple.JSONValue;
public volatile static String SEARCH = HOST + MODULE + "/projects?search=%s";
public volatile static String PLUGIN = HOST + MODULE + "/files?projectIds=%s";
public List<Projects> projects; public class BukkitDev implements Serializable {
public List<Files> files; public static String HOST = "https://api.curseforge.com";
public static String MODULE = "/servermods";
public static String SEARCH = HOST + MODULE + "/projects?search=%s";
public static String PLUGIN = HOST + MODULE + "/files?projectIds=%s";
public static class Files { public static class Files {
public int projectId; public int projectId;
@ -21,6 +24,27 @@ public class BukkitDev implements Serializable {
public String gameVersion; public String gameVersion;
public String md5; public String md5;
public String releaseType; public String releaseType;
public Files(final JSONObject obj) {
projectId = Integer.parseInt(obj.get("projectId").toString());
name = obj.get("name").toString();
fileUrl = obj.get("fileUrl").toString();
fileName = obj.get("fileName").toString();
downloadUrl = obj.get("downloadUrl").toString();
gameVersion = obj.get("gameVersion").toString();
md5 = obj.get("md5").toString();
releaseType = obj.get("releaseType").toString();
}
public static List<Files> parseList(final String json) {
final List<Files> temp = new ArrayList<>();
final JSONArray ja = (JSONArray) JSONValue.parse(json);
for (int i = 0; i < ja.size(); i++) {
temp.add(new Files((JSONObject) ja.get(i)));
}
Collections.reverse(temp);
return temp;
}
} }
public static class Projects { public static class Projects {
@ -28,5 +52,21 @@ public class BukkitDev implements Serializable {
public String name; public String name;
public String slug; public String slug;
public String stage; public String stage;
public Projects(final JSONObject obj) {
id = Integer.parseInt(obj.get("id").toString());
name = obj.get("name").toString();
slug = obj.get("slug").toString();
stage = obj.get("stage").toString();
}
public static List<Projects> parseList(final String json) {
final List<Projects> temp = new ArrayList<>();
final JSONArray ja = (JSONArray) JSONValue.parse(json);
for (int i = 0; i < ja.size(); i++) {
temp.add(new Projects((JSONObject) ja.get(i)));
}
return temp;
}
} }
} }