Merge pull request #4157 from MovingBlocks/feat/picocli

BREAKING CHANGE: changes command line option punctuation to POSIX-style.
This commit is contained in:
Kevin Turner 2021-08-14 11:24:39 -07:00 committed by GitHub
commit c1c5b73422
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 115 additions and 220 deletions

View file

@ -7,6 +7,7 @@
</list>
<writeAnnotations>
<writeAnnotation name="org.terasology.engine.registry.In" />
<writeAnnotation name="picocli.CommandLine.Option" />
</writeAnnotations>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir -noCrashReport " />
<option name="PROGRAM_PARAMETERS" value="--homedir=. --no-crash-report" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m" />
<extension name="coverage">
@ -24,4 +24,4 @@
<option name="Gradle.BeforeRunTask" enabled="true" tasks="fetchModuleDependencies" externalProjectPath="$PROJECT_DIR$/modules" vmOptions="" scriptParameters="" />
</method>
</configuration>
</component>
</component>

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (2nd client)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir=terasology-2ndclient -noCrashReport" />
<option name="PROGRAM_PARAMETERS" value="--homedir=terasology-2ndclient --no-crash-report" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (3rd client)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir=terasology-3rdclient -noCrashReport" />
<option name="PROGRAM_PARAMETERS" value="--homedir=terasology-3rdclient --no-crash-report" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (CR enabled)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir" />
<option name="PROGRAM_PARAMETERS" value="--homedir=. --crash-report" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (EXTREME 8GB)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir -noCrashReport" />
<option name="PROGRAM_PARAMETERS" value="--homedir=. --no-crash-report" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx8192m" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (Headless)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-headless -homedir=terasology-server -overrideDefaultConfig=override.cfg" />
<option name="PROGRAM_PARAMETERS" value="--headless --homedir=terasology-server --override-default-config=override.cfg" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (Java FlightRecorder)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir -noCrashReport" />
<option name="PROGRAM_PARAMETERS" value="--homedir=. --no-crash-report" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:StartFlightRecording=filename=terasology.jfr,dumponexit=true" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (Splash disabled)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir -noCrashReport -noSplash" />
<option name="PROGRAM_PARAMETERS" value="--homedir=. --no-crash-report --no-splash" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (load latest)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir -noCrashReport -loadlastgame" />
<option name="PROGRAM_PARAMETERS" value="--homedir=. --no-crash-report --load-last-game" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (no audio)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir -noCrashReport -noSound" />
<option name="PROGRAM_PARAMETERS" value="--homedir=. --no-crash-report --no-sound" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (no saves)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir -noCrashReport -noSaveGames" />
<option name="PROGRAM_PARAMETERS" value="--homedir=. --no-crash-report --no-save-games" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (permissive security)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir -noCrashReport -permissiveSecurity" />
<option name="PROGRAM_PARAMETERS" value="--homedir=. --no-crash-report --permissive-security" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m -Djava.library.path=$PROJECT_DIR$/natives/linux" />
<extension name="coverage">

View file

@ -2,7 +2,7 @@
<configuration default="false" name="TerasologyPC (recreate latest)" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.terasology.engine.Terasology" />
<module name="Terasology.facades.PC.main" />
<option name="PROGRAM_PARAMETERS" value="-homedir -noCrashReport -createlastgame" />
<option name="PROGRAM_PARAMETERS" value="--homedir=. --no-crash-report --create-last-game" />
<shortenClasspath name="MANIFEST" />
<option name="VM_PARAMETERS" value="-Xms256m -Xmx1536m" />
<method v="2">

View file

@ -64,11 +64,11 @@ open class RunTerasology : JavaExec() {
classpath(project.the<SourceSetContainer>()["main"].runtimeClasspath)
dependsOn(project.configurations.named("modules"))
args("-homedir")
args("--homedir=.")
maxHeapSize = DEFAULT_MAX_HEAP_SIZE
if (isMacOS()) {
args("-noSplash")
args("--no-splash")
jvmArgs("-XstartOnFirstThread", "-Djava.awt.headless=true")
}
}

View file

@ -4,7 +4,7 @@ For more details on how to play Terasology, keep reading!
If you hit issues look for the game log files. By default they go into your user home directory, for instance `C:\Users\[username]\Saved Games\Terasology\logs` on Windows.
You can run the game with `-homedir` to instead store all game data in the directory you ran from. Or just use the [Launcher](https://github.com/MovingBlocks/TerasologyLauncher/releases) - it handles all that stuff!
You can run the game with `--homedir=.` to instead store all game data in the directory you ran from. Or just use the [Launcher](https://github.com/MovingBlocks/TerasologyLauncher/releases) - it handles all that stuff!
Report issues on [GitHub](https://github.com/MovingBlocks/Terasology/issues/new) or ask on [Discord](https://discord.com/channels/270264625419911192/713903952764207164).
@ -97,9 +97,9 @@ Unlike in single player in a multiplayer setting permissions are enforced for co
You can also run a headless server, but need to do so via command line, for example with a downloaded version:
`java -jar libs/Terasology.jar -headless -homedir=server`
`java -jar libs/Terasology.jar --headless --homedir=server`
This will launch the server and store game files in the "server" subdir at the place you launch from (otherwise it'll use the default path, which could clash with a client on the same system). You can add `-serverPort=#####` to run on a different port than default 25777.
This will launch the server and store game files in the "server" subdir at the place you launch from (otherwise it'll use the default path, which could clash with a client on the same system). You can add `--server-port=#####` to run on a different port than default 25777.
In this case *there is no default player with rights beyond "chat"*. You need to gain admin powers yourself using the `oneTimeAuthorizationKey` that generates in the server's `config.cfg`. This gives you all permission types except "debug"
@ -113,7 +113,7 @@ With *server* rights you can terminate the server gracefully via `shutdownServer
Finally to get modules configured for a headless server you either have to manually edit in a list of modules to the `defaultModSelection` section, and `defaultGenerator` for your chosen world, then delete the `saves` dir for the server and restart it. Start a single player world and look at the `config.cfg` that generates for hints.
It is also possible to provide a configuration file which overrides the default configuration on startup. This file can be passed using the `-overrideDefaultConfig=<pathToFile>`. Settings from this file will be copied to the generated `config.cfg`. After that changes in the `config.cfg` have priority, so further modifications in the override file will not modify the server values. It not required to pass an entire configuration file. A typical example would be:
It is also possible to provide a configuration file which overrides the default configuration on startup. This file can be passed using the `--override-default-config=<pathToFile>`. Settings from this file will be copied to the generated `config.cfg`. After that changes in the `config.cfg` have priority, so further modifications in the override file will not modify the server values. It not required to pass an entire configuration file. A typical example would be:
```
{

View file

@ -160,7 +160,7 @@ static PathManager setInstance(PathManager pathManager) {
* @throws IOException Thrown when required directories cannot be accessed.
*/
public void useOverrideHomePath(Path rootPath) throws IOException {
this.homePath = rootPath.toAbsolutePath();
this.homePath = rootPath.toRealPath();
updateDirs();
}

View file

@ -60,6 +60,9 @@ logger.info("PC VERSION: {}", version)
group = "org.terasology.facades"
dependencies {
implementation(group = "info.picocli", name = "picocli", version = "4.5.2")
annotationProcessor("info.picocli:picocli-codegen:4.5.2")
implementation(project(":engine"))
implementation(project(":subsystems:DiscordRPC"))
@ -67,6 +70,11 @@ dependencies {
implementation(group = "org.terasology.crashreporter", name = "cr-terasology", version = "4.1.0")
}
tasks.named<JavaCompile>("compileJava") {
// according to https://picocli.info/#_gradle_2
options.compilerArgs.add("-Aproject=${project.group}/${project.name}")
}
/****************************************
* Run Targets
*/
@ -93,14 +101,14 @@ tasks.register<RunTerasology>("debug") {
tasks.register<RunTerasology>("permissiveNatives") {
description = "Run 'Terasology' with security set to permissive and natives loading a second way (for KComputers)"
args("-permissiveSecurity")
args("--permissive-security")
systemProperty("java.library.path", rootProject.file(dirNatives + "/" + nativeSubdirectoryName()))
}
// TODO: Make a task to reset server / game data
tasks.register<RunTerasology>("server") {
description = "Starts a headless multiplayer server with data stored in [project-root]/$localServerDataPath"
args("-headless", "-homedir=$localServerDataPath")
args("--headless", "--homedir=$localServerDataPath")
}

View file

@ -1,10 +1,7 @@
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.crashreporter.CrashReporter;
@ -41,79 +38,87 @@
import org.terasology.splash.SplashScreen;
import org.terasology.splash.SplashScreenBuilder;
import org.terasology.subsystem.discordrpc.DiscordRPCSubSystem;
import picocli.CommandLine;
import picocli.CommandLine.Option;
import java.awt.GraphicsEnvironment;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Class providing the main() method for launching Terasology as a PC app.
* <br><br>
* <p>
* Through the following launch arguments default locations to store logs and game saves can be overridden, by using the
* current directory or a specified one as the home directory. Furthermore, Terasology can be launched headless, to save
* resources while acting as a server or to run in an environment with no graphics, audio or input support. Additional
* arguments are available to reload the latest game on startup and to disable crash reporting.
* <br><br>
* Available launch arguments:
* <br><br>
* <table summary="Launch arguments">
* <tbody>
* <tr><td>-homedir</td><td>Use the current directory as the home directory.</td></tr>
* <tr><td>-homedir=path</td><td>Use the specified path as the home directory.</td></tr>
* <tr><td>-headless</td><td>Start headless.</td></tr>
* <tr><td>-loadlastgame</td><td>Load the latest game on startup.</td></tr>
* <tr><td>-createlastgame</td><td>Recreates the world of the latest game with a new save file on startup.</td></tr>
* <tr><td>-noSaveGames</td><td>Disable writing of save games.</td></tr>
* <tr><td>-noCrashReport</td><td>Disable crash reporting.</td></tr>
* <tr><td>-noSound</td><td>Disable sound.</td></tr>
* <tr><td>-noSplash</td><td>Disable splash screen.</td></tr>
* <tr><td>-serverPort=xxxxx</td><td>Change the server port.</td></tr>
* </tbody>
* </table>
* <br><br>
* <p>
* When used via command line an usage help and some examples can be obtained via:
* <br><br>
* terasology -help or terasology /?
* <br><br>
* <p>
* terasology --help or terasology /?
*
*/
public final class Terasology {
private static final String[] PRINT_USAGE_FLAGS = {"--help", "-help", "/help", "-h", "/h", "-?", "/?"};
private static final String USE_CURRENT_DIR_AS_HOME = "-homedir";
private static final String USE_SPECIFIED_DIR_AS_HOME = "-homedir=";
private static final String START_HEADLESS = "-headless";
private static final String LOAD_LAST_GAME = "-loadlastgame";
private static final String CREATE_LAST_GAME = "-createlastgame";
private static final String NO_CRASH_REPORT = "-noCrashReport";
private static final String NO_SAVE_GAMES = "-noSaveGames";
private static final String PERMISSIVE_SECURITY = "-permissiveSecurity";
private static final String NO_SOUND = "-noSound";
private static final String NO_SPLASH = "-noSplash";
private static final String SERVER_PORT = "-serverPort=";
private static final String OVERRIDE_DEFAULT_CONFIG = "-overrideDefaultConfig=";
@CommandLine.Command(name = "terasology", usageHelpAutoWidth = true,
footer = "%nAlternatively use our standalone Launcher from%n https://github.com/MovingBlocks/TerasologyLauncher/releases")
public final class Terasology implements Callable<Integer> {
private static final Logger logger = LoggerFactory.getLogger(Terasology.class);
@CommandLine.Spec CommandLine.Model.CommandSpec spec;
private static boolean isHeadless;
private static boolean crashReportEnabled = true;
private static boolean soundEnabled = true;
private static boolean splashEnabled = true;
private static boolean loadLastGame;
private static boolean createLastGame;
@SuppressWarnings("unused")
@Option(names = {"--help", "-help", "/help", "-h", "/h", "-?", "/?"}, usageHelp = true, description = "show help")
private boolean helpRequested;
@Option(names = "--headless", description = "Start headless (no graphics)")
private boolean isHeadless;
@Option(names = "--crash-report", defaultValue = "true", negatable = true, description = "Enable crash reporting")
private boolean crashReportEnabled;
@Option(names = "--sound", defaultValue = "true", negatable = true, description = "Enable sound")
private boolean soundEnabled;
@Option(names = "--splash", defaultValue = "true", negatable = true, description = "Enable splash screen")
private boolean splashEnabled;
@Option(names = "--load-last-game", description = "Load the latest game on startup")
private boolean loadLastGame;
@Option(names = "--create-last-game", description = "Recreates the world of the latest game with a new save file on startup")
private boolean createLastGame;
@Option(names = "--permissive-security")
private boolean permissiveSecurity;
@Option(names = "--save-games", defaultValue = "true", negatable = true, description = "Enable new save games")
private boolean saveGamesEnabled;
@Option(names = "--server-port", description = "Change the server port")
private Integer serverPort;
@Option(names = "--override-default-config", description = "Override default config")
private Path overrideConfigPath;
@Option(names = "--homedir", description = "Path to home directory")
private Path homeDir;
private Terasology() {
}
public static void main(String[] args) {
new CommandLine(new Terasology()).execute(args);
}
handlePrintUsageRequest(args);
handleLaunchArguments(args);
@Override
public Integer call() throws IOException {
handleLaunchArguments();
setupLogging();
SplashScreen splashScreen;
if (splashEnabled) {
@ -124,6 +129,7 @@ public static void main(String[] args) {
thread.start();
try {
// wait splash initialize... we will lose some post messages otherwise.
//noinspection ResultOfMethodCallIgnored
splashInitLatch.await(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// ignore
@ -134,8 +140,6 @@ public static void main(String[] args) {
}
splashScreen.post("Java Runtime " + System.getProperty("java.version") + " loaded");
setupLogging();
try {
TerasologyEngineBuilder builder = new TerasologyEngineBuilder();
populateSubsystems(builder);
@ -183,6 +187,8 @@ public static void main(String[] args) {
splashScreen.close();
reportException(e);
}
return 0;
}
private static String getNewTitle(String title) {
@ -201,155 +207,35 @@ private static void setupLogging() {
LoggingContext.initialize(path);
}
private static void handlePrintUsageRequest(String[] args) {
for (String arg : args) {
for (String usageArg : PRINT_USAGE_FLAGS) {
if (usageArg.equalsIgnoreCase(arg)) {
printUsageAndExit();
}
}
private void handleLaunchArguments() throws IOException {
if (homeDir != null) {
logger.info("homeDir is {}", homeDir);
PathManager.getInstance().useOverrideHomePath(homeDir);
// TODO: what is this?
// PathManager.getInstance().chooseHomePathManually();
} else {
PathManager.getInstance().useDefaultHomePath();
}
if (isHeadless) {
crashReportEnabled = false;
splashEnabled = false;
}
if (!saveGamesEnabled) {
System.setProperty(SystemConfig.SAVED_GAMES_ENABLED_PROPERTY, "false");
}
if (permissiveSecurity) {
System.setProperty(SystemConfig.PERMISSIVE_SECURITY_ENABLED_PROPERTY, "true");
}
if (serverPort != null) {
System.setProperty(ConfigurationSubsystem.SERVER_PORT_PROPERTY, serverPort.toString());
}
if (overrideConfigPath != null) {
System.setProperty(Config.PROPERTY_OVERRIDE_DEFAULT_CONFIG, overrideConfigPath.toString());
}
}
private static void printUsageAndExit() {
String printUsageFlags = Joiner.on("|").join(PRINT_USAGE_FLAGS);
List<String> opts = ImmutableList.of(
printUsageFlags,
USE_CURRENT_DIR_AS_HOME + "|" + USE_SPECIFIED_DIR_AS_HOME + "<path>",
START_HEADLESS,
LOAD_LAST_GAME,
CREATE_LAST_GAME,
NO_CRASH_REPORT,
NO_SAVE_GAMES,
PERMISSIVE_SECURITY,
NO_SOUND,
NO_SPLASH,
OVERRIDE_DEFAULT_CONFIG + "<path>",
SERVER_PORT + "<port>");
StringBuilder optText = new StringBuilder();
for (String opt : opts) {
optText.append(" [").append(opt).append("]");
}
System.out.println("Usage:");
System.out.println();
System.out.println(" terasology" + optText.toString());
System.out.println();
System.out.println("By default Terasology saves data such as game saves and logs into subfolders of a platform-specific \"home " +
"directory\".");
System.out.println("Saving can be explicitly disabled using the \"" + NO_SAVE_GAMES + "\" flag.");
System.out.println("Optionally, the user can override the default by using one of the following launch arguments:");
System.out.println();
System.out.println(" " + USE_CURRENT_DIR_AS_HOME + " Use the current directory as the home directory.");
System.out.println(" " + USE_SPECIFIED_DIR_AS_HOME + "<path> Use the specified directory as the home directory.");
System.out.println();
System.out.println("It is also possible to start Terasology in headless mode (no graphics), i.e. to act as a server.");
System.out.println("For this purpose use the " + START_HEADLESS + " launch argument.");
System.out.println();
System.out.println("To automatically load the latest game on startup,");
System.out.println("use the " + LOAD_LAST_GAME + " launch argument.");
System.out.println();
System.out.println("To automatically recreate the last game played with a new save file,");
System.out.println("use the " + CREATE_LAST_GAME + "launch argument");
System.out.println();
System.out.println("By default Crash Reporting is enabled.");
System.out.println("To disable this feature use the " + NO_CRASH_REPORT + " launch argument.");
System.out.println();
System.out.println("To disable sound use the " + NO_SOUND + " launch argument (default in headless mode).");
System.out.println();
System.out.println("To disable the splash screen use the " + NO_SPLASH + " launch argument.");
System.out.println();
System.out.println("To change the port the server is hosted on use the " + SERVER_PORT + " launch argument.");
System.out.println();
System.out.println("To override the default generated config (useful for headless server) use the " + OVERRIDE_DEFAULT_CONFIG +
" launch argument");
System.out.println();
System.out.println("Examples:");
System.out.println();
System.out.println(" Use the current directory as the home directory:");
System.out.println(" terasology " + USE_CURRENT_DIR_AS_HOME);
System.out.println();
System.out.println(" Use \"myPath\" as the home directory:");
System.out.println(" terasology " + USE_SPECIFIED_DIR_AS_HOME + "myPath");
System.out.println();
System.out.println(" Start terasology in headless mode (no graphics) and enforce using the default port:");
System.out.println(" terasology " + START_HEADLESS + " " + SERVER_PORT + TerasologyConstants.DEFAULT_PORT);
System.out.println();
System.out.println(" Load the latest game on startup and disable crash reporting");
System.out.println(" terasology " + LOAD_LAST_GAME + " " + NO_CRASH_REPORT);
System.out.println();
System.out.println(" Don't start Terasology, just print this help:");
System.out.println(" terasology " + PRINT_USAGE_FLAGS[1]);
System.out.println();
System.out.println("Alternatively use our standalone Launcher from: https://github.com/MovingBlocks/TerasologyLauncher/releases");
System.out.println();
System.exit(0);
}
private static void handleLaunchArguments(String[] args) {
Path homePath = null;
for (String arg : args) {
boolean recognized = true;
if (arg.startsWith(USE_SPECIFIED_DIR_AS_HOME)) {
homePath = Paths.get(arg.substring(USE_SPECIFIED_DIR_AS_HOME.length()));
} else if (arg.equals(USE_CURRENT_DIR_AS_HOME)) {
homePath = Paths.get("");
} else if (arg.equals(START_HEADLESS)) {
isHeadless = true;
crashReportEnabled = false;
splashEnabled = false;
} else if (arg.equals(NO_SAVE_GAMES)) {
System.setProperty(SystemConfig.SAVED_GAMES_ENABLED_PROPERTY, "false");
} else if (arg.equals(PERMISSIVE_SECURITY)) {
System.setProperty(SystemConfig.PERMISSIVE_SECURITY_ENABLED_PROPERTY, "true");
} else if (arg.equals(NO_CRASH_REPORT)) {
crashReportEnabled = false;
} else if (arg.equals(NO_SOUND)) {
soundEnabled = false;
} else if (arg.equals(NO_SPLASH)) {
splashEnabled = false;
} else if (arg.equals(LOAD_LAST_GAME)) {
loadLastGame = true;
} else if (arg.equals(CREATE_LAST_GAME)) {
createLastGame = true;
} else if (arg.startsWith(SERVER_PORT)) {
System.setProperty(ConfigurationSubsystem.SERVER_PORT_PROPERTY, arg.substring(SERVER_PORT.length()));
} else if (arg.startsWith(OVERRIDE_DEFAULT_CONFIG)) {
System.setProperty(Config.PROPERTY_OVERRIDE_DEFAULT_CONFIG, arg.substring(OVERRIDE_DEFAULT_CONFIG.length()));
} else {
recognized = false;
}
System.out.println((recognized ? "Recognized" : "Invalid") + " argument: " + arg);
}
try {
if (homePath != null) {
PathManager.getInstance().useOverrideHomePath(homePath);
} else {
PathManager.getInstance().useDefaultHomePath();
}
} catch (IOException e) {
logger.warn("The game cannot detect default home directory");
try {
PathManager.getInstance().chooseHomePathManually();
} catch (IOException ex) {
reportException(ex);
System.exit(0);
}
}
}
private static void populateSubsystems(TerasologyEngineBuilder builder) {
private void populateSubsystems(TerasologyEngineBuilder builder) {
if (isHeadless) {
builder.add(new HeadlessGraphics())
.add(new HeadlessTimer())
@ -368,7 +254,7 @@ private static void populateSubsystems(TerasologyEngineBuilder builder) {
builder.add(new HibernationSubsystem());
}
private static void reportException(Throwable throwable) {
private void reportException(Throwable throwable) {
Path logPath = LoggingContext.getLoggingPath();
if (!GraphicsEnvironment.isHeadless() && crashReportEnabled) {