mirror of
https://e.coding.net/circlecloud/Yum.git
synced 2024-11-22 22:38:46 +00:00
add reinstall and modify PluginsManager...
Signed-off-by: j502647092 <jtb1@163.com>
This commit is contained in:
parent
896357ad1b
commit
ab32d82651
@ -36,7 +36,7 @@ public class CommandInstall extends BaseCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (yum.download.install(sender, pluginname)) {
|
if (yum.download.install(sender, pluginname)) {
|
||||||
sender.sendMessage(PluginsManager.load(pluginname));
|
PluginsManager.load(sender, pluginname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package cn.citycraft.Yum.commands;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandException;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import cn.citycraft.Yum.Yum;
|
||||||
|
import cn.citycraft.Yum.utils.PluginsManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插件安装命令类
|
||||||
|
*
|
||||||
|
* @author 蒋天蓓 2015年8月12日下午2:04:05
|
||||||
|
*/
|
||||||
|
public class CommandReinstall extends BaseCommand {
|
||||||
|
Yum yum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public CommandReinstall(Yum main) {
|
||||||
|
super("reinstall");
|
||||||
|
this.yum = main;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(final CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
final String pluginname = args[0];
|
||||||
|
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(pluginname);
|
||||||
|
sender.sendMessage("§a开始重装插件: " + pluginname);
|
||||||
|
if (plugin != null) {
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(yum, new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (yum.download.yum(sender, plugin.getName())) {
|
||||||
|
PluginsManager.deletePlugin(plugin);
|
||||||
|
PluginsManager.installFromYum(sender, plugin.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
sender.sendMessage("§c插件未安装或已卸载 需要安装请使用yum install " + pluginname + "!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<插件名称>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOnlyPlayerExecutable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -26,21 +26,16 @@ public class CommandRemove extends BaseCommand {
|
|||||||
this.yum = main;
|
this.yum = main;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOnlyPlayerExecutable() {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
String pluginname = args[0];
|
String pluginname = args[0];
|
||||||
Plugin plugin = yum.getServer().getPluginManager().getPlugin(pluginname);
|
Plugin plugin = yum.getServer().getPluginManager().getPlugin(pluginname);
|
||||||
if (plugin != null) {
|
if (plugin != null) {
|
||||||
sender.sendMessage(PluginsManager.unload(plugin));
|
PluginsManager.unload(sender, plugin);
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage("§c插件 " + pluginname + " 不存在或已卸载!");
|
sender.sendMessage("§c插件 " + pluginname + " 不存在或已卸载!");
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinimumArguments() {
|
public int getMinimumArguments() {
|
||||||
@ -51,4 +46,9 @@ public class CommandRemove extends BaseCommand {
|
|||||||
public String getPossibleArguments() {
|
public String getPossibleArguments() {
|
||||||
return "<插件名称>";
|
return "<插件名称>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOnlyPlayerExecutable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,8 @@ public class CommandUpdate extends BaseCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (yum.download.update(sender, plugin)) {
|
if (yum.download.update(sender, plugin)) {
|
||||||
sender.sendMessage(PluginsManager.unload(plugin));
|
PluginsManager.unload(sender, plugin);
|
||||||
sender.sendMessage(PluginsManager.load(plugin));
|
PluginsManager.load(sender, plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@ package cn.citycraft.Yum.utils;
|
|||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -16,12 +17,18 @@ import org.bukkit.plugin.Plugin;
|
|||||||
* @author 蒋天蓓 2015年8月21日下午6:08:09 TODO
|
* @author 蒋天蓓 2015年8月21日下午6:08:09 TODO
|
||||||
*/
|
*/
|
||||||
public class DownloadManager {
|
public class DownloadManager {
|
||||||
|
String yumurl = "http://ci.citycraft.cn:8800/jenkins/job/%1$s/lastSuccessfulBuild/artifact/target/%1$s.jar";
|
||||||
Plugin plugin;
|
Plugin plugin;
|
||||||
|
|
||||||
public DownloadManager(Plugin main) {
|
public DownloadManager(Plugin main) {
|
||||||
this.plugin = main;
|
this.plugin = main;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getFileName(URL url) {
|
||||||
|
int end = url.getFile().lastIndexOf('/');
|
||||||
|
return url.getFile().substring(end + 1);
|
||||||
|
}
|
||||||
|
|
||||||
private String getPer(int per) {
|
private String getPer(int per) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < 11; i++) {
|
for (int i = 0; i < 11; i++) {
|
||||||
@ -36,14 +43,19 @@ public class DownloadManager {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean install(CommandSender sender, String pluginname) {
|
public URL getUrl(String pluginname) {
|
||||||
return run(sender, pluginname, null);
|
try {
|
||||||
|
return new URL(String.format(yumurl, pluginname));
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean run(final CommandSender sender, final String pluginname, final String filename) {
|
public boolean install(CommandSender sender, String pluginname) {
|
||||||
String url = "http://ci.citycraft.cn:8800/jenkins/job/%1$s/lastSuccessfulBuild/artifact/target/%1$s.jar";
|
return run(sender, getUrl(pluginname), new File("plugins", pluginname + ".jar"));
|
||||||
// String url = "https://502647092.github.io/plugins/%1$s/%1$s.jar";
|
}
|
||||||
|
|
||||||
|
public boolean run(CommandSender sender, URL url, File file) {
|
||||||
BufferedInputStream in = null;
|
BufferedInputStream in = null;
|
||||||
FileOutputStream fout = null;
|
FileOutputStream fout = null;
|
||||||
CommandSender resultsender = sender;
|
CommandSender resultsender = sender;
|
||||||
@ -51,18 +63,11 @@ public class DownloadManager {
|
|||||||
resultsender = Bukkit.getConsoleSender();
|
resultsender = Bukkit.getConsoleSender();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
resultsender.sendMessage("§6开始下载: §3" + pluginname);
|
resultsender.sendMessage("§6开始下载: §3" + getFileName(url));
|
||||||
URL fileUrl = new URL(String.format(url, pluginname));
|
resultsender.sendMessage("§6下载地址: §3" + url.getPath());
|
||||||
resultsender.sendMessage("§6下载地址: §3" + fileUrl.getPath());
|
int fileLength = url.openConnection().getContentLength();
|
||||||
int fileLength = fileUrl.openConnection().getContentLength();
|
|
||||||
resultsender.sendMessage("§6文件长度: §3" + fileLength);
|
resultsender.sendMessage("§6文件长度: §3" + fileLength);
|
||||||
in = new BufferedInputStream(fileUrl.openStream());
|
in = new BufferedInputStream(url.openStream());
|
||||||
File file = null;
|
|
||||||
if (filename == null) {
|
|
||||||
file = new File(new File("plugins"), pluginname + ".jar");
|
|
||||||
} else {
|
|
||||||
file = new File(new File("plugins/update"), filename);
|
|
||||||
}
|
|
||||||
if (!file.getParentFile().exists()) {
|
if (!file.getParentFile().exists()) {
|
||||||
file.getParentFile().mkdirs();
|
file.getParentFile().mkdirs();
|
||||||
resultsender.sendMessage("§d创建新目录: " + file.getParentFile().getAbsolutePath());
|
resultsender.sendMessage("§d创建新目录: " + file.getParentFile().getAbsolutePath());
|
||||||
@ -84,10 +89,10 @@ public class DownloadManager {
|
|||||||
resultsender.sendMessage(String.format("§6已下载: §a" + getPer(percent / 10) + " %s%%", percent));
|
resultsender.sendMessage(String.format("§6已下载: §a" + getPer(percent / 10) + " %s%%", percent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resultsender.sendMessage("§a插件: " + pluginname + " 下载完成!");
|
resultsender.sendMessage("§a文件: " + file.getName() + " 下载完成!");
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
resultsender.sendMessage("§c插件" + pluginname + "下载失败!");
|
resultsender.sendMessage("§c文件" + file.getName() + "下载失败!");
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
@ -101,9 +106,17 @@ public class DownloadManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean run(URL url, File file) {
|
||||||
|
return run(null, url, file);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean update(CommandSender sender, Plugin plugin) {
|
public boolean update(CommandSender sender, Plugin plugin) {
|
||||||
String pluginname = plugin.getName();
|
String pluginname = plugin.getName();
|
||||||
String filename = PluginsManager.getPluginFile(plugin).getName();
|
String filename = PluginsManager.getPluginFile(plugin).getName();
|
||||||
return run(sender, pluginname, filename);
|
return run(sender, getUrl(pluginname), new File("plugins/update", filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean yum(CommandSender sender, String pluginname) {
|
||||||
|
return run(sender, getUrl(pluginname), new File("YumCenter", pluginname + ".jar"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,10 @@
|
|||||||
package cn.citycraft.Yum.utils;
|
package cn.citycraft.Yum.utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
@ -18,6 +21,7 @@ import java.util.SortedSet;
|
|||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
import org.bukkit.command.SimpleCommandMap;
|
import org.bukkit.command.SimpleCommandMap;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
@ -37,12 +41,31 @@ import com.google.common.base.Joiner;
|
|||||||
*/
|
*/
|
||||||
public class PluginsManager {
|
public class PluginsManager {
|
||||||
|
|
||||||
public static boolean deletePlugin(Plugin plugin) {
|
public static boolean copyFile(File src, File des) {
|
||||||
ClassLoader cl = plugin.getClass().getClassLoader();
|
InputStream inStream = null; // 读入原文件
|
||||||
if ((cl instanceof URLClassLoader)) {
|
FileOutputStream fs = null;
|
||||||
} else {
|
try {
|
||||||
}
|
int byteread = 0;
|
||||||
|
if (!src.exists())
|
||||||
return false;
|
return false;
|
||||||
|
inStream = new FileInputStream(src); // 读入原文件
|
||||||
|
fs = new FileOutputStream(des);
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
while ((byteread = inStream.read(buffer)) != -1) {
|
||||||
|
fs.write(buffer, 0, byteread);
|
||||||
|
}
|
||||||
|
inStream.close();
|
||||||
|
fs.close();
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean deletePlugin(Plugin plugin) {
|
||||||
|
unload(plugin);
|
||||||
|
getPluginFile(plugin).delete();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void disable(Plugin plugin) {
|
public static void disable(Plugin plugin) {
|
||||||
@ -140,10 +163,22 @@ public class PluginsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parsedCommands.isEmpty())
|
if (parsedCommands.isEmpty())
|
||||||
return "§c没有注册命令!";
|
return null;
|
||||||
return Joiner.on(", ").join(parsedCommands);
|
return Joiner.on(", ").join(parsedCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean installFromYum(CommandSender sender, String filename) {
|
||||||
|
File file = new File("plugins/YumCenter", filename + ".jar");
|
||||||
|
if (!file.exists()) {
|
||||||
|
sender.sendMessage("§c仓库不存在该插件!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
File pluginfile = new File("plugins", filename + ".jar");
|
||||||
|
copyFile(file, pluginfile);
|
||||||
|
load(sender, filename + ".jar");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isIgnored(Plugin plugin) {
|
public static boolean isIgnored(Plugin plugin) {
|
||||||
return isIgnored(plugin.getName());
|
return isIgnored(plugin.getName());
|
||||||
}
|
}
|
||||||
@ -156,12 +191,12 @@ public class PluginsManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String load(Plugin plugin) {
|
public static boolean load(CommandSender sender, Plugin plugin) {
|
||||||
String filename = getPluginFile(plugin).getName();
|
String filename = getPluginFile(plugin).getName();
|
||||||
return load(filename);
|
return load(sender, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String load(String name) {
|
public static boolean load(CommandSender sender, String name) {
|
||||||
Plugin target = null;
|
Plugin target = null;
|
||||||
|
|
||||||
if (!name.endsWith(".jar")) {
|
if (!name.endsWith(".jar")) {
|
||||||
@ -171,31 +206,44 @@ public class PluginsManager {
|
|||||||
File pluginDir = new File("plugins");
|
File pluginDir = new File("plugins");
|
||||||
File updateDir = new File(pluginDir, "update");
|
File updateDir = new File(pluginDir, "update");
|
||||||
|
|
||||||
if (!pluginDir.isDirectory())
|
if (!pluginDir.isDirectory()) {
|
||||||
return "§c插件目录不存在或IO错误!";
|
sender.sendMessage("§c插件目录不存在或IO错误!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
File pluginFile = new File(pluginDir, name);
|
File pluginFile = new File(pluginDir, name);
|
||||||
|
|
||||||
if (!pluginFile.isFile() && !new File(updateDir, name).isFile())
|
if (!pluginFile.isFile() && !new File(updateDir, name).isFile()) {
|
||||||
return "§c在插件目录和更新目录未找到 " + name + " 插件 请确认文件是否存在!";
|
sender.sendMessage("§c在插件目录和更新目录未找到 " + name + " 插件 请确认文件是否存在!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
target = Bukkit.getPluginManager().loadPlugin(pluginFile);
|
target = Bukkit.getPluginManager().loadPlugin(pluginFile);
|
||||||
} catch (InvalidDescriptionException e) {
|
} catch (InvalidDescriptionException e) {
|
||||||
e.printStackTrace();
|
sender.sendMessage("§c异常: " + e.getMessage() + " 插件: " + name + " 的plugin.yml文件存在错误!");
|
||||||
return "§c异常: " + e.getMessage() + " 插件: " + name + " 的plugin.yml文件存在错误!";
|
return false;
|
||||||
} catch (InvalidPluginException e) {
|
} catch (InvalidPluginException e) {
|
||||||
e.printStackTrace();
|
sender.sendMessage("§c异常: " + e.getMessage() + " 文件: " + name + " 不是一个可载入的插件!");
|
||||||
return "§c异常: " + e.getMessage() + " 文件: " + name + " 不是一个可载入的插件!";
|
return false;
|
||||||
} catch (UnknownDependencyException e) {
|
} catch (UnknownDependencyException e) {
|
||||||
e.printStackTrace();
|
sender.sendMessage("§c异常: " + e.getMessage() + " 插件: " + name + " 缺少部分依赖!");
|
||||||
return "§c异常: " + e.getMessage() + " 插件: " + name + " 缺少部分依赖!";
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
target.onLoad();
|
target.onLoad();
|
||||||
Bukkit.getPluginManager().enablePlugin(target);
|
Bukkit.getPluginManager().enablePlugin(target);
|
||||||
|
|
||||||
return "§a插件: " + name + " 已成功载入到服务器!";
|
return true;
|
||||||
|
// "§a插件: " + name + " 已成功载入到服务器!";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean load(Plugin plugin) {
|
||||||
|
return load(null, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean load(String name) {
|
||||||
|
return load(null, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reload(Plugin plugin) {
|
public static void reload(Plugin plugin) {
|
||||||
@ -214,7 +262,7 @@ public class PluginsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static String unload(Plugin plugin) {
|
public static boolean unload(CommandSender sender, Plugin plugin) {
|
||||||
String name = plugin.getName();
|
String name = plugin.getName();
|
||||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||||
SimpleCommandMap commandMap = null;
|
SimpleCommandMap commandMap = null;
|
||||||
@ -249,11 +297,11 @@ public class PluginsManager {
|
|||||||
knownCommandsField.setAccessible(true);
|
knownCommandsField.setAccessible(true);
|
||||||
commands = (Map<String, Command>) knownCommandsField.get(commandMap);
|
commands = (Map<String, Command>) knownCommandsField.get(commandMap);
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
e.printStackTrace();
|
return false;
|
||||||
return "§c异常: " + e.getMessage() + " 插件 " + name + " 卸载失败!";
|
// "§c异常: " + e.getMessage() + " 插件 " + name + " 卸载失败!";
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
return false;
|
||||||
return "§c异常: " + e.getMessage() + " 插件 " + name + " 卸载失败!";
|
// "§c异常: " + e.getMessage() + " 插件 " + name + " 卸载失败!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pluginManager.disablePlugin(plugin);
|
pluginManager.disablePlugin(plugin);
|
||||||
@ -289,11 +337,15 @@ public class PluginsManager {
|
|||||||
if ((cl instanceof URLClassLoader)) {
|
if ((cl instanceof URLClassLoader)) {
|
||||||
try {
|
try {
|
||||||
((URLClassLoader) cl).close();
|
((URLClassLoader) cl).close();
|
||||||
cl = null;
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.gc();
|
System.gc();
|
||||||
return "§a插件: " + name + " 已成功卸载!";
|
return true;
|
||||||
|
// "§a插件: " + name + " 已成功卸载!";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean unload(Plugin plugin) {
|
||||||
|
return unload(null, plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
name: Yum
|
name: Yum
|
||||||
main: cn.citycraft.Yum.Yum
|
main: cn.citycraft.Yum.Yum
|
||||||
website: http://ci.citycraft.cn:8800/jenkins/job/Yum/
|
website: http://ci.citycraft.cn:8800/jenkins/job/Yum/
|
||||||
version: 1.2
|
version: 1.3
|
||||||
commands:
|
commands:
|
||||||
yum:
|
yum:
|
||||||
description: MC插件仓库
|
description: MC插件仓库
|
||||||
|
Loading…
Reference in New Issue
Block a user