Plan/Plan/standalone/src/main/java/net/playeranalytics/plan/PlanStandalone.java

174 lines
6.7 KiB
Java

package net.playeranalytics.plan;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.PlanSystem;
import com.djrapitops.plan.commands.use.ColorScheme;
import com.djrapitops.plan.commands.use.Subcommand;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.*;
import com.djrapitops.plan.settings.config.paths.key.Setting;
import net.playeranalytics.plugin.StandalonePlatformAbstractionLayer;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
public class PlanStandalone implements PlanPlugin {
private static final Logger LOGGER = Logger.getGlobal();
private static final ScannerPrompter SCANNER_PROMPTER = new ScannerPrompter();
private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
private static PlanStandalone pluginInstance;
private PlanSystem system;
public static void main(String[] args) throws Exception {
LogManager.getLogManager().readConfiguration(PlanStandalone.class.getResourceAsStream("/logging.properties"));
LOGGER.info("Starting Plan..");
LOGGER.info("Type 'exit' at any time to stop the program.");
LOGGER.info(() -> "Java version: " + System.getProperty("java.version"));
LOGGER.info("");
pluginInstance = new PlanStandalone();
EXECUTOR_SERVICE.submit(pluginInstance::onEnable);
// Blocks and waits user input to the console
SCANNER_PROMPTER.enable();
}
public static void shutdown(int status) {
LOGGER.info("Stopping the program...");
if (pluginInstance != null) pluginInstance.onDisable();
SCANNER_PROMPTER.disable();
EXECUTOR_SERVICE.shutdown();
try {
if (!EXECUTOR_SERVICE.awaitTermination(5, TimeUnit.SECONDS)) {
EXECUTOR_SERVICE.shutdownNow();
}
} catch (InterruptedException e) {
LOGGER.info("Press enter to exit..");
System.exit(131);
Thread.currentThread().interrupt();
return;
}
if (status != 0) LOGGER.info("Press enter to exit..");
System.exit(status);
}
@Override
public InputStream getResource(String resource) {
try {
return pluginInstance.getSystem().getPlanFiles().getResourceFromJar(resource).asInputStream();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public ColorScheme getColorScheme() {
return new ColorScheme("", "", "");
}
@Override
public PlanSystem getSystem() {
return system;
}
@Override
public void registerCommand(Subcommand command) {
// no-op, unused
}
@Override
public void onEnable() {
try {
PlanStandaloneComponent component = DaggerPlanStandaloneComponent.builder()
.plan(this)
.abstractionLayer(new StandalonePlatformAbstractionLayer(LOGGER))
.build();
system = component.system();
system.enableForCommands();
PlanConfig config = system.getConfigSystem().getConfig();
config.set(WebserverSettings.DISABLED, false);
config.set(DataGatheringSettings.GEOLOCATIONS, false);
config.set(DataGatheringSettings.DISK_SPACE, false);
config.set(DataGatheringSettings.PING, false);
String ip = config.get(ProxySettings.IP);
if ("0.0.0.0".equals(ip)) {
// First installation, prompt for settings
LOGGER.info("\n--------------\n");
promptSetting(config, ProxySettings.IP, "Please enter IP / address to access this server");
promptSetting(config, DatabaseSettings.MYSQL_HOST, "Please enter MySQL address");
promptSetting(config, DatabaseSettings.MYSQL_PORT, "Please enter MySQL port");
promptSetting(config, DatabaseSettings.MYSQL_DATABASE, "Please enter MySQL database name/schema name");
promptSetting(config, DatabaseSettings.MYSQL_USER, "Please enter MySQL user");
promptSetting(config, DatabaseSettings.MYSQL_PASS, "Please enter MySQL password");
promptSettingInt(config, WebserverSettings.PORT, "Please enter Webserver port to use");
config.set(PluginSettings.SERVER_NAME, "Standalone Plan Instance");
LOGGER.info("Saving config..");
config.save();
LOGGER.info("\n--------------\n");
LOGGER.info("Config saved - proceeding with plugin enable..");
}
SCANNER_PROMPTER.insertCommands(component.planCommand());
} catch (Exception | Error e) {
LOGGER.log(Level.SEVERE, "Failed to enable commands" + e + ", program will exit\n", e);
shutdown(1);
}
try {
system.enable();
LOGGER.info("-- Startup complete, Plan enabled successfully!");
} catch (Exception | Error e) {
LOGGER.log(Level.SEVERE, "Failed to enable plugin " + e + ", you can try 'plan reload' after changing config settings.\n", e);
}
}
private void promptSetting(PlanConfig config, Setting<String> setting, String prompt) {
LOGGER.info(() -> prompt + " (" + setting.getPath() + " setting):");
String inputValue = SCANNER_PROMPTER.waitAndGetInput()
.orElseThrow(() -> new IllegalStateException("KeyboardInterrupt"));
config.set(setting, inputValue);
LOGGER.info(() -> "Set '" + setting.getPath() + "' as '" + inputValue + "'");
}
private void promptSettingInt(PlanConfig config, Setting<Integer> setting, String prompt) {
LOGGER.info(() -> prompt + " (" + setting.getPath() + " setting):");
String inputValue = SCANNER_PROMPTER.waitAndGetInput()
.orElseThrow(() -> new IllegalStateException("KeyboardInterrupt"));
try {
config.set(setting, Integer.parseInt(inputValue));
} catch (NumberFormatException invalid) {
LOGGER.warning("'" + inputValue + "' is not a valid number, try again");
promptSettingInt(config, setting, prompt);
return;
}
LOGGER.info(() -> "Set '" + setting.getPath() + "' as '" + inputValue + "'");
}
@Override
public void onDisable() {
if (system != null) system.disable();
}
@Override
public File getDataFolder() {
return pluginInstance.getSystem().getPlanFiles().getDataFolder();
}
}