mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-25 08:44:45 +00:00
improve server side command line input (#415)
* improve server side command line input * prevent multiline logs from covering typed commands * reduce text in console * resolve conflicts caused by multilanguage Co-authored-by: Magix <kobedo11@gmail.com>
This commit is contained in:
parent
c930c637e4
commit
050784dfab
32
build.gradle
32
build.gradle
@ -60,27 +60,31 @@ repositories {
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'lib', include: ['*.jar'])
|
||||
|
||||
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.32'
|
||||
implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.2.9'
|
||||
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.32'
|
||||
implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.2.9'
|
||||
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.9'
|
||||
|
||||
implementation group: 'io.netty', name: 'netty-all', version: '4.1.71.Final'
|
||||
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.8'
|
||||
implementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.18.2'
|
||||
|
||||
implementation group: 'org.reflections', name: 'reflections', version: '0.10.2'
|
||||
|
||||
implementation group: 'dev.morphia.morphia', name: 'morphia-core', version: '2.2.6'
|
||||
implementation group: 'org.jline', name: 'jline', version: '3.21.0'
|
||||
implementation group: 'org.jline', name: 'jline-terminal-jna', version: '3.21.0'
|
||||
implementation group: 'net.java.dev.jna', name: 'jna', version: '5.10.0'
|
||||
|
||||
implementation group: 'io.netty', name: 'netty-all', version: '4.1.71.Final'
|
||||
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.8'
|
||||
implementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.18.2'
|
||||
|
||||
implementation group: 'org.reflections', name: 'reflections', version: '0.10.2'
|
||||
|
||||
implementation group: 'dev.morphia.morphia', name: 'morphia-core', version: '2.2.6'
|
||||
|
||||
implementation group: 'org.greenrobot', name: 'eventbus-java', version: '3.3.1'
|
||||
implementation group: 'org.danilopianini', name: 'java-quadtree', version: '0.1.9'
|
||||
|
||||
implementation group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.2'
|
||||
implementation group: 'org.quartz-scheduler', name: 'quartz-jobs', version: '2.3.2'
|
||||
|
||||
|
||||
implementation group: 'org.luaj', name: 'luaj-jse', version: '3.0.1'
|
||||
|
||||
|
||||
protobuf files('proto/')
|
||||
}
|
||||
|
||||
@ -107,8 +111,8 @@ jar {
|
||||
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
||||
|
||||
from('src/main/java') {
|
||||
include '*.xml'
|
||||
}
|
||||
include '*.xml'
|
||||
}
|
||||
|
||||
destinationDir = file(".")
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
package emu.grasscutter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOError;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Calendar;
|
||||
|
||||
@ -13,6 +12,12 @@ import emu.grasscutter.plugin.PluginManager;
|
||||
import emu.grasscutter.plugin.api.ServerHook;
|
||||
import emu.grasscutter.scripts.ScriptLoader;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import org.jline.reader.EndOfFileException;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.LineReaderBuilder;
|
||||
import org.jline.reader.UserInterruptException;
|
||||
import org.jline.terminal.Terminal;
|
||||
import org.jline.terminal.TerminalBuilder;
|
||||
import org.reflections.Reflections;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -30,8 +35,9 @@ import emu.grasscutter.utils.Crypto;
|
||||
public final class Grasscutter {
|
||||
private static final Logger log = (Logger) LoggerFactory.getLogger(Grasscutter.class);
|
||||
private static Config config;
|
||||
private static LineReader consoleLineReader = null;
|
||||
private static Language language;
|
||||
|
||||
|
||||
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
private static final File configFile = new File("./config.json");
|
||||
|
||||
@ -108,11 +114,12 @@ public final class Grasscutter {
|
||||
|
||||
// Enable all plugins.
|
||||
pluginManager.enablePlugins();
|
||||
|
||||
// Open console.
|
||||
startConsole();
|
||||
|
||||
// Hook into shutdown event.
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(Grasscutter::onShutdown));
|
||||
|
||||
// Open console.
|
||||
startConsole();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,7 +129,7 @@ public final class Grasscutter {
|
||||
// Disable all plugins.
|
||||
pluginManager.disablePlugins();
|
||||
}
|
||||
|
||||
|
||||
public static void loadConfig() {
|
||||
try (FileReader file = new FileReader(configFile)) {
|
||||
config = gson.fromJson(file, Config.class);
|
||||
@ -167,23 +174,40 @@ public final class Grasscutter {
|
||||
}
|
||||
|
||||
public static void startConsole() {
|
||||
String input;
|
||||
// Console should not start in dispatch only mode.
|
||||
if (getConfig().RunMode == ServerRunMode.DISPATCH_ONLY) {
|
||||
getLogger().info(language.Dispatch_mode_not_support_command);
|
||||
return;
|
||||
}
|
||||
|
||||
getLogger().info(language.Start_done);
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
|
||||
while ((input = br.readLine()) != null) {
|
||||
try {
|
||||
if (getConfig().RunMode == ServerRunMode.DISPATCH_ONLY) {
|
||||
getLogger().error(language.Dispatch_mode_not_support_command);
|
||||
return;
|
||||
}
|
||||
|
||||
CommandMap.getInstance().invoke(null, input);
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error(language.Command_error, e);
|
||||
String input = null;
|
||||
boolean isLastInterrupted = false;
|
||||
while (true) {
|
||||
try {
|
||||
input = consoleLineReader.readLine("> ");
|
||||
} catch (UserInterruptException e) {
|
||||
if (!isLastInterrupted) {
|
||||
isLastInterrupted = true;
|
||||
Grasscutter.getLogger().info("Press Ctrl-C again to shutdown.");
|
||||
continue;
|
||||
} else {
|
||||
Runtime.getRuntime().exit(0);
|
||||
}
|
||||
} catch (EndOfFileException e) {
|
||||
Grasscutter.getLogger().info("EOF detected.");
|
||||
continue;
|
||||
} catch (IOError e) {
|
||||
Grasscutter.getLogger().error("An IO error occurred.", e);
|
||||
continue;
|
||||
}
|
||||
|
||||
isLastInterrupted = false;
|
||||
try {
|
||||
CommandMap.getInstance().invoke(null, input);
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error(language.Command_error, e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error(language.Error, e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,6 +223,26 @@ public final class Grasscutter {
|
||||
return log;
|
||||
}
|
||||
|
||||
public static LineReader getConsole() {
|
||||
if (consoleLineReader == null) {
|
||||
Terminal terminal = null;
|
||||
try {
|
||||
terminal = TerminalBuilder.builder().jna(true).build();
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
// Fallback to a dumb jline terminal.
|
||||
terminal = TerminalBuilder.builder().dumb(true).build();
|
||||
} catch (Exception ignored) {
|
||||
// When dumb is true, build() never throws.
|
||||
}
|
||||
}
|
||||
consoleLineReader = LineReaderBuilder.builder()
|
||||
.terminal(terminal)
|
||||
.build();
|
||||
}
|
||||
return consoleLineReader;
|
||||
}
|
||||
|
||||
public static Gson getGsonFactory() {
|
||||
return gson;
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.utils;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.ConsoleAppender;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import org.jline.reader.LineReader;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class JlineLogbackAppender extends ConsoleAppender<ILoggingEvent> {
|
||||
@Override
|
||||
protected void append(ILoggingEvent eventObject) {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
Arrays.stream(
|
||||
new String(encoder.encode(eventObject)).split("\n")
|
||||
).forEach(Grasscutter.getConsole()::printAbove);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<Configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<appender name="STDOUT" class="emu.grasscutter.utils.JlineLogbackAppender">
|
||||
<encoder>
|
||||
<pattern>[%d{HH:mm:ss}] [%highlight(%level)] %msg%n</pattern>
|
||||
</encoder>
|
||||
|
Loading…
Reference in New Issue
Block a user