mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 11:39:11 +03:00
[FEATURE] Support virtual threads and client locks
This commit is contained in:
parent
34ac6a0f28
commit
7060697bad
21 changed files with 222 additions and 144 deletions
|
@ -422,21 +422,6 @@ public void syncUpdatesDir(Collection<String> dirs) throws IOException {
|
||||||
updatesManager.syncUpdatesDir(dirs);
|
updatesManager.syncUpdatesDir(dirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void restart() {
|
|
||||||
ProcessBuilder builder = new ProcessBuilder();
|
|
||||||
if (config.startScript != null) builder.command(Collections.singletonList(config.startScript));
|
|
||||||
else throw new IllegalArgumentException("Please create start script and link it as startScript in config.");
|
|
||||||
builder.directory(this.dir.toFile());
|
|
||||||
builder.inheritIO();
|
|
||||||
builder.redirectErrorStream(true);
|
|
||||||
builder.redirectOutput(Redirect.PIPE);
|
|
||||||
try {
|
|
||||||
builder.start();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.error("Restart failed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerObject(String name, Object object) {
|
public void registerObject(String name, Object object) {
|
||||||
if (object instanceof Reconfigurable) {
|
if (object instanceof Reconfigurable) {
|
||||||
reconfigurableManager.registerReconfigurable(name, (Reconfigurable) object);
|
reconfigurableManager.registerReconfigurable(name, (Reconfigurable) object);
|
||||||
|
@ -449,11 +434,6 @@ public void unregisterObject(String name, Object object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fullyRestart() {
|
|
||||||
restart();
|
|
||||||
JVMHelper.RUNTIME.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public enum ReloadType {
|
public enum ReloadType {
|
||||||
NO_AUTH,
|
NO_AUTH,
|
||||||
|
|
|
@ -63,7 +63,24 @@ public LaunchServerBuilder setLaunchServerConfigManager(LaunchServer.LaunchServe
|
||||||
public LaunchServer build() throws Exception {
|
public LaunchServer build() throws Exception {
|
||||||
directories.collect();
|
directories.collect();
|
||||||
if (launchServerConfigManager == null) {
|
if (launchServerConfigManager == null) {
|
||||||
launchServerConfigManager = new LaunchServer.LaunchServerConfigManager() {
|
launchServerConfigManager = new NullLaunchServerConfigManager();
|
||||||
|
}
|
||||||
|
if (keyAgreementManager == null) {
|
||||||
|
keyAgreementManager = new KeyAgreementManager(directories.keyDirectory);
|
||||||
|
}
|
||||||
|
return new LaunchServer(directories, env, config, runtimeConfig, launchServerConfigManager, modulesManager, keyAgreementManager, commandHandler, certificateManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LaunchServerBuilder setCertificateManager(CertificateManager certificateManager) {
|
||||||
|
this.certificateManager = certificateManager;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyAgreementManager(KeyAgreementManager keyAgreementManager) {
|
||||||
|
this.keyAgreementManager = keyAgreementManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NullLaunchServerConfigManager implements LaunchServer.LaunchServerConfigManager {
|
||||||
@Override
|
@Override
|
||||||
public LaunchServerConfig readConfig() {
|
public LaunchServerConfig readConfig() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
@ -83,20 +100,5 @@ public void writeConfig(LaunchServerConfig config) {
|
||||||
public void writeRuntimeConfig(LaunchServerRuntimeConfig config) {
|
public void writeRuntimeConfig(LaunchServerRuntimeConfig config) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
if (keyAgreementManager == null) {
|
|
||||||
keyAgreementManager = new KeyAgreementManager(directories.keyDirectory);
|
|
||||||
}
|
|
||||||
return new LaunchServer(directories, env, config, runtimeConfig, launchServerConfigManager, modulesManager, keyAgreementManager, commandHandler, certificateManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LaunchServerBuilder setCertificateManager(CertificateManager certificateManager) {
|
|
||||||
this.certificateManager = certificateManager;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKeyAgreementManager(KeyAgreementManager keyAgreementManager) {
|
|
||||||
this.keyAgreementManager = keyAgreementManager;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,57 +122,7 @@ public static void main(String[] args) throws Exception {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchServer.LaunchServerConfigManager launchServerConfigManager = new LaunchServer.LaunchServerConfigManager() {
|
LaunchServer.LaunchServerConfigManager launchServerConfigManager = new BasicLaunchServerConfigManager(configFile, runtimeConfigFile);
|
||||||
@Override
|
|
||||||
public LaunchServerConfig readConfig() throws IOException {
|
|
||||||
LaunchServerConfig config1;
|
|
||||||
try (BufferedReader reader = IOHelper.newReader(configFile)) {
|
|
||||||
config1 = Launcher.gsonManager.gson.fromJson(reader, LaunchServerConfig.class);
|
|
||||||
}
|
|
||||||
return config1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LaunchServerRuntimeConfig readRuntimeConfig() throws IOException {
|
|
||||||
LaunchServerRuntimeConfig config1;
|
|
||||||
try (BufferedReader reader = IOHelper.newReader(runtimeConfigFile)) {
|
|
||||||
config1 = Launcher.gsonManager.gson.fromJson(reader, LaunchServerRuntimeConfig.class);
|
|
||||||
}
|
|
||||||
return config1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeConfig(LaunchServerConfig config) throws IOException {
|
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
||||||
try (Writer writer = IOHelper.newWriter(output)) {
|
|
||||||
if (Launcher.gsonManager.configGson != null) {
|
|
||||||
Launcher.gsonManager.configGson.toJson(config, writer);
|
|
||||||
} else {
|
|
||||||
logger.error("Error writing LaunchServer config file. Gson is null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
byte[] bytes = output.toByteArray();
|
|
||||||
if(bytes.length > 0) {
|
|
||||||
IOHelper.write(configFile, bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeRuntimeConfig(LaunchServerRuntimeConfig config) throws IOException {
|
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
||||||
try (Writer writer = IOHelper.newWriter(output)) {
|
|
||||||
if (Launcher.gsonManager.configGson != null) {
|
|
||||||
Launcher.gsonManager.configGson.toJson(config, writer);
|
|
||||||
} else {
|
|
||||||
logger.error("Error writing LaunchServer runtime config file. Gson is null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
byte[] bytes = output.toByteArray();
|
|
||||||
if(bytes.length > 0) {
|
|
||||||
IOHelper.write(runtimeConfigFile, bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
LaunchServer.LaunchServerDirectories directories = new LaunchServer.LaunchServerDirectories();
|
LaunchServer.LaunchServerDirectories directories = new LaunchServer.LaunchServerDirectories();
|
||||||
directories.dir = dir;
|
directories.dir = dir;
|
||||||
LaunchServer server = new LaunchServerBuilder()
|
LaunchServer server = new LaunchServerBuilder()
|
||||||
|
@ -284,4 +234,64 @@ public static void generateConfigIfNotExists(Path configFile, CommandHandler com
|
||||||
Launcher.gsonManager.configGson.toJson(newConfig, writer);
|
Launcher.gsonManager.configGson.toJson(newConfig, writer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class BasicLaunchServerConfigManager implements LaunchServer.LaunchServerConfigManager {
|
||||||
|
private final Path configFile;
|
||||||
|
private final Path runtimeConfigFile;
|
||||||
|
|
||||||
|
public BasicLaunchServerConfigManager(Path configFile, Path runtimeConfigFile) {
|
||||||
|
this.configFile = configFile;
|
||||||
|
this.runtimeConfigFile = runtimeConfigFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LaunchServerConfig readConfig() throws IOException {
|
||||||
|
LaunchServerConfig config1;
|
||||||
|
try (BufferedReader reader = IOHelper.newReader(configFile)) {
|
||||||
|
config1 = Launcher.gsonManager.gson.fromJson(reader, LaunchServerConfig.class);
|
||||||
|
}
|
||||||
|
return config1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LaunchServerRuntimeConfig readRuntimeConfig() throws IOException {
|
||||||
|
LaunchServerRuntimeConfig config1;
|
||||||
|
try (BufferedReader reader = IOHelper.newReader(runtimeConfigFile)) {
|
||||||
|
config1 = Launcher.gsonManager.gson.fromJson(reader, LaunchServerRuntimeConfig.class);
|
||||||
|
}
|
||||||
|
return config1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeConfig(LaunchServerConfig config) throws IOException {
|
||||||
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
|
try (Writer writer = IOHelper.newWriter(output)) {
|
||||||
|
if (Launcher.gsonManager.configGson != null) {
|
||||||
|
Launcher.gsonManager.configGson.toJson(config, writer);
|
||||||
|
} else {
|
||||||
|
logger.error("Error writing LaunchServer config file. Gson is null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byte[] bytes = output.toByteArray();
|
||||||
|
if(bytes.length > 0) {
|
||||||
|
IOHelper.write(configFile, bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeRuntimeConfig(LaunchServerRuntimeConfig config) throws IOException {
|
||||||
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
|
try (Writer writer = IOHelper.newWriter(output)) {
|
||||||
|
if (Launcher.gsonManager.configGson != null) {
|
||||||
|
Launcher.gsonManager.configGson.toJson(config, writer);
|
||||||
|
} else {
|
||||||
|
logger.error("Error writing LaunchServer runtime config file. Gson is null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byte[] bytes = output.toByteArray();
|
||||||
|
if(bytes.length > 0) {
|
||||||
|
IOHelper.write(runtimeConfigFile, bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,9 @@ protected boolean showApplyDialog(String text) throws IOException {
|
||||||
protected Downloader downloadWithProgressBar(String taskName, List<Downloader.SizedFile> list, String baseUrl, Path targetDir) throws Exception {
|
protected Downloader downloadWithProgressBar(String taskName, List<Downloader.SizedFile> list, String baseUrl, Path targetDir) throws Exception {
|
||||||
long total = 0;
|
long total = 0;
|
||||||
for (Downloader.SizedFile file : list) {
|
for (Downloader.SizedFile file : list) {
|
||||||
|
if(file.size < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
total += file.size;
|
total += file.size;
|
||||||
}
|
}
|
||||||
long totalFiles = list.size();
|
long totalFiles = list.size();
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package pro.gravit.launchserver.command.basic;
|
|
||||||
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
|
||||||
import pro.gravit.launchserver.command.Command;
|
|
||||||
|
|
||||||
public final class RestartCommand extends Command {
|
|
||||||
public RestartCommand(LaunchServer server) {
|
|
||||||
super(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArgsDescription() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsageDescription() {
|
|
||||||
return "Restart LaunchServer";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) {
|
|
||||||
server.fullyRestart();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,6 +6,9 @@
|
||||||
import pro.gravit.launchserver.command.modules.LoadModuleCommand;
|
import pro.gravit.launchserver.command.modules.LoadModuleCommand;
|
||||||
import pro.gravit.launchserver.command.modules.ModulesCommand;
|
import pro.gravit.launchserver.command.modules.ModulesCommand;
|
||||||
import pro.gravit.launchserver.command.service.*;
|
import pro.gravit.launchserver.command.service.*;
|
||||||
|
import pro.gravit.launchserver.command.sync.*;
|
||||||
|
import pro.gravit.launchserver.command.tools.SignDirCommand;
|
||||||
|
import pro.gravit.launchserver.command.tools.SignJarCommand;
|
||||||
import pro.gravit.utils.command.BaseCommandCategory;
|
import pro.gravit.utils.command.BaseCommandCategory;
|
||||||
import pro.gravit.utils.command.basic.ClearCommand;
|
import pro.gravit.utils.command.basic.ClearCommand;
|
||||||
import pro.gravit.utils.command.basic.GCCommand;
|
import pro.gravit.utils.command.basic.GCCommand;
|
||||||
|
@ -19,7 +22,6 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
|
||||||
basic.registerCommand("version", new VersionCommand(server));
|
basic.registerCommand("version", new VersionCommand(server));
|
||||||
basic.registerCommand("build", new BuildCommand(server));
|
basic.registerCommand("build", new BuildCommand(server));
|
||||||
basic.registerCommand("stop", new StopCommand(server));
|
basic.registerCommand("stop", new StopCommand(server));
|
||||||
basic.registerCommand("restart", new RestartCommand(server));
|
|
||||||
basic.registerCommand("debug", new DebugCommand(server));
|
basic.registerCommand("debug", new DebugCommand(server));
|
||||||
basic.registerCommand("clear", new ClearCommand(handler));
|
basic.registerCommand("clear", new ClearCommand(handler));
|
||||||
basic.registerCommand("gc", new GCCommand());
|
basic.registerCommand("gc", new GCCommand());
|
||||||
|
@ -34,10 +36,7 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
|
||||||
updates.registerCommand("unindexAsset", new UnindexAssetCommand(server));
|
updates.registerCommand("unindexAsset", new UnindexAssetCommand(server));
|
||||||
updates.registerCommand("downloadAsset", new DownloadAssetCommand(server));
|
updates.registerCommand("downloadAsset", new DownloadAssetCommand(server));
|
||||||
updates.registerCommand("downloadClient", new DownloadClientCommand(server));
|
updates.registerCommand("downloadClient", new DownloadClientCommand(server));
|
||||||
updates.registerCommand("syncBinaries", new SyncBinariesCommand(server));
|
updates.registerCommand("sync", new SyncCommand(server));
|
||||||
updates.registerCommand("syncUpdates", new SyncUpdatesCommand(server));
|
|
||||||
updates.registerCommand("syncProfiles", new SyncProfilesCommand(server));
|
|
||||||
updates.registerCommand("syncUP", new SyncUPCommand(server));
|
|
||||||
updates.registerCommand("saveProfiles", new SaveProfilesCommand(server));
|
updates.registerCommand("saveProfiles", new SaveProfilesCommand(server));
|
||||||
updates.registerCommand("makeProfile", new MakeProfileCommand(server));
|
updates.registerCommand("makeProfile", new MakeProfileCommand(server));
|
||||||
Category updatesCategory = new Category(updates, "updates", "Update and Sync Management");
|
Category updatesCategory = new Category(updates, "updates", "Update and Sync Management");
|
||||||
|
@ -50,11 +49,16 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
|
||||||
service.registerCommand("notify", new NotifyCommand(server));
|
service.registerCommand("notify", new NotifyCommand(server));
|
||||||
service.registerCommand("component", new ComponentCommand(server));
|
service.registerCommand("component", new ComponentCommand(server));
|
||||||
service.registerCommand("clients", new ClientsCommand(server));
|
service.registerCommand("clients", new ClientsCommand(server));
|
||||||
service.registerCommand("signJar", new SignJarCommand(server));
|
|
||||||
service.registerCommand("signDir", new SignDirCommand(server));
|
|
||||||
service.registerCommand("securitycheck", new SecurityCheckCommand(server));
|
service.registerCommand("securitycheck", new SecurityCheckCommand(server));
|
||||||
service.registerCommand("token", new TokenCommand(server));
|
service.registerCommand("token", new TokenCommand(server));
|
||||||
Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components");
|
Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components");
|
||||||
handler.registerCategory(serviceCategory);
|
handler.registerCategory(serviceCategory);
|
||||||
|
|
||||||
|
//Register tools commands
|
||||||
|
BaseCommandCategory tools = new BaseCommandCategory();
|
||||||
|
tools.registerCommand("signJar", new SignJarCommand(server));
|
||||||
|
tools.registerCommand("signDir", new SignDirCommand(server));
|
||||||
|
Category toolsCategory = new Category(tools, "tools", "Other tools");
|
||||||
|
handler.registerCategory(toolsCategory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package pro.gravit.launchserver.command.hash;
|
package pro.gravit.launchserver.command.sync;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
|
@ -0,0 +1,30 @@
|
||||||
|
package pro.gravit.launchserver.command.sync;
|
||||||
|
|
||||||
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
|
import pro.gravit.launchserver.command.Command;
|
||||||
|
|
||||||
|
public class SyncCommand extends Command {
|
||||||
|
public SyncCommand(LaunchServer server) {
|
||||||
|
super(server);
|
||||||
|
this.childCommands.put("profiles", new SyncProfilesCommand(server));
|
||||||
|
this.childCommands.put("binaries", new SyncBinariesCommand(server));
|
||||||
|
this.childCommands.put("updates", new SyncUpdatesCommand(server));
|
||||||
|
this.childCommands.put("up", new SyncUPCommand(server));
|
||||||
|
this.childCommands.put("launchermodules", new SyncLauncherModulesCommand(server));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getArgsDescription() {
|
||||||
|
return "[updates/profiles/up/binaries/launchermodules] [args...]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsageDescription() {
|
||||||
|
return "sync specified objects";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke(String... args) throws Exception {
|
||||||
|
invokeSubcommands(args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,31 +1,31 @@
|
||||||
package pro.gravit.launchserver.launchermodules;
|
package pro.gravit.launchserver.command.sync;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import pro.gravit.utils.command.Command;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
|
import pro.gravit.launchserver.command.Command;
|
||||||
|
|
||||||
public class SyncLauncherModulesCommand extends Command {
|
public class SyncLauncherModulesCommand extends Command {
|
||||||
private final LauncherModuleLoader mod;
|
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
public SyncLauncherModulesCommand(LauncherModuleLoader mod) {
|
public SyncLauncherModulesCommand(LaunchServer server) {
|
||||||
this.mod = mod;
|
super(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getArgsDescription() {
|
public String getArgsDescription() {
|
||||||
return "Resync launcher modules";
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUsageDescription() {
|
public String getUsageDescription() {
|
||||||
return "[]";
|
return "Resync launcher modules";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(String... args) throws Exception {
|
public void invoke(String... args) throws Exception {
|
||||||
mod.syncModules();
|
server.launcherModuleLoader.syncModules();
|
||||||
logger.info("Launcher Modules synced");
|
logger.info("Launcher Modules synced");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package pro.gravit.launchserver.command.hash;
|
package pro.gravit.launchserver.command.sync;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
|
@ -1,4 +1,4 @@
|
||||||
package pro.gravit.launchserver.command.hash;
|
package pro.gravit.launchserver.command.sync;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
|
@ -1,4 +1,4 @@
|
||||||
package pro.gravit.launchserver.command.hash;
|
package pro.gravit.launchserver.command.sync;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
|
@ -1,4 +1,4 @@
|
||||||
package pro.gravit.launchserver.command.service;
|
package pro.gravit.launchserver.command.tools;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
|
@ -1,4 +1,4 @@
|
||||||
package pro.gravit.launchserver.command.service;
|
package pro.gravit.launchserver.command.tools;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
|
@ -41,7 +41,6 @@ public final class LaunchServerConfig {
|
||||||
public NettyConfig netty;
|
public NettyConfig netty;
|
||||||
public LauncherConf launcher;
|
public LauncherConf launcher;
|
||||||
public JarSignerConf sign;
|
public JarSignerConf sign;
|
||||||
public String startScript;
|
|
||||||
private transient LaunchServer server = null;
|
private transient LaunchServer server = null;
|
||||||
private transient AuthProviderPair authDefault;
|
private transient AuthProviderPair authDefault;
|
||||||
|
|
||||||
|
@ -49,7 +48,6 @@ public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) {
|
||||||
LaunchServerConfig newConfig = new LaunchServerConfig();
|
LaunchServerConfig newConfig = new LaunchServerConfig();
|
||||||
newConfig.mirrors = new String[]{"https://mirror.gravitlauncher.com/5.6.x/", "https://gravit-launcher-mirror.storage.googleapis.com/"};
|
newConfig.mirrors = new String[]{"https://mirror.gravitlauncher.com/5.6.x/", "https://gravit-launcher-mirror.storage.googleapis.com/"};
|
||||||
newConfig.env = LauncherConfig.LauncherEnvironment.STD;
|
newConfig.env = LauncherConfig.LauncherEnvironment.STD;
|
||||||
newConfig.startScript = JVMHelper.OS_TYPE.equals(JVMHelper.OS.MUSTDIE) ? "." + File.separator + "start.bat" : "." + File.separator + "start.sh";
|
|
||||||
newConfig.auth = new HashMap<>();
|
newConfig.auth = new HashMap<>();
|
||||||
AuthProviderPair a = new AuthProviderPair(new RejectAuthCoreProvider(),
|
AuthProviderPair a = new AuthProviderPair(new RejectAuthCoreProvider(),
|
||||||
new RequestTextureProvider("http://example.com/skins/%username%.png", "http://example.com/cloaks/%username%.png")
|
new RequestTextureProvider("http://example.com/skins/%username%.png", "http://example.com/cloaks/%username%.png")
|
||||||
|
@ -263,6 +261,12 @@ public static class NettyPerformanceConfig {
|
||||||
public int workerThread;
|
public int workerThread;
|
||||||
public int schedulerThread;
|
public int schedulerThread;
|
||||||
public int maxWebSocketRequestBytes = 1024 * 1024;
|
public int maxWebSocketRequestBytes = 1024 * 1024;
|
||||||
|
public boolean disableThreadSafeClientObject;
|
||||||
|
public NettyExecutorType executorType = NettyExecutorType.VIRTUAL_THREADS;
|
||||||
|
|
||||||
|
public enum NettyExecutorType {
|
||||||
|
NONE, DEFAULT, WORK_STEAL, VIRTUAL_THREADS
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class NettyBindAddress {
|
public static class NettyBindAddress {
|
||||||
|
|
|
@ -44,7 +44,6 @@ public void init() {
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
server.commandHandler.registerCommand("syncLauncherModules", new SyncLauncherModulesCommand(this));
|
|
||||||
MainBuildTask mainTask = server.launcherBinary.getTaskByClass(MainBuildTask.class).get();
|
MainBuildTask mainTask = server.launcherBinary.getTaskByClass(MainBuildTask.class).get();
|
||||||
mainTask.preBuildHook.registerHook((buildContext) -> {
|
mainTask.preBuildHook.registerHook((buildContext) -> {
|
||||||
for (ModuleEntity e : launcherModules) {
|
for (ModuleEntity e : launcherModules) {
|
||||||
|
|
|
@ -10,8 +10,11 @@
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
public class Client {
|
public class Client {
|
||||||
|
ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
public String auth_id;
|
public String auth_id;
|
||||||
public long timestamp;
|
public long timestamp;
|
||||||
public AuthResponse.ConnectTypes type;
|
public AuthResponse.ConnectTypes type;
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
public class WebSocketService {
|
public class WebSocketService {
|
||||||
|
@ -51,11 +53,18 @@ public class WebSocketService {
|
||||||
private final LaunchServer server;
|
private final LaunchServer server;
|
||||||
private final Gson gson;
|
private final Gson gson;
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
|
private ExecutorService executors;
|
||||||
|
|
||||||
public WebSocketService(ChannelGroup channels, LaunchServer server) {
|
public WebSocketService(ChannelGroup channels, LaunchServer server) {
|
||||||
this.channels = channels;
|
this.channels = channels;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.gson = Launcher.gsonManager.gson;
|
this.gson = Launcher.gsonManager.gson;
|
||||||
|
executors = switch (server.config.netty.performance.executorType) {
|
||||||
|
case NONE -> null;
|
||||||
|
case DEFAULT -> Executors.newCachedThreadPool();
|
||||||
|
case WORK_STEAL -> Executors.newWorkStealingPool();
|
||||||
|
case VIRTUAL_THREADS -> Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerResponses() {
|
public static void registerResponses() {
|
||||||
|
@ -126,8 +135,42 @@ public void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client
|
||||||
sendObject(ctx.channel(), event, WebSocketEvent.class);
|
sendObject(ctx.channel(), event, WebSocketEvent.class);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var safeStatus = server.config.netty.performance.disableThreadSafeClientObject ?
|
||||||
|
WebSocketServerResponse.ThreadSafeStatus.NONE : response.getThreadSafeStatus();
|
||||||
|
if(executors == null) {
|
||||||
|
process(safeStatus, client, ip, context, response);
|
||||||
|
} else {
|
||||||
|
executors.submit(() -> {
|
||||||
|
process(safeStatus, client, ip, context, response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void process(WebSocketServerResponse.ThreadSafeStatus safeStatus, Client client, String ip, WebSocketRequestContext context, WebSocketServerResponse response) {
|
||||||
|
switch (safeStatus) {
|
||||||
|
case NONE -> {
|
||||||
process(context, response, client, ip);
|
process(context, response, client, ip);
|
||||||
}
|
}
|
||||||
|
case READ -> {
|
||||||
|
var lock = client.lock.readLock();
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
process(context, response, client, ip);
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case READ_WRITE -> {
|
||||||
|
var lock = client.lock.writeLock();
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
process(context, response, client, ip);
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void process(WebSocketRequestContext context, WebSocketServerResponse response, Client client, String ip) {
|
void process(WebSocketRequestContext context, WebSocketServerResponse response, Client client, String ip) {
|
||||||
if (hookBeforeExecute.hook(context)) {
|
if (hookBeforeExecute.hook(context)) {
|
||||||
|
|
|
@ -8,4 +8,12 @@ public interface WebSocketServerResponse extends WebSocketRequest {
|
||||||
String getType();
|
String getType();
|
||||||
|
|
||||||
void execute(ChannelHandlerContext ctx, Client client) throws Exception;
|
void execute(ChannelHandlerContext ctx, Client client) throws Exception;
|
||||||
|
|
||||||
|
default ThreadSafeStatus getThreadSafeStatus() {
|
||||||
|
return ThreadSafeStatus.READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ThreadSafeStatus {
|
||||||
|
NONE, READ, READ_WRITE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"features": ["nojava8support"],
|
"features": [],
|
||||||
"info": ["Java below 17 not supported"]
|
"info": []
|
||||||
}
|
}
|
|
@ -21,6 +21,7 @@
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
@ -159,6 +160,16 @@ public CompletableFuture<Void> downloadFile(URI uri, Path path) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Void> downloadFile(String url, Path path, DownloadCallback callback, ExecutorService executor) throws Exception {
|
||||||
|
return downloadFiles(new ArrayList<>(List.of(new SizedFile(url, path.getFileName().toString()))), null,
|
||||||
|
path.getParent(), callback, executor, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Void> downloadFile(String url, Path path, long size, DownloadCallback callback, ExecutorService executor) throws Exception {
|
||||||
|
return downloadFiles(new ArrayList<>(List.of(new SizedFile(url, path.getFileName().toString(), size))), null,
|
||||||
|
path.getParent(), callback, executor, 1);
|
||||||
|
}
|
||||||
|
|
||||||
public CompletableFuture<Void> downloadFiles(List<SizedFile> files, String baseURL, Path targetDir, DownloadCallback callback, ExecutorService executor, int threads) throws Exception {
|
public CompletableFuture<Void> downloadFiles(List<SizedFile> files, String baseURL, Path targetDir, DownloadCallback callback, ExecutorService executor, int threads) throws Exception {
|
||||||
// URI scheme
|
// URI scheme
|
||||||
URI baseUri = baseURL == null ? null : new URI(baseURL);
|
URI baseUri = baseURL == null ? null : new URI(baseURL);
|
||||||
|
@ -355,5 +366,11 @@ public SizedFile(String urlPath, String filePath, long size) {
|
||||||
this.filePath = filePath;
|
this.filePath = filePath;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SizedFile(String urlPath, String filePath) {
|
||||||
|
this.urlPath = urlPath;
|
||||||
|
this.filePath = filePath;
|
||||||
|
this.size = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue