Add support for custom server jars
This commit is contained in:
parent
2dac8eb9f5
commit
8310e0889b
11 changed files with 361 additions and 284 deletions
2
.idea/.gitignore
vendored
Normal file
2
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Default ignored files
|
||||
/workspace.xml
|
15
.idea/ButtonServerRunner.iml
Normal file
15
.idea/ButtonServerRunner.iml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: jline:jline:2.12" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.21" level="project" />
|
||||
</component>
|
||||
</module>
|
4
.idea/encodings.xml
Normal file
4
.idea/encodings.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
|
||||
</project>
|
11
.idea/inspectionProfiles/Project_Default.xml
Normal file
11
.idea/inspectionProfiles/Project_Default.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="false" />
|
||||
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
|
||||
<option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />
|
||||
<disabledExtension id="moduleInfo" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
13
.idea/libraries/Maven__org_yaml_snakeyaml_1_21.xml
Normal file
13
.idea/libraries/Maven__org_yaml_snakeyaml_1_21.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<component name="libraryTable">
|
||||
<library name="Maven: org.yaml:snakeyaml:1.21">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.21/snakeyaml-1.21.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.21/snakeyaml-1.21-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.21/snakeyaml-1.21-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
3
.idea/markdown-navigator/profiles_settings.xml
Normal file
3
.idea/markdown-navigator/profiles_settings.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<component name="MarkdownNavigator.ProfileManager">
|
||||
<settings default="" pdf-export="" />
|
||||
</component>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/MCServerRunner.iml" filepath="$PROJECT_DIR$/MCServerRunner.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
15
MCServerRunner.iml
Normal file
15
MCServerRunner.iml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: jline:jline:2.12" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.21" level="project" />
|
||||
</component>
|
||||
</module>
|
117
pom.xml
117
pom.xml
|
@ -1,59 +1,60 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>ButtonDevTeam</groupId>
|
||||
<artifactId>MCServerRunner</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<mainClass>buttondevteam.serverrunner.ServerRunner</mainClass>
|
||||
<classpathPrefix>ServerRunner_lib/</classpathPrefix>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jline</groupId>
|
||||
<artifactId>jline</artifactId>
|
||||
<version>2.12</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.yaml/snakeyaml -->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.21</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>ButtonDevTeam</groupId>
|
||||
<artifactId>MCServerRunner</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<finalName>ServerRunner</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<mainClass>buttondevteam.serverrunner.ServerRunner</mainClass>
|
||||
<classpathPrefix>ServerRunner_lib/</classpathPrefix>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jline</groupId>
|
||||
<artifactId>jline</artifactId>
|
||||
<version>2.12</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.yaml/snakeyaml -->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.21</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -4,6 +4,7 @@ public class Config {
|
|||
public String serverVersion;
|
||||
public String serverParams;
|
||||
public int restartAt;
|
||||
public String customJar;
|
||||
|
||||
public Config(String serverVersion, String serverParams, int restartAt) {
|
||||
this.serverVersion = serverVersion;
|
||||
|
@ -14,5 +15,6 @@ public class Config {
|
|||
this.serverVersion = "1.12.2";
|
||||
this.serverParams = "-Djline.terminal=jline.UnixTerminal -Xms4G -Xmx6G";
|
||||
this.restartAt = 12;
|
||||
this.customJar = "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,226 +1,229 @@
|
|||
package buttondevteam.serverrunner;
|
||||
|
||||
import jline.console.ConsoleReader;
|
||||
import jline.console.CursorBuffer;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ServerRunner {
|
||||
private static final int RESTART_MESSAGE_COUNT = 60;
|
||||
|
||||
private static final int interval = 24; // hours
|
||||
|
||||
private static volatile boolean stop = false;
|
||||
private static int restartcounter = RESTART_MESSAGE_COUNT;
|
||||
private static volatile Process serverprocess;
|
||||
private static volatile PrintWriter serveroutput;
|
||||
private static volatile Thread rt;
|
||||
private static volatile ConsoleReader reader;
|
||||
private static volatile PrintWriter runnerout;
|
||||
|
||||
private static volatile boolean customrestartfailed = false;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Yaml yaml = new Yaml();
|
||||
File f=new File("plugins/ServerRunner/config.yml");
|
||||
f.getParentFile().mkdirs();
|
||||
final Config config;
|
||||
if(!f.exists())
|
||||
Files.write(f.toPath(), Collections.singleton(yaml.dump(config = new Config())));
|
||||
else
|
||||
config=yaml.load(new FileInputStream(f));
|
||||
if (!new File("spigot-" + config.serverVersion + ".jar").exists()) {
|
||||
System.out.println("The server JAR for " + config.serverVersion + " cannot be found!");
|
||||
return;
|
||||
}
|
||||
reader = new ConsoleReader();
|
||||
reader.setPrompt("Runner>");
|
||||
runnerout = new PrintWriter(reader.getOutput());
|
||||
writeToScreen("Starting server...");
|
||||
serverprocess = startServer(config);
|
||||
serveroutput = new PrintWriter(serverprocess.getOutputStream());
|
||||
rt = Thread.currentThread();
|
||||
final Thread it = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String readLine;
|
||||
while (!stop) {
|
||||
try {
|
||||
if ((readLine = reader.readLine()) == null)
|
||||
break;
|
||||
if (readLine.equalsIgnoreCase("stop"))
|
||||
ServerRunner.stop();
|
||||
serveroutput.println(readLine);
|
||||
serveroutput.flush();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Thread.sleep(100); //Sleep a bit and keep going
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ServerRunner.stop();
|
||||
writeToScreen("Stopped " + Thread.currentThread().getName());
|
||||
}
|
||||
};
|
||||
it.setName("InputThread");
|
||||
it.start();
|
||||
final Thread ot = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
BufferedReader serverinput = new BufferedReader(
|
||||
new InputStreamReader(serverprocess.getInputStream(), StandardCharsets.UTF_8));
|
||||
String line;
|
||||
while (true) {
|
||||
if ((line = serverinput.readLine()) != null) {
|
||||
writeToScreen(line);
|
||||
if (line.contains("FAILED TO BIND TO PORT")) {
|
||||
ServerRunner.stop();
|
||||
writeToScreen("A server is already running!");
|
||||
}
|
||||
if (Pattern.matches(
|
||||
"\\[\\d\\d:\\d\\d:\\d\\d INFO]: Unknown command. Type \"/help\" for help.\\s+", line))
|
||||
customrestartfailed = true;
|
||||
|
||||
} else if (!stop) {
|
||||
try {
|
||||
serverinput.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
serveroutput.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
writeToScreen("Server stopped! Restarting...");
|
||||
serverprocess = startServer(config);
|
||||
serverinput = new BufferedReader(new InputStreamReader(serverprocess.getInputStream()));
|
||||
serveroutput = new PrintWriter(serverprocess.getOutputStream());
|
||||
restartcounter = RESTART_MESSAGE_COUNT;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
serverinput.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ServerRunner.stop();
|
||||
writeToScreen("Stopped " + Thread.currentThread().getName());
|
||||
}
|
||||
};
|
||||
ot.setName("OutputThread");
|
||||
ot.start();
|
||||
Thread.currentThread().setName("RestarterThread");
|
||||
long starttime = syncStart(config.restartAt);
|
||||
System.out.println("Restart scheduled in " + starttime / 3600000f);
|
||||
boolean firstrun = true;
|
||||
while (!stop) {
|
||||
try {
|
||||
if (restartcounter >= 0) {
|
||||
if (restartcounter == RESTART_MESSAGE_COUNT) {
|
||||
if (firstrun) {
|
||||
// writeToScreen("Sleeping for " + starttime);
|
||||
Thread.sleep(starttime);
|
||||
firstrun = false;
|
||||
} else
|
||||
Thread.sleep(interval * 3600000);
|
||||
customrestartfailed = false;
|
||||
serveroutput.println("schrestart");
|
||||
serveroutput.flush();
|
||||
} else if (restartcounter > 0) {
|
||||
if (customrestartfailed) {
|
||||
if (restartcounter % 10 == 0)
|
||||
sendMessage(serveroutput, "red",
|
||||
"-- Server restarting in " + restartcounter + " seconds!");
|
||||
Thread.sleep(1000);
|
||||
} else {
|
||||
restartcounter = RESTART_MESSAGE_COUNT;
|
||||
continue; // Don't decrement the counter so it will sleep the full time
|
||||
}
|
||||
} else {
|
||||
Thread.sleep(500);
|
||||
if (customrestartfailed) {
|
||||
writeToScreen("Stopping server for restart...");
|
||||
serveroutput.println("restart");
|
||||
serveroutput.flush();
|
||||
customrestartfailed = false;
|
||||
}
|
||||
Thread.sleep(5000); // Don't run needless cycles
|
||||
}
|
||||
restartcounter--;
|
||||
}
|
||||
} catch (InterruptedException e) { // The while checks if stop is true and then stops
|
||||
}
|
||||
}
|
||||
writeToScreen("Stopped " + Thread.currentThread().getName());
|
||||
}
|
||||
|
||||
private static Process startServer(Config config) throws IOException {
|
||||
return Runtime.getRuntime().exec(("java "+config.serverParams+" -jar spigot-" + config.serverVersion + ".jar").split(" "));
|
||||
}
|
||||
|
||||
private static void sendMessage(PrintWriter output, String color, String text) {
|
||||
output.println("tellraw @a {\"text\":\"" + text + "\",\"color\":\"" + color + "\"}");
|
||||
output.flush();
|
||||
writeToScreen(text);
|
||||
}
|
||||
|
||||
private static void stop() {
|
||||
stop = true;
|
||||
rt.interrupt(); // The restarter thread sleeps for a long time and keeps the program running
|
||||
}
|
||||
|
||||
private static void writeToScreen(String line) {
|
||||
stashLine();
|
||||
runnerout.println(line);
|
||||
unstashLine();
|
||||
}
|
||||
|
||||
private static CursorBuffer stashed;
|
||||
|
||||
private static void stashLine() {
|
||||
stashed = reader.getCursorBuffer().copy();
|
||||
try {
|
||||
reader.getOutput().write("\u001b[1G\u001b[K");
|
||||
reader.flush();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private static void unstashLine() {
|
||||
try {
|
||||
reader.resetPromptLine(reader.getPrompt(), stashed.toString(), stashed.cursor);
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private static double hoursOf(Calendar parsedTime) {
|
||||
return parsedTime.get(Calendar.HOUR_OF_DAY) + parsedTime.get(Calendar.MINUTE) / 60.
|
||||
+ parsedTime.get(Calendar.SECOND) / 3600.;
|
||||
}
|
||||
|
||||
private static long syncStart(double startHour) { // Copied original code from SimpleBackup
|
||||
double now = hoursOf(Calendar.getInstance(TimeZone.getTimeZone("GMT")));
|
||||
double diff = now - startHour;
|
||||
if (diff < 0) {
|
||||
diff += 24;
|
||||
}
|
||||
double intervalPart = diff - Math.floor(diff / interval) * interval;
|
||||
double remaining = interval - intervalPart;
|
||||
return (long) (remaining * 3600000);
|
||||
}
|
||||
|
||||
}
|
||||
package buttondevteam.serverrunner;
|
||||
|
||||
import jline.console.ConsoleReader;
|
||||
import jline.console.CursorBuffer;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ServerRunner {
|
||||
private static final int RESTART_MESSAGE_COUNT = 60;
|
||||
|
||||
private static final int interval = 24; // hours
|
||||
|
||||
private static volatile boolean stop = false;
|
||||
private static int restartcounter = RESTART_MESSAGE_COUNT;
|
||||
private static volatile Process serverprocess;
|
||||
private static volatile PrintWriter serveroutput;
|
||||
private static volatile Thread rt;
|
||||
private static volatile ConsoleReader reader;
|
||||
private static volatile PrintWriter runnerout;
|
||||
|
||||
private static volatile boolean customrestartfailed = false;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Yaml yaml = new Yaml();
|
||||
File f = new File("plugins/ServerRunner/config.yml");
|
||||
f.getParentFile().mkdirs();
|
||||
final Config config;
|
||||
if (!f.exists())
|
||||
Files.write(f.toPath(), Collections.singleton(yaml.dump(config = new Config())));
|
||||
else
|
||||
config = yaml.load(new FileInputStream(f));
|
||||
final File serverJar = new File(config.customJar == null || config.customJar.length() == 0
|
||||
? "spigot-" + config.serverVersion + ".jar"
|
||||
: config.customJar);
|
||||
if (!serverJar.exists()) {
|
||||
System.out.println("The server JAR for " + config.serverVersion + " cannot be found!");
|
||||
return;
|
||||
}
|
||||
reader = new ConsoleReader();
|
||||
reader.setPrompt("Runner>");
|
||||
runnerout = new PrintWriter(reader.getOutput());
|
||||
writeToScreen("Starting server...");
|
||||
serverprocess = startServer(config, serverJar);
|
||||
serveroutput = new PrintWriter(serverprocess.getOutputStream());
|
||||
rt = Thread.currentThread();
|
||||
final Thread it = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String readLine;
|
||||
while (!stop) {
|
||||
try {
|
||||
if ((readLine = reader.readLine()) == null)
|
||||
break;
|
||||
if (readLine.equalsIgnoreCase("stop"))
|
||||
ServerRunner.stop();
|
||||
serveroutput.println(readLine);
|
||||
serveroutput.flush();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Thread.sleep(100); //Sleep a bit and keep going
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ServerRunner.stop();
|
||||
writeToScreen("Stopped " + Thread.currentThread().getName());
|
||||
}
|
||||
};
|
||||
it.setName("InputThread");
|
||||
it.start();
|
||||
final Thread ot = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
BufferedReader serverinput = new BufferedReader(
|
||||
new InputStreamReader(serverprocess.getInputStream(), StandardCharsets.UTF_8));
|
||||
String line;
|
||||
while (true) {
|
||||
if ((line = serverinput.readLine()) != null) {
|
||||
writeToScreen(line);
|
||||
if (line.contains("FAILED TO BIND TO PORT")) {
|
||||
ServerRunner.stop();
|
||||
writeToScreen("A server is already running!");
|
||||
}
|
||||
if (Pattern.matches(
|
||||
"\\[\\d\\d:\\d\\d:\\d\\d INFO]: Unknown command. Type \"/help\" for help.\\s+", line))
|
||||
customrestartfailed = true;
|
||||
|
||||
} else if (!stop) {
|
||||
try {
|
||||
serverinput.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
serveroutput.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
writeToScreen("Server stopped! Restarting...");
|
||||
serverprocess = startServer(config, serverJar);
|
||||
serverinput = new BufferedReader(new InputStreamReader(serverprocess.getInputStream()));
|
||||
serveroutput = new PrintWriter(serverprocess.getOutputStream());
|
||||
restartcounter = RESTART_MESSAGE_COUNT;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
serverinput.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ServerRunner.stop();
|
||||
writeToScreen("Stopped " + Thread.currentThread().getName());
|
||||
}
|
||||
};
|
||||
ot.setName("OutputThread");
|
||||
ot.start();
|
||||
Thread.currentThread().setName("RestarterThread");
|
||||
long starttime = syncStart(config.restartAt);
|
||||
System.out.println("Restart scheduled in " + starttime / 3600000f);
|
||||
boolean firstrun = true;
|
||||
while (!stop) {
|
||||
try {
|
||||
if (restartcounter >= 0) {
|
||||
if (restartcounter == RESTART_MESSAGE_COUNT) {
|
||||
if (firstrun) {
|
||||
// writeToScreen("Sleeping for " + starttime);
|
||||
Thread.sleep(starttime);
|
||||
firstrun = false;
|
||||
} else
|
||||
Thread.sleep(interval * 3600000);
|
||||
customrestartfailed = false;
|
||||
serveroutput.println("schrestart");
|
||||
serveroutput.flush();
|
||||
} else if (restartcounter > 0) {
|
||||
if (customrestartfailed) {
|
||||
if (restartcounter % 10 == 0)
|
||||
sendMessage(serveroutput, "red",
|
||||
"-- Server restarting in " + restartcounter + " seconds!");
|
||||
Thread.sleep(1000);
|
||||
} else {
|
||||
restartcounter = RESTART_MESSAGE_COUNT;
|
||||
continue; // Don't decrement the counter so it will sleep the full time
|
||||
}
|
||||
} else {
|
||||
Thread.sleep(500);
|
||||
if (customrestartfailed) {
|
||||
writeToScreen("Stopping server for restart...");
|
||||
serveroutput.println("restart");
|
||||
serveroutput.flush();
|
||||
customrestartfailed = false;
|
||||
}
|
||||
Thread.sleep(5000); // Don't run needless cycles
|
||||
}
|
||||
restartcounter--;
|
||||
}
|
||||
} catch (InterruptedException e) { // The while checks if stop is true and then stops
|
||||
}
|
||||
}
|
||||
writeToScreen("Stopped " + Thread.currentThread().getName());
|
||||
}
|
||||
|
||||
private static Process startServer(Config config, File serverJar) throws IOException {
|
||||
return Runtime.getRuntime().exec(new String[]{"java", config.serverParams, "-jar", serverJar.getPath()});
|
||||
}
|
||||
|
||||
private static void sendMessage(PrintWriter output, String color, String text) {
|
||||
output.println("tellraw @a {\"text\":\"" + text + "\",\"color\":\"" + color + "\"}");
|
||||
output.flush();
|
||||
writeToScreen(text);
|
||||
}
|
||||
|
||||
private static void stop() {
|
||||
stop = true;
|
||||
rt.interrupt(); // The restarter thread sleeps for a long time and keeps the program running
|
||||
}
|
||||
|
||||
private static void writeToScreen(String line) {
|
||||
stashLine();
|
||||
runnerout.println(line);
|
||||
unstashLine();
|
||||
}
|
||||
|
||||
private static CursorBuffer stashed;
|
||||
|
||||
private static void stashLine() {
|
||||
stashed = reader.getCursorBuffer().copy();
|
||||
try {
|
||||
reader.getOutput().write("\u001b[1G\u001b[K");
|
||||
reader.flush();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private static void unstashLine() {
|
||||
try {
|
||||
reader.resetPromptLine(reader.getPrompt(), stashed.toString(), stashed.cursor);
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private static double hoursOf(Calendar parsedTime) {
|
||||
return parsedTime.get(Calendar.HOUR_OF_DAY) + parsedTime.get(Calendar.MINUTE) / 60.
|
||||
+ parsedTime.get(Calendar.SECOND) / 3600.;
|
||||
}
|
||||
|
||||
private static long syncStart(double startHour) { // Copied original code from SimpleBackup
|
||||
double now = hoursOf(Calendar.getInstance(TimeZone.getTimeZone("GMT")));
|
||||
double diff = now - startHour;
|
||||
if (diff < 0) {
|
||||
diff += 24;
|
||||
}
|
||||
double intervalPart = diff - Math.floor(diff / interval) * interval;
|
||||
double remaining = interval - intervalPart;
|
||||
return (long) (remaining * 3600000);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue