diff --git a/MultiServer/pom.xml b/MultiServer/pom.xml new file mode 100644 index 0000000..0eecf4b --- /dev/null +++ b/MultiServer/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + Multi Server + + multiserver + 0.1 + bundle + + + asys + asys + 0.5 + + + + + asys + core + RELEASE + + + + + ${project.groupId}.${project.artifactId}-${project.version} + + + org.apache.felix + maven-bundle-plugin + 3.0.1 + true + + + ASys: ${project.name} + ${project.groupId}.${project.artifactId} + asys.multiserver.Activator + asys.core.api, * + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + + asys.core.api.IServerManager + + + + + + + \ No newline at end of file diff --git a/SingleServer/Protocol/pom.xml b/SingleServer/Protocol/pom.xml new file mode 100644 index 0000000..7cbdad4 --- /dev/null +++ b/SingleServer/Protocol/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + ASys Bridge Protocol + http://dmitriymx.ru/ + + + + DmitriyMX + mail@dmiriymx.ru + + + + + UTF-8 + 1.8 + + + asys + bridge-protocol + jar + 0.1 + + + + io.netty + netty-all + 4.0.23.Final + provided + + + + + ${project.artifactId}-${project.version} + + + ${project.basedir}/src/main/resources + + ** + + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.15 + + -Dfile.encoding=${project.build.sourceEncoding} + + + + + + diff --git a/SingleServer/bukkit-plugin/pom.xml b/SingleServer/bukkit-plugin/pom.xml new file mode 100644 index 0000000..3451d7c --- /dev/null +++ b/SingleServer/bukkit-plugin/pom.xml @@ -0,0 +1,90 @@ + + + 4.0.0 + ASys Bridge + http://dmitriymx.ru/ + + + + DmitriyMX + mail@dmiriymx.ru + + + + + UTF-8 + 1.8 + 1.8.8-R0.1-SNAPSHOT + asys.bridge.ASysBukkitBridge + + + asys + bridge + jar + 1.0 + + + + spigot + https://hub.spigotmc.org/nexus/content/groups/public/ + + + + + + org.bukkit + bukkit + ${bukkit.version} + provided + + + com.googlecode.json-simple + json-simple + + + + + io.netty + netty-all + 4.0.23.Final + provided + + + + + asysbridge-${project.version} + + + ${project.basedir}/src/main/resources + + ** + + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.15 + + -Dfile.encoding=${project.build.sourceEncoding} + + + + + + diff --git a/SingleServer/bukkit-plugin/src/main/java/asys/bridge/ASysBukkitBridge.java b/SingleServer/bukkit-plugin/src/main/java/asys/bridge/ASysBukkitBridge.java new file mode 100644 index 0000000..590b9b7 --- /dev/null +++ b/SingleServer/bukkit-plugin/src/main/java/asys/bridge/ASysBukkitBridge.java @@ -0,0 +1,35 @@ +/* + * DmitriyMX + * 2016-08-08 + */ +package asys.bridge; + +import org.bukkit.plugin.java.JavaPlugin; + +/* + * Инфо: + * - ID сервера + * - кол-во игроков + * - максимальный онлайн + * - политика присоединения + */ +public class ASysBukkitBridge extends JavaPlugin { + private String idServer; + + @Override + public void onEnable() { + idServer = System.getProperty("asys.server.name"); + if (idServer == null || idServer.trim().isEmpty()) { + getLogger().severe("Don't get property \"asys.server.name\""); + getLogger().severe("Server shutdown!"); + getServer().shutdown(); + } else { + getLogger().info(String.format("Server ID: %s", idServer)); + } + } + + @Override + public void onDisable() { + getLogger().info("Bye"); + } +} diff --git a/SingleServer/bukkit-plugin/src/main/resources/plugin.yml b/SingleServer/bukkit-plugin/src/main/resources/plugin.yml new file mode 100644 index 0000000..6b5c6fd --- /dev/null +++ b/SingleServer/bukkit-plugin/src/main/resources/plugin.yml @@ -0,0 +1,5 @@ +name: ASysBridge +main: ${bukkit.mainclass} +version: ${project.version} +description: 'Plugin-connector for ASys' +author: DmitriyMX \ No newline at end of file diff --git a/SingleServer/pom.xml b/SingleServer/pom.xml index 382be24..1337f33 100644 --- a/SingleServer/pom.xml +++ b/SingleServer/pom.xml @@ -7,7 +7,7 @@ Single Server singleserver - 0.16 + 0.26 bundle @@ -20,7 +20,7 @@ asys core - 0.18 + RELEASE diff --git a/SingleServer/src/main/java/asys/singleserver/Command.java b/SingleServer/src/main/java/asys/singleserver/Command.java new file mode 100644 index 0000000..26c70a7 --- /dev/null +++ b/SingleServer/src/main/java/asys/singleserver/Command.java @@ -0,0 +1,15 @@ +/* + * DmitriyMX + * 2016-08-14 + */ +package asys.singleserver; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value = ElementType.METHOD) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface Command { +} diff --git a/SingleServer/src/main/java/asys/singleserver/Commands.java b/SingleServer/src/main/java/asys/singleserver/Commands.java index 1c3535b..afe6788 100644 --- a/SingleServer/src/main/java/asys/singleserver/Commands.java +++ b/SingleServer/src/main/java/asys/singleserver/Commands.java @@ -4,29 +4,84 @@ */ package asys.singleserver; +import asys.core.api.IMinecraftServer; import asys.core.api.IServerManager; import org.apache.felix.service.command.Descriptor; +import org.apache.felix.service.command.Parameter; -import java.util.Dictionary; -import java.util.Hashtable; +import java.lang.reflect.Method; +import java.util.*; public class Commands { private IServerManager serverManager; - public static Dictionary getDictionary() { - Hashtable dictionary = new Hashtable<>(); - dictionary.put("osgi.command.scope", "asys.singleserver"); - dictionary.put("osgi.command.function", new String[] { "startserver" }); - return dictionary; + public static Dictionary getProps(String group) { + List listCommand = new ArrayList<>(); + + try { + Class clazz = Class.forName(Commands.class.getName()); + Method[] methods = clazz.getMethods(); + for(Method method : methods) { + if (method.isAnnotationPresent(Command.class)) { + listCommand.add(method.getName()); + } + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + Hashtable props = new Hashtable<>(); + if (listCommand.size() > 0) { + props.put("osgi.command.scope", group); + props.put("osgi.command.function", listCommand.toArray(new String[listCommand.size()])); + } + return props; } public Commands(IServerManager serverManager) { this.serverManager = serverManager; } + @Command @Descriptor("Server start") - public void startserver() { + public void start() { serverManager.getServer(null).start(); } + @Command + @Descriptor("Server stop") + public void stop() { + serverManager.getServer(null).stop(); + serverManager.removeServer(null); + } + + @Command + @Descriptor("Server force stop") + public void forceStop() { + serverManager.getServer(null).forceStop(); + serverManager.removeServer(null); + } + + @Command + @Descriptor("Server restart") + public void restart() { + IMinecraftServer server = serverManager.getServer(null); + server.stop(); + server.start(); + } + + @Command + @Descriptor("Server is alive?") + public void isAlive() { + boolean alive = serverManager.getServer(null).isAlive(); + System.out.println(String.format("Server is alive: %s", alive)); + } + + @Command + @Descriptor("Send server command") + public void cmd(String... command) { + StringJoiner sj = new StringJoiner(" "); + Arrays.asList(command).forEach(sj::add); + serverManager.getServer(null).sendCommand(sj.toString()); + } } diff --git a/SingleServer/src/main/java/asys/singleserver/MinecraftWinServer.java b/SingleServer/src/main/java/asys/singleserver/MinecraftProcessServer.java similarity index 60% rename from SingleServer/src/main/java/asys/singleserver/MinecraftWinServer.java rename to SingleServer/src/main/java/asys/singleserver/MinecraftProcessServer.java index 998f755..90ae2cd 100644 --- a/SingleServer/src/main/java/asys/singleserver/MinecraftWinServer.java +++ b/SingleServer/src/main/java/asys/singleserver/MinecraftProcessServer.java @@ -11,25 +11,17 @@ import java.nio.file.Path; import java.util.List; import java.util.Vector; -public class MinecraftWinServer implements IMinecraftServer { +public class MinecraftProcessServer implements IMinecraftServer { private ProcessBuilder processBuilder; + private Process process; + private String name; - /** запуск через скрипт */ - public MinecraftWinServer(Path directory, Path script) { - processBuilder = new ProcessBuilder(); - processBuilder.directory(directory.toFile()); - processBuilder.command("cmd.exe", "/C", "start", script.toString()); - } - - /** запуск через asys */ - public MinecraftWinServer(Path directory, Path mainJar, String jvmArgs, String params) { + public MinecraftProcessServer(String name, Path directory, Path mainJar, String jvmArgs, String params) { processBuilder = new ProcessBuilder(); processBuilder.directory(directory.toFile()); List commandLine = new Vector<>(); - commandLine.add("cmd.exe"); - commandLine.add("/C"); - commandLine.add("start"); commandLine.add("java"); + commandLine.add("-Dasys.server.name=\""+name+"\""); if (jvmArgs != null && !jvmArgs.trim().isEmpty()) { commandLine.add(jvmArgs); } @@ -39,12 +31,18 @@ public class MinecraftWinServer implements IMinecraftServer { commandLine.add(params); } processBuilder.command(commandLine); + this.name = name; + } + + @Override + public String getName() { + return name; } @Override public void start() { try { - processBuilder.start(); + process = processBuilder.start(); } catch (IOException e) { e.printStackTrace(); } @@ -57,16 +55,23 @@ public class MinecraftWinServer implements IMinecraftServer { @Override public void forceStop() { - //TODO need code - } - - @Override - public boolean isAlive() { - return false; //TODO need code + process.destroy(); + process = null; } @Override public void sendCommand(String command) { - //TODO need code + try { + process.getOutputStream().write(command.getBytes()); + process.getOutputStream().write("\n".getBytes()); + process.getOutputStream().flush(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public boolean isAlive() { + return process.isAlive(); } } diff --git a/SingleServer/src/main/java/asys/singleserver/MinecraftScreenServer.java b/SingleServer/src/main/java/asys/singleserver/MinecraftScreenServer.java new file mode 100644 index 0000000..88bd9d7 --- /dev/null +++ b/SingleServer/src/main/java/asys/singleserver/MinecraftScreenServer.java @@ -0,0 +1,105 @@ +/* + * DmitriyMX + * 2016-08-11 + */ +package asys.singleserver; + +import asys.core.api.IMinecraftServer; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Vector; + +public class MinecraftScreenServer implements IMinecraftServer { + private ProcessBuilder startPB; + private String name; + private String serverPID; + + public MinecraftScreenServer(String name, Path directory, Path mainJar, String jvmArgs, String params) { + startPB = new ProcessBuilder(); + startPB.directory(directory.toFile()); + List commandLine = new Vector<>(Arrays.asList("screen", "-dmS", name, "java", "-Dasys.server.name=\""+name+"\"")); + if (jvmArgs != null && !jvmArgs.trim().isEmpty()) { + commandLine.add(jvmArgs); + } + commandLine.add("-jar"); + commandLine.add(mainJar.toString()); + if (params != null && !params.trim().isEmpty()) { + commandLine.add(params); + } + startPB.command(commandLine); + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void start() { + try { + startPB.start(); + + Thread.sleep(500); + + Process process = Runtime.getRuntime().exec("bash -c \"screen -ls | sed 's/\\t//g' | grep '\\."+name+"(' | cut -f1 -d.\""); + BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); + String out = br.readLine(); + br.close(); + + process = Runtime.getRuntime().exec("pgrep -P " + out); + br = new BufferedReader(new InputStreamReader(process.getInputStream())); + serverPID = br.readLine(); + br.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void stop() { + sendCommand("stop"); + } + + @Override + public void forceStop() { + ProcessBuilder sendCmdPB = new ProcessBuilder(); + sendCmdPB.command("screen", "-S", name, "-X", "quit"); + try { + sendCmdPB.start(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void sendCommand(String command) { + ProcessBuilder sendCmdPB = new ProcessBuilder(); + sendCmdPB.command("screen", "-S", name, "-p", "0", "-X", "stuff", command+"\\r"); + try { + sendCmdPB.start(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public boolean isAlive() { + try { + Process process = Runtime.getRuntime().exec("ps -p " + serverPID); + BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); + br.readLine(); + String line = br.readLine(); + br.close(); + return (line != null); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } +} diff --git a/SingleServer/src/main/java/asys/singleserver/SingleServer.java b/SingleServer/src/main/java/asys/singleserver/SingleServer.java index ff517bd..9815886 100644 --- a/SingleServer/src/main/java/asys/singleserver/SingleServer.java +++ b/SingleServer/src/main/java/asys/singleserver/SingleServer.java @@ -8,6 +8,8 @@ import asys.core.api.ICore; import asys.core.api.IMinecraftServer; import asys.core.api.IServerManager; import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.nio.file.Files; import java.nio.file.Path; @@ -16,36 +18,37 @@ import java.util.Properties; public class SingleServer implements IServerManager { private IMinecraftServer mcServer; - private BundleContext bundleContext; + private Logger logger = LoggerFactory.getLogger(SingleServer.class.getName()); + private Properties configuration; - public SingleServer(BundleContext bundleContext) { - this.bundleContext = bundleContext; + public SingleServer(Properties configuration) { + this.configuration = configuration; - Path serverPath = Paths.get(getProperty("asys.singleserver.server.path")); + prepareMcServer(); + } + + private void prepareMcServer() { + Path serverPath = Paths.get(configuration.getProperty("asys.singleserver.server.path")); if (Files.notExists(serverPath)) { throw new RuntimeException(String.format("Server path \"%s\" not found", serverPath.toString())); } - if (getProperty("asys.singleserver.runscript.use", "false").equalsIgnoreCase("true")) { - Path scriptFile = Paths.get(getProperty("asys.singleserver.runscript.file")); - if (Files.notExists(scriptFile)) { - throw new RuntimeException(String.format("Runscript \"%s\" not found", scriptFile.toString())); - } + Path mainJar = serverPath.resolve(configuration.getProperty("asys.singleserver.server.mainjar")); + if (Files.notExists(mainJar)) { + throw new RuntimeException(String.format("Main jar \"%s\" not found", mainJar.toString())); + } - if (!Files.isExecutable(scriptFile)) { - throw new RuntimeException(String.format("Runscript \"%s\" is not executable", scriptFile.toString())); - } - - mcServer = new MinecraftWinServer(serverPath, scriptFile); + String typeServerImplement = configuration.getProperty("asys.singleserver.typeImplement", "process"); + if (typeServerImplement.equalsIgnoreCase("screen")) { + logger.debug("Used server implement: screen"); + mcServer = new MinecraftScreenServer("mcserver", serverPath, mainJar, + configuration.getProperty("asys.singleserver.server.jvm.args", null), + configuration.getProperty("asys.singleserver.server.params", null)); } else { - Path mainJar = serverPath.resolve(getProperty("asys.singleserver.server.mainjar")); - if (Files.notExists(mainJar)) { - throw new RuntimeException(String.format("Main jar \"%s\" not found", mainJar.toString())); - } - - mcServer = new MinecraftWinServer(serverPath, mainJar, - getProperty("asys.singleserver.server.jvm.args", null), - getProperty("asys.singleserver.server.params", null)); + logger.debug("Used server implement: process"); + mcServer = new MinecraftProcessServer("mcserver", serverPath, mainJar, + configuration.getProperty("asys.singleserver.server.jvm.args", null), + configuration.getProperty("asys.singleserver.server.params", null)); } } @@ -56,9 +59,17 @@ public class SingleServer implements IServerManager { @Override public IMinecraftServer getServer(String serverName) { + if (mcServer == null) { + prepareMcServer(); + } return mcServer; } + @Override + public void removeServer(String name) { + mcServer = null; + } + void loadState() { ICore core = SingleServerActivator.instance.getCore(); IMinecraftServer testMcServer = (IMinecraftServer) core.loadObject(SingleServer.class.getName() + "#mcServer"); @@ -71,16 +82,4 @@ public class SingleServer implements IServerManager { ICore core = SingleServerActivator.instance.getCore(); core.saveObject(SingleServer.class.getName() + "#mcServer", mcServer); } - - private String getProperty(String name) { - return getProperty(name, null); - } - - private String getProperty(String name, String defValue) { - try { - return bundleContext.getProperty(name); - } catch (NullPointerException e) { - return defValue; - } - } } diff --git a/SingleServer/src/main/java/asys/singleserver/SingleServerActivator.java b/SingleServer/src/main/java/asys/singleserver/SingleServerActivator.java index db64f6b..29e48c1 100644 --- a/SingleServer/src/main/java/asys/singleserver/SingleServerActivator.java +++ b/SingleServer/src/main/java/asys/singleserver/SingleServerActivator.java @@ -6,11 +6,18 @@ package asys.singleserver; import asys.core.api.ICore; import asys.core.api.IServerManager; +import org.apache.commons.io.FileUtils; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.ServiceTracker; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; + public class SingleServerActivator implements BundleActivator { static SingleServerActivator instance; private ServiceRegistration service, cmdService; @@ -24,13 +31,13 @@ public class SingleServerActivator implements BundleActivator { tracker = new ServiceTracker<>(bundleContext, ICore.class.getName(), null); tracker.open(); - singleServer = new SingleServer(bundleContext); + singleServer = new SingleServer(loadProperties(getProperty(bundleContext, "asys.core.config.dir", "conf"))); singleServer.loadState(); service = bundleContext.registerService(IServerManager.class.getName(), singleServer, null); // Регистрация комманд для Gogo Shell cmdService = bundleContext.registerService( - Commands.class.getName(), new Commands(singleServer), Commands.getDictionary()); + Commands.class.getName(), new Commands(singleServer), Commands.getProps("asys.server")); } @Override @@ -45,4 +52,51 @@ public class SingleServerActivator implements BundleActivator { ICore getCore() { return tracker.getService(); } + + private Properties loadProperties(String confDir) { + Path propsPath = Paths.get(confDir).resolve("asys.singleserver.properties"); + if (Files.notExists(propsPath)) { + propsPath.toFile().getParentFile().mkdirs(); + + InputStream resourceAsStream = getClass().getResourceAsStream("/asys.singleserver.properties"); + try { + BufferedWriter bw = new BufferedWriter(new FileWriter(propsPath.toFile())); + BufferedReader br = new BufferedReader(new InputStreamReader(resourceAsStream)); + String line; + while((line = br.readLine()) != null) { + bw.write(line); + bw.write("\n"); + } + bw.flush(); + bw.close(); + br.close(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + Properties properties = new Properties(); + try { + properties.load(new FileReader(propsPath.toFile())); + return properties; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + private String getProperty(BundleContext bundleContext, String name) { + return getProperty(bundleContext, name, null); + } + + private String getProperty(BundleContext bundleContext, String name, String defValue) { + try { + String result = bundleContext.getProperty(name); + if (result == null) return defValue; + else return result; + } catch (NullPointerException e) { + return defValue; + } + } } diff --git a/SingleServer/src/main/resources/asys.singleserver.properties b/SingleServer/src/main/resources/asys.singleserver.properties new file mode 100644 index 0000000..cc97a9b --- /dev/null +++ b/SingleServer/src/main/resources/asys.singleserver.properties @@ -0,0 +1,6 @@ +asys.singleserver.server.path=server + +asys.singleserver.typeImplement=process +asys.singleserver.server.mainjar=spigot.jar +asys.singleserver.server.jvm.args="-Dfile.encoding=UTF-8" +asys.singleserver.server.params= \ No newline at end of file diff --git a/SingleServer/src/test/java/asys/singleserver/TestMinectaftScreenServer.java b/SingleServer/src/test/java/asys/singleserver/TestMinectaftScreenServer.java new file mode 100644 index 0000000..0e5ade8 --- /dev/null +++ b/SingleServer/src/test/java/asys/singleserver/TestMinectaftScreenServer.java @@ -0,0 +1,31 @@ +/* + * DmitriyMX + * 2016-08-11 + */ +package asys.singleserver; + +import asys.core.api.IMinecraftServer; + +import java.nio.file.Paths; + +public class TestMinectaftScreenServer { + public static void main(String[] args) { + IMinecraftServer server = new MinecraftScreenServer( + "test", + Paths.get("D:\\tmp\\spigot_test"), + Paths.get("D:\\tmp\\spigot_test\\spigot-1.8.8.jar"), + "", ""); + server.start(); + System.out.println(String.format("isAlive: %s", server.isAlive())); + try { + Thread.sleep(30000); + } catch (InterruptedException ignored) { + } + server.stop(); + try { + Thread.sleep(5000); + } catch (InterruptedException ignored) { + } + System.out.println(String.format("isAlive: %s", server.isAlive())); + } +} diff --git a/SingleServer/src/test/java/asys/singleserver/TestSingleServer.java b/SingleServer/src/test/java/asys/singleserver/TestSingleServer.java new file mode 100644 index 0000000..93c0e33 --- /dev/null +++ b/SingleServer/src/test/java/asys/singleserver/TestSingleServer.java @@ -0,0 +1,49 @@ +/* + * DmitriyMX + * 2016-07-30 + */ +package asys.singleserver; + +import asys.core.api.IMinecraftServer; +import asys.core.api.IServerManager; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.osgi.framework.BundleContext; + +import java.util.Iterator; +import java.util.Properties; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class TestSingleServer { + @Test + public void testAutorun() throws InterruptedException { + BundleContext mockBundleContext = mock(BundleContext.class); + when(mockBundleContext.getProperty("asys.singleserver.server.path")).thenReturn("D:\\tmp\\spigot_test"); + when(mockBundleContext.getProperty("asys.singleserver.server.mainjar")).thenReturn("spigot-1.8.8.jar"); + when(mockBundleContext.getProperty("asys.singleserver.server.jvm.args")).thenReturn("-Dserver.name=\\\"Minecraft Server\\\" -Dfile.encoding=UTF-8"); + + IServerManager serverManager = new SingleServer(mockBundleContext); + IMinecraftServer server = serverManager.getServer(null); + server.start(); + Assert.assertTrue(server.isAlive()); + for (int i = 0; i < 7; i++) Thread.sleep(1000); + server.stop(); + for (int i = 0; i < 5; i++) { + if (server.isAlive()) { + Thread.sleep(1000); + } else { + break; + } + } + if (server.isAlive()) { + server.forceStop(); + for (int i = 0; i < 5; i++) Thread.sleep(1000); + } + Assert.assertFalse(server.isAlive()); + } +} diff --git a/core/pom.xml b/core/pom.xml index cc6c69c..555deb2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ Core core - 0.18 + 0.21 bundle diff --git a/core/src/main/java/asys/core/api/AccessPolicy.java b/core/src/main/java/asys/core/api/AccessPolicy.java new file mode 100644 index 0000000..0adc778 --- /dev/null +++ b/core/src/main/java/asys/core/api/AccessPolicy.java @@ -0,0 +1,18 @@ +/* + * DmitriyMX + * 2016-08-14 + */ +package asys.core.api; + +public enum AccessPolicy { + EVERYONE(3), PERMISSIONED(2), ADMIN(1), NO_ONE(0); + + int id; + AccessPolicy(int id) { + this.id = id; + } + + public int getId() { + return id; + } +} diff --git a/core/src/main/java/asys/core/api/IMinecraftServer.java b/core/src/main/java/asys/core/api/IMinecraftServer.java index 5950f9a..b1ff740 100644 --- a/core/src/main/java/asys/core/api/IMinecraftServer.java +++ b/core/src/main/java/asys/core/api/IMinecraftServer.java @@ -5,9 +5,10 @@ package asys.core.api; public interface IMinecraftServer { + String getName(); void start(); void stop(); void forceStop(); - boolean isAlive(); void sendCommand(String command); + boolean isAlive(); } diff --git a/core/src/main/java/asys/core/api/IServerManager.java b/core/src/main/java/asys/core/api/IServerManager.java index 05baff1..c4387c5 100644 --- a/core/src/main/java/asys/core/api/IServerManager.java +++ b/core/src/main/java/asys/core/api/IServerManager.java @@ -5,6 +5,7 @@ package asys.core.api; public interface IServerManager { - IMinecraftServer developServer(String serverName); - IMinecraftServer getServer(String serverName); + IMinecraftServer developServer(String name); + IMinecraftServer getServer(String name); + void removeServer(String name); } diff --git a/core/src/test/java/asys/core/TestAppRunner.java b/core/src/test/java/asys/core/TestAppRunner.java new file mode 100644 index 0000000..e2e910f --- /dev/null +++ b/core/src/test/java/asys/core/TestAppRunner.java @@ -0,0 +1,69 @@ +/* + * DmitriyMX + * 2016-07-29 + */ +package asys.core; + +import org.junit.Test; + +import java.io.*; +import java.nio.file.Paths; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TestAppRunner { + public static void main(String[] args) throws IOException, InterruptedException { +// ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "ping 127.0.0.1 -t"); + ProcessBuilder processBuilder = new ProcessBuilder("java.exe", "-jar", "spigot-1.8.8.jar"); + processBuilder.directory(Paths.get("D:\\tmp\\spigot_test").toFile()); + final Process process = processBuilder.start(); + final boolean[] res = new boolean[1]; + + new Thread(() -> { + Pattern pattern = Pattern.compile("Done \\(.+?\\)! For help, type \"help\" or \"\\?\""); + InputStream inputStream = process.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + String line; + try { + while ((line = reader.readLine()) != null) { + System.out.println(System.currentTimeMillis() + " " + line); + Matcher matcher = pattern.matcher(line); + if (matcher.find()) { + System.err.println(System.currentTimeMillis() + " " + "GOTCHA!!!"); + res[0] = true; + } + } + } catch (IOException e) { + e.printStackTrace(); + } + }).start(); + + new Thread(() -> { + InputStream inputStream = process.getErrorStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + String line; + try { + while ((line = reader.readLine()) != null) { + System.err.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + }).start(); + + while(!res[0]) { + Thread.sleep(1000); + } + +// OutputStream outputStream = process.getOutputStream(); +// for(int i = 0; i < 10; i++) { +// outputStream.write("echo hello\n".getBytes()); +// outputStream.flush(); +// } +// +// outputStream.write("stop\n".getBytes()); +// outputStream.flush(); + + process.waitFor(); + } +} diff --git a/pom.xml b/pom.xml index dd25c88..b621357 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,7 @@ core singleserver + multiserver @@ -46,6 +47,12 @@ 4.12 test + + org.mockito + mockito-core + 2.0.99-beta + test + org.slf4j slf4j-jdk14