Initial version of standalone
- Prompts settings on enable - Runs with MySQL pretending to be a new game server in the database - Works pretty well for first attempt at it. A lot of inspiration was taken from the mock version of the system used during tests. TODO: - Doesn't have commands implemented yet - Doesn't log errors properly - Doesn't log console contents to a file - Network page needs to be accessible if proxy server is in database
This commit is contained in:
parent
3b09fd8da2
commit
925906bec6
|
@ -48,7 +48,6 @@ public abstract class ServerInfo implements SubSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerIdentifier getServerIdentifier() {
|
public ServerIdentifier getServerIdentifier() {
|
||||||
Server server = getServer();
|
|
||||||
return new ServerIdentifier(server.getUuid(), server.getIdentifiableName());
|
return new ServerIdentifier(server.getUuid(), server.getIdentifiableName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,18 +8,21 @@ dependencies {
|
||||||
shadow project(path: ":sponge")
|
shadow project(path: ":sponge")
|
||||||
shadow project(path: ":bungeecord")
|
shadow project(path: ":bungeecord")
|
||||||
shadow project(path: ":velocity")
|
shadow project(path: ":velocity")
|
||||||
|
shadow project(path: ":standalone")
|
||||||
testImplementation project(path: ":common", configuration: 'testArtifacts')
|
testImplementation project(path: ":common", configuration: 'testArtifacts')
|
||||||
testImplementation project(path: ":bukkit", configuration: 'testArtifacts')
|
testImplementation project(path: ":bukkit", configuration: 'testArtifacts')
|
||||||
testImplementation project(path: ":nukkit", configuration: 'testArtifacts')
|
testImplementation project(path: ":nukkit", configuration: 'testArtifacts')
|
||||||
testImplementation project(path: ":sponge", configuration: 'testArtifacts')
|
testImplementation project(path: ":sponge", configuration: 'testArtifacts')
|
||||||
testImplementation project(path: ":bungeecord", configuration: 'testArtifacts')
|
testImplementation project(path: ":bungeecord", configuration: 'testArtifacts')
|
||||||
testImplementation project(path: ":velocity", configuration: 'testArtifacts')
|
testImplementation project(path: ":velocity", configuration: 'testArtifacts')
|
||||||
|
testImplementation project(path: ":standalone", configuration: 'testArtifacts')
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
// Add the sponge mixin into the manifest
|
// Add the sponge mixin into the manifest
|
||||||
manifest.attributes([
|
manifest.attributes([
|
||||||
'MixinConfigs': 'plan-sponge.mixins.json'
|
'MixinConfigs': 'plan-sponge.mixins.json',
|
||||||
|
'Main-Class' : 'net.playeranalytics.plan.PlanStandalone'
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
plugins {
|
|
||||||
id "net.kyori.blossom" version "1.3.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly project(":common")
|
implementation project(":api")
|
||||||
implementation project(path: ":common", configuration: 'shadow')
|
implementation project(":common")
|
||||||
compileOnly project(":api")
|
|
||||||
|
|
||||||
testImplementation project(path: ":common", configuration: 'testArtifacts')
|
shadow "net.playeranalytics:platform-abstraction-layer-api:$palVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
configurations = [project.configurations.shadow]
|
||||||
}
|
}
|
|
@ -1,14 +1,173 @@
|
||||||
package net.playeranalytics.plan;
|
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;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class PlanStandalone {
|
public class PlanStandalone implements PlanPlugin {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger("Plan");
|
private static final Logger LOGGER = Logger.getGlobal();
|
||||||
|
|
||||||
public static void main(String[] args) {
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,26 @@ package net.playeranalytics.plan;
|
||||||
|
|
||||||
import com.djrapitops.plan.PlanSystem;
|
import com.djrapitops.plan.PlanSystem;
|
||||||
import com.djrapitops.plan.commands.PlanCommand;
|
import com.djrapitops.plan.commands.PlanCommand;
|
||||||
|
import com.djrapitops.plan.modules.FiltersModule;
|
||||||
|
import com.djrapitops.plan.modules.PlatformAbstractionLayerModule;
|
||||||
import dagger.BindsInstance;
|
import dagger.BindsInstance;
|
||||||
import dagger.Component;
|
import dagger.Component;
|
||||||
|
import net.playeranalytics.plan.module.StandaloneBindingModule;
|
||||||
|
import net.playeranalytics.plan.module.StandaloneProvidingModule;
|
||||||
|
import net.playeranalytics.plan.module.StandaloneServerPropertiesModule;
|
||||||
|
import net.playeranalytics.plugin.PlatformAbstractionLayer;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Component(modules = {
|
||||||
|
PlatformAbstractionLayerModule.class,
|
||||||
|
FiltersModule.class,
|
||||||
|
|
||||||
|
StandaloneBindingModule.class,
|
||||||
|
StandaloneProvidingModule.class,
|
||||||
|
StandaloneServerPropertiesModule.class
|
||||||
|
})
|
||||||
public interface PlanStandaloneComponent {
|
public interface PlanStandaloneComponent {
|
||||||
|
|
||||||
PlanCommand planCommand();
|
PlanCommand planCommand();
|
||||||
|
@ -17,6 +34,9 @@ public interface PlanStandaloneComponent {
|
||||||
@BindsInstance
|
@BindsInstance
|
||||||
Builder plan(PlanStandalone plan);
|
Builder plan(PlanStandalone plan);
|
||||||
|
|
||||||
|
@BindsInstance
|
||||||
|
Builder abstractionLayer(PlatformAbstractionLayer abstractionLayer);
|
||||||
|
|
||||||
PlanStandaloneComponent build();
|
PlanStandaloneComponent build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plan;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.SubSystem;
|
||||||
|
import com.djrapitops.plan.commands.PlanCommand;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author AuroraLS3
|
||||||
|
*/
|
||||||
|
public class ScannerPrompter implements SubSystem {
|
||||||
|
|
||||||
|
private final AtomicBoolean shutdown = new AtomicBoolean(false);
|
||||||
|
private final AtomicReference<String> scannedLine = new AtomicReference<>();
|
||||||
|
private Scanner scanner;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
scanner = new Scanner(System.in);
|
||||||
|
while (!shutdown.get() && scanner.hasNext()) {
|
||||||
|
synchronized (scannedLine) {
|
||||||
|
String scanned = scanner.nextLine();
|
||||||
|
|
||||||
|
if (StringUtils.equalsAny(scanned, "stop", "end", "quit", "exit")) {
|
||||||
|
PlanStandalone.shutdown(0);
|
||||||
|
return; // Ends the loop
|
||||||
|
}
|
||||||
|
|
||||||
|
scannedLine.set(scanned);
|
||||||
|
scannedLine.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
scanner.close();
|
||||||
|
shutdown.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<String> waitAndGetInput() {
|
||||||
|
try {
|
||||||
|
String scanned = "";
|
||||||
|
while (scanned.trim().isEmpty()) {
|
||||||
|
synchronized (scannedLine) {
|
||||||
|
scannedLine.wait();
|
||||||
|
scanned = scannedLine.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.of(scanned);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
PlanStandalone.shutdown(132);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertCommands(PlanCommand planCommand) {
|
||||||
|
// TODO enable commands
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plan.gathering;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.PlanPlugin;
|
||||||
|
import com.djrapitops.plan.gathering.listeners.ListenerSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author AuroraLS3
|
||||||
|
*/
|
||||||
|
public class NoOpListenerSystem extends ListenerSystem {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerListeners() {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void unregisterListeners() {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void callEnableEvent(PlanPlugin plugin) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plan.gathering;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.gathering.ServerSensor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author AuroraLS3
|
||||||
|
*/
|
||||||
|
public class NoOpServerSensor implements ServerSensor<Object> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsDirectTPS() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOnlinePlayerCount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plan.module;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.PlanPlugin;
|
||||||
|
import com.djrapitops.plan.delivery.webserver.cache.JSONFileStorage;
|
||||||
|
import com.djrapitops.plan.delivery.webserver.cache.JSONStorage;
|
||||||
|
import com.djrapitops.plan.delivery.webserver.http.JettyWebserver;
|
||||||
|
import com.djrapitops.plan.delivery.webserver.http.WebServer;
|
||||||
|
import com.djrapitops.plan.identification.ServerInfo;
|
||||||
|
import com.djrapitops.plan.identification.ServerServerInfo;
|
||||||
|
import com.djrapitops.plan.settings.ConfigSystem;
|
||||||
|
import com.djrapitops.plan.settings.ProxyConfigSystem;
|
||||||
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
|
import dagger.Binds;
|
||||||
|
import dagger.Module;
|
||||||
|
import net.playeranalytics.plan.PlanStandalone;
|
||||||
|
import net.playeranalytics.plan.utilities.logging.StandaloneErrorLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author AuroraLS3
|
||||||
|
*/
|
||||||
|
@Module
|
||||||
|
public interface StandaloneBindingModule {
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
PlanPlugin bindPlugin(PlanStandalone plugin);
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
ServerInfo bindServerInfo(ServerServerInfo serverServerInfo);
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
ConfigSystem bindConfigSystem(ProxyConfigSystem configSystem);
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
JSONStorage bindJSONStorage(JSONFileStorage jsonFileStorage);
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
WebServer bindWebserver(JettyWebserver webServer);
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
ErrorLogger bindErrorLogger(StandaloneErrorLogger standaloneErrorLogger);
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plan.module;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.TaskSystem;
|
||||||
|
import com.djrapitops.plan.gathering.ServerSensor;
|
||||||
|
import com.djrapitops.plan.gathering.importing.importers.Importer;
|
||||||
|
import com.djrapitops.plan.gathering.listeners.ListenerSystem;
|
||||||
|
import com.djrapitops.plan.settings.config.ExtensionSettings;
|
||||||
|
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||||
|
import com.djrapitops.plan.settings.locale.Locale;
|
||||||
|
import com.djrapitops.plan.settings.locale.LocaleSystem;
|
||||||
|
import com.djrapitops.plan.storage.database.DBSystem;
|
||||||
|
import com.djrapitops.plan.storage.database.DBType;
|
||||||
|
import com.djrapitops.plan.storage.database.MySQLDB;
|
||||||
|
import com.djrapitops.plan.storage.database.SQLiteDB;
|
||||||
|
import com.djrapitops.plan.storage.file.JarResource;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
import dagger.multibindings.ElementsIntoSet;
|
||||||
|
import net.playeranalytics.plan.gathering.NoOpListenerSystem;
|
||||||
|
import net.playeranalytics.plan.gathering.NoOpServerSensor;
|
||||||
|
import net.playeranalytics.plugin.PluginInformation;
|
||||||
|
import net.playeranalytics.plugin.server.PluginLogger;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author AuroraLS3
|
||||||
|
*/
|
||||||
|
@Module
|
||||||
|
public class StandaloneProvidingModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
DBSystem provideDatabaseSystem(
|
||||||
|
PlanConfig config,
|
||||||
|
Locale locale,
|
||||||
|
SQLiteDB.Factory sqLiteDB,
|
||||||
|
MySQLDB mySQLDB,
|
||||||
|
PluginLogger logger
|
||||||
|
) {
|
||||||
|
return new DBSystem(config, locale, sqLiteDB, logger) {
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
databases.add(mySQLDB);
|
||||||
|
db = getActiveDatabaseByName(DBType.MYSQL.getConfigName());
|
||||||
|
super.enable();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@ElementsIntoSet
|
||||||
|
Set<Importer> provideEmptyImporterSet() {
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@ElementsIntoSet
|
||||||
|
Set<TaskSystem.Task> provideEmptyTaskSet() {
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ListenerSystem provideListenerSystem() {
|
||||||
|
return new NoOpListenerSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ServerSensor<?> provideServerSensor() {
|
||||||
|
return new NoOpServerSensor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named("mainCommandName")
|
||||||
|
String provideMainCommandName() {
|
||||||
|
return "plan";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
Gson provideGson() {
|
||||||
|
return new Gson();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
Locale provideLocale(LocaleSystem localeSystem) {
|
||||||
|
return localeSystem.getLocale();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ExtensionSettings providePluginsConfigSection(PlanConfig config) {
|
||||||
|
return config.getExtensionSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named("isExtensionEnabled")
|
||||||
|
Predicate<String> provideExtensionEnabledConfigCheck(PlanConfig config) {
|
||||||
|
return config.getExtensionSettings()::isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
JarResource.StreamFunction provideJarStreamFunction(PluginInformation information) {
|
||||||
|
return information::getResourceFromJar;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named("dataFolder")
|
||||||
|
File provideDataFolder(PluginInformation information) {
|
||||||
|
return information.getDataFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plan.module;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.identification.properties.ServerProperties;
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author AuroraLS3
|
||||||
|
*/
|
||||||
|
@Module
|
||||||
|
public class StandaloneServerPropertiesModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ServerProperties provideServerProperties() {
|
||||||
|
return new ServerProperties(
|
||||||
|
"Standalone Java",
|
||||||
|
0,
|
||||||
|
"Java " + System.getProperty("java.version"),
|
||||||
|
"",
|
||||||
|
() -> new InetSocketAddress(25565).getAddress().getHostAddress(),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plan.utilities.logging;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||||
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
|
import net.playeranalytics.plan.PlanStandalone;
|
||||||
|
import net.playeranalytics.plugin.server.PluginLogger;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author AuroraLS3
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class StandaloneErrorLogger implements ErrorLogger {
|
||||||
|
|
||||||
|
private final PluginLogger logger;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public StandaloneErrorLogger(PluginLogger logger) {
|
||||||
|
this.logger = logger;
|
||||||
|
// TODO Extract file logging properties of PluginErrorLogger without PlanPlugin as dependency.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void critical(Throwable throwable, ErrorContext context) {
|
||||||
|
error(throwable, context);
|
||||||
|
PlanStandalone.shutdown(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(Throwable throwable, ErrorContext context) {
|
||||||
|
logger.error("", throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(Throwable throwable, ErrorContext context) {
|
||||||
|
logger.warn("", throwable);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,23 +1,36 @@
|
||||||
package net.playeranalytics.plugin;
|
package net.playeranalytics.plugin;
|
||||||
|
|
||||||
|
import net.playeranalytics.plugin.information.StandalonePluginInformation;
|
||||||
import net.playeranalytics.plugin.scheduling.RunnableFactory;
|
import net.playeranalytics.plugin.scheduling.RunnableFactory;
|
||||||
|
import net.playeranalytics.plugin.scheduling.StandaloneRunnableFactory;
|
||||||
import net.playeranalytics.plugin.server.JavaUtilPluginLogger;
|
import net.playeranalytics.plugin.server.JavaUtilPluginLogger;
|
||||||
import net.playeranalytics.plugin.server.Listeners;
|
import net.playeranalytics.plugin.server.Listeners;
|
||||||
import net.playeranalytics.plugin.server.PluginLogger;
|
import net.playeranalytics.plugin.server.PluginLogger;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class StandalonePlatformAbstractionLayer implements PlatformAbstractionLayer {
|
public class StandalonePlatformAbstractionLayer implements PlatformAbstractionLayer {
|
||||||
|
|
||||||
private final PluginLogger logger;
|
private final PluginLogger logger;
|
||||||
|
private final StandaloneRunnableFactory runnableFactory;
|
||||||
|
private final StandalonePluginInformation pluginInformation;
|
||||||
|
private final Listeners listeners;
|
||||||
|
|
||||||
public StandalonePlatformAbstractionLayer(Logger logger) {this.logger = new JavaUtilPluginLogger(logger);}
|
public StandalonePlatformAbstractionLayer(Logger logger) {
|
||||||
|
this.logger = new JavaUtilPluginLogger(logger);
|
||||||
|
runnableFactory = new StandaloneRunnableFactory();
|
||||||
|
pluginInformation = new StandalonePluginInformation();
|
||||||
|
listeners = new Listeners() {
|
||||||
|
@Override
|
||||||
|
public void registerListener(Object o) {/*no-op*/}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregisterListener(Object o) {/*no-op*/}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregisterListeners() {/*no-op*/}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PluginLogger getPluginLogger() {
|
public PluginLogger getPluginLogger() {
|
||||||
|
@ -26,53 +39,16 @@ public class StandalonePlatformAbstractionLayer implements PlatformAbstractionLa
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Listeners getListeners() {
|
public Listeners getListeners() {
|
||||||
return new Listeners() {
|
return listeners;
|
||||||
@Override
|
|
||||||
public void registerListener(Object o) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unregisterListener(Object o) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unregisterListeners() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RunnableFactory getRunnableFactory() {
|
public RunnableFactory getRunnableFactory() {
|
||||||
return null;
|
return runnableFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PluginInformation getPluginInformation() {
|
public PluginInformation getPluginInformation() {
|
||||||
return new PluginInformation() {
|
return pluginInformation;
|
||||||
@Override
|
|
||||||
public InputStream getResourceFromJar(String s) {
|
|
||||||
return getClass().getResourceAsStream(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public File getDataFolder() {
|
|
||||||
return new File("Plan");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getVersion() {
|
|
||||||
try {
|
|
||||||
return readVersionFromPluginYml();
|
|
||||||
} catch (IOException | URISyntaxException e) {
|
|
||||||
return e.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String readVersionFromPluginYml() throws IOException, URISyntaxException {
|
|
||||||
String pluginYmlContents = new String(Files.readAllBytes(new File(getClass().getResource("plugin.yml").toURI()).toPath()));
|
|
||||||
String versionHalf = StringUtils.split(pluginYmlContents, "version:")[1];
|
|
||||||
return StringUtils.split(versionHalf, "\n")[0];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plugin.information;
|
||||||
|
|
||||||
|
import net.playeranalytics.plugin.PluginInformation;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author AuroraLS3
|
||||||
|
*/
|
||||||
|
public class StandalonePluginInformation implements PluginInformation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getResourceFromJar(String resourceName) {
|
||||||
|
return getClass().getResourceAsStream("/" + resourceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getDataFolder() {
|
||||||
|
return new File("Plan");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersion() {
|
||||||
|
return readVersionFromPluginYml();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readVersionFromPluginYml() {
|
||||||
|
String pluginYmlContents = readAllBytes("plugin.yml");
|
||||||
|
for (String line : StringUtils.split(pluginYmlContents, "\n")) {
|
||||||
|
if (line.contains("version")) {
|
||||||
|
return StringUtils.split(line, ":")[1].trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "Missing plugin.yml";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readAllBytes(String resource) {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
try (InputStream inStream = getResourceFromJar(resource); buffer) {
|
||||||
|
int nRead;
|
||||||
|
byte[] data = new byte[16384];
|
||||||
|
|
||||||
|
while ((nRead = inStream.read(data, 0, data.length)) != -1) {
|
||||||
|
buffer.write(data, 0, nRead);
|
||||||
|
}
|
||||||
|
buffer.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedIOException(e);
|
||||||
|
}
|
||||||
|
return buffer.toString(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plugin.scheduling;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
|
public class StandaloneRunnableFactory implements RunnableFactory {
|
||||||
|
|
||||||
|
private final Set<StandaloneTask> tasks;
|
||||||
|
private ScheduledExecutorService executorService;
|
||||||
|
|
||||||
|
public StandaloneRunnableFactory() {
|
||||||
|
this.executorService = Executors.newScheduledThreadPool(8);
|
||||||
|
this.tasks = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UnscheduledTask create(Runnable runnable) {
|
||||||
|
return new UnscheduledStandaloneTask(getExecutorService(), runnable, task -> {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScheduledExecutorService getExecutorService() {
|
||||||
|
if (executorService.isShutdown() || executorService.isTerminated()) {
|
||||||
|
// Hacky way of fixing tasks when plugin is disabled, leaks one thread every reload.
|
||||||
|
executorService = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
}
|
||||||
|
return executorService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UnscheduledTask create(PluginRunnable runnable) {
|
||||||
|
return new UnscheduledStandaloneTask(getExecutorService(), runnable, runnable::setCancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelAllKnownTasks() {
|
||||||
|
this.tasks.forEach(Task::cancel);
|
||||||
|
this.tasks.clear();
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plugin.scheduling;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class StandaloneTask implements Task {
|
||||||
|
|
||||||
|
private final Future<?> task;
|
||||||
|
|
||||||
|
public StandaloneTask(Future<?> task) {
|
||||||
|
this.task = task;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGameThread() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
task.cancel(false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.playeranalytics.plugin.scheduling;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class UnscheduledStandaloneTask implements UnscheduledTask {
|
||||||
|
|
||||||
|
private final ScheduledExecutorService scheduler;
|
||||||
|
private final Runnable runnable;
|
||||||
|
private final Consumer<Task> cancellableConsumer;
|
||||||
|
|
||||||
|
public UnscheduledStandaloneTask(ScheduledExecutorService scheduler, Runnable runnable, Consumer<Task> cancellableConsumer) {
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
this.runnable = runnable;
|
||||||
|
this.cancellableConsumer = cancellableConsumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task runTaskAsynchronously() {
|
||||||
|
StandaloneTask task = new StandaloneTask(this.scheduler.submit(this.runnable));
|
||||||
|
cancellableConsumer.accept(task);
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task runTaskLaterAsynchronously(long delayTicks) {
|
||||||
|
StandaloneTask task = new StandaloneTask(this.scheduler.schedule(
|
||||||
|
this.runnable,
|
||||||
|
delayTicks * 50,
|
||||||
|
TimeUnit.MILLISECONDS
|
||||||
|
));
|
||||||
|
cancellableConsumer.accept(task);
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task runTaskTimerAsynchronously(long delayTicks, long periodTicks) {
|
||||||
|
StandaloneTask task = new StandaloneTask(this.scheduler.scheduleAtFixedRate(
|
||||||
|
runnable,
|
||||||
|
delayTicks * 50,
|
||||||
|
periodTicks * 50,
|
||||||
|
TimeUnit.MILLISECONDS
|
||||||
|
));
|
||||||
|
cancellableConsumer.accept(task);
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task runTask() {
|
||||||
|
return runTaskAsynchronously();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task runTaskLater(long delayTicks) {
|
||||||
|
return runTaskLaterAsynchronously(delayTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task runTaskTimer(long delayTicks, long periodTicks) {
|
||||||
|
return runTaskTimerAsynchronously(delayTicks, periodTicks);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
handlers=java.util.logging.ConsoleHandler
|
||||||
|
.level=INFO
|
||||||
|
java.util.logging.ConsoleHandler.level=INFO
|
||||||
|
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
|
||||||
|
java.util.logging.SimpleFormatter.format=[%1$tF %1$tT] %4$-7s : %5$s %n
|
Loading…
Reference in New Issue