mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 11:39:11 +03:00
Merge branch 'release/5.0.5'
This commit is contained in:
commit
bfa466397a
192 changed files with 1435 additions and 1891 deletions
|
@ -1,14 +1,14 @@
|
|||
image: java:8-jdk
|
||||
image: frekele/java
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
|
||||
before_script:
|
||||
# - echo `pwd` # debug
|
||||
# - echo "$CI_BUILD_NAME, $CI_BUILD_REF_NAME $CI_BUILD_STAGE" # debug
|
||||
- export GRADLE_USER_HOME=`pwd`/.gradle
|
||||
- apt-get update -qq && apt-get install -y -qq git git-core
|
||||
|
||||
cache:
|
||||
paths:
|
||||
|
@ -28,10 +28,5 @@ build:
|
|||
- ServerWrapper/build/libs/*.jar
|
||||
expire_in: 1 week
|
||||
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- ./gradlew check
|
||||
|
||||
after_script:
|
||||
- echo "End CI"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
language: java
|
||||
dist: trusty
|
||||
# Use https (public access) instead of git for git-submodules. This modifies only Travis-CI behavior!
|
||||
# disable the default submodule logic
|
||||
git:
|
||||
|
|
|
@ -54,6 +54,7 @@ bundle project(':Radon')
|
|||
bundle 'org.javassist:javassist:3.25.0-GA'
|
||||
bundle 'io.netty:netty-all:4.1.36.Final'
|
||||
bundle 'org.hibernate:hibernate-core:5.4.3.Final'
|
||||
bundle 'org.bouncycastle:bcpkix-jdk15on:1.61'
|
||||
|
||||
bundle 'org.slf4j:slf4j-simple:1.7.25'
|
||||
bundle 'org.slf4j:slf4j-api:1.7.25'
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
import java.io.Writer;
|
||||
import java.lang.ProcessBuilder.Redirect;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
|
@ -38,8 +36,8 @@
|
|||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.launcher.LauncherConfig;
|
||||
import pro.gravit.launcher.NeedGarbageCollection;
|
||||
import pro.gravit.launcher.config.JsonConfigurable;
|
||||
import pro.gravit.launcher.hasher.HashedDir;
|
||||
import pro.gravit.launcher.hwid.HWIDProvider;
|
||||
import pro.gravit.launcher.managers.ConfigManager;
|
||||
import pro.gravit.launcher.managers.GarbageManager;
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
|
@ -65,20 +63,15 @@
|
|||
import pro.gravit.launchserver.binary.ProguardConf;
|
||||
import pro.gravit.launchserver.components.AuthLimiterComponent;
|
||||
import pro.gravit.launchserver.components.Component;
|
||||
import pro.gravit.launchserver.components.RegLimiterComponent;
|
||||
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
|
||||
import pro.gravit.launchserver.dao.UserService;
|
||||
import pro.gravit.launchserver.legacy.Response;
|
||||
import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
|
||||
import pro.gravit.launchserver.manangers.MirrorManager;
|
||||
import pro.gravit.launchserver.manangers.ModulesManager;
|
||||
import pro.gravit.launchserver.manangers.ReconfigurableManager;
|
||||
import pro.gravit.launchserver.manangers.ReloadManager;
|
||||
import pro.gravit.launchserver.manangers.SessionManager;
|
||||
import pro.gravit.launchserver.dao.provider.DaoProvider;
|
||||
import pro.gravit.launchserver.manangers.*;
|
||||
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
|
||||
import pro.gravit.launchserver.manangers.hook.BuildHookManager;
|
||||
import pro.gravit.launchserver.manangers.hook.SocketHookManager;
|
||||
import pro.gravit.launchserver.socket.ServerSocketHandler;
|
||||
import pro.gravit.launchserver.websocket.NettyServerSocketHandler;
|
||||
import pro.gravit.launchserver.socket.WebSocketService;
|
||||
import pro.gravit.launchserver.socket.handlers.NettyServerSocketHandler;
|
||||
import pro.gravit.utils.Version;
|
||||
import pro.gravit.utils.command.CommandHandler;
|
||||
import pro.gravit.utils.command.JLineCommandHandler;
|
||||
|
@ -88,7 +81,6 @@
|
|||
import pro.gravit.utils.helper.JVMHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
import pro.gravit.utils.helper.VerifyHelper;
|
||||
|
||||
public final class LaunchServer implements Runnable, AutoCloseable, Reloadable {
|
||||
@Override
|
||||
|
@ -105,11 +97,6 @@ public void reload() throws Exception {
|
|||
|
||||
public static final class Config {
|
||||
private transient LaunchServer server = null;
|
||||
public int legacyPort;
|
||||
|
||||
private String legacyAddress;
|
||||
|
||||
private String legacyBindAddress;
|
||||
|
||||
public String projectName;
|
||||
|
||||
|
@ -125,6 +112,8 @@ public static final class Config {
|
|||
|
||||
public AuthProviderPair[] auth;
|
||||
|
||||
public DaoProvider dao;
|
||||
|
||||
private transient AuthProviderPair authDefault;
|
||||
|
||||
public AuthProviderPair getAuthProviderPair(String name) {
|
||||
|
@ -153,11 +142,6 @@ public AuthProviderPair getAuthProviderPair() {
|
|||
|
||||
public Map<String, Component> components;
|
||||
|
||||
// Misc options
|
||||
public int threadCount;
|
||||
|
||||
public int threadCoreCount;
|
||||
|
||||
public ExeConf launch4j;
|
||||
public NettyConfig netty;
|
||||
public GuardLicenseConf guardLicense;
|
||||
|
@ -175,15 +159,6 @@ public AuthProviderPair getAuthProviderPair() {
|
|||
|
||||
public String startScript;
|
||||
|
||||
public String getLegacyAddress() {
|
||||
return legacyAddress;
|
||||
}
|
||||
|
||||
|
||||
public String getLegacyBindAddress() {
|
||||
return legacyBindAddress;
|
||||
}
|
||||
|
||||
public void setProjectName(String projectName) {
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
@ -197,18 +172,7 @@ public void setEnv(LauncherConfig.LauncherEnvironment env) {
|
|||
}
|
||||
|
||||
|
||||
public SocketAddress getSocketAddress() {
|
||||
return new InetSocketAddress(legacyBindAddress, legacyPort);
|
||||
}
|
||||
|
||||
|
||||
public void setLegacyAddress(String legacyAddress) {
|
||||
this.legacyAddress = legacyAddress;
|
||||
}
|
||||
|
||||
|
||||
public void verify() {
|
||||
VerifyHelper.verify(getLegacyAddress(), VerifyHelper.NOT_EMPTY, "LaunchServer address can't be empty");
|
||||
if (auth == null || auth[0] == null) {
|
||||
throw new NullPointerException("AuthHandler must not be null");
|
||||
}
|
||||
|
@ -243,10 +207,12 @@ public void init() {
|
|||
}
|
||||
permissionsHandler.init(server);
|
||||
hwidHandler.init();
|
||||
dao.init(server);
|
||||
if (protectHandler != null) {
|
||||
protectHandler.checkLaunchServerLicense();
|
||||
}
|
||||
server.registerObject("permissionsHandler", permissionsHandler);
|
||||
server.registerObject("daoProvider", dao);
|
||||
for (AuthProviderPair pair : auth) {
|
||||
server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
|
||||
server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
|
||||
|
@ -327,6 +293,7 @@ public class NettyConfig {
|
|||
}
|
||||
|
||||
public class NettyPerformanceConfig {
|
||||
public boolean usingEpoll;
|
||||
public int bossThread;
|
||||
public int workerThread;
|
||||
}
|
||||
|
@ -452,15 +419,11 @@ public static void main(String... args) throws Throwable {
|
|||
|
||||
public final SessionManager sessionManager;
|
||||
|
||||
public final SocketHookManager socketHookManager;
|
||||
|
||||
public final AuthHookManager authHookManager;
|
||||
// Server
|
||||
|
||||
public final ModulesManager modulesManager;
|
||||
|
||||
public final UserService userService;
|
||||
|
||||
public final MirrorManager mirrorManager;
|
||||
|
||||
public final ReloadManager reloadManager;
|
||||
|
@ -469,6 +432,8 @@ public static void main(String... args) throws Throwable {
|
|||
|
||||
public final ConfigManager configManager;
|
||||
|
||||
public final CertificateManager certificateManager;
|
||||
|
||||
|
||||
public final BuildHookManager buildHookManager;
|
||||
|
||||
|
@ -477,8 +442,6 @@ public static void main(String... args) throws Throwable {
|
|||
|
||||
public final CommandHandler commandHandler;
|
||||
|
||||
public final ServerSocketHandler serverSocketHandler;
|
||||
|
||||
public final NettyServerSocketHandler nettyServerSocketHandler;
|
||||
|
||||
private final AtomicBoolean started = new AtomicBoolean(false);
|
||||
|
@ -498,8 +461,22 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
|
|||
launcherLibraries = dir.resolve("launcher-libraries");
|
||||
launcherLibrariesCompile = dir.resolve("launcher-libraries-compile");
|
||||
this.args = Arrays.asList(args);
|
||||
if(IOHelper.exists(dir.resolve("LaunchServer.conf")))
|
||||
{
|
||||
configFile = dir.resolve("LaunchServer.conf");
|
||||
}
|
||||
else
|
||||
{
|
||||
configFile = dir.resolve("LaunchServer.json");
|
||||
}
|
||||
if(IOHelper.exists(dir.resolve("RuntimeLaunchServer.conf")))
|
||||
{
|
||||
runtimeConfigFile = dir.resolve("RuntimeLaunchServer.conf");
|
||||
}
|
||||
else
|
||||
{
|
||||
runtimeConfigFile = dir.resolve("RuntimeLaunchServer.json");
|
||||
}
|
||||
publicKeyFile = dir.resolve("public.key");
|
||||
privateKeyFile = dir.resolve("private.key");
|
||||
updatesDir = dir.resolve("updates");
|
||||
|
@ -511,9 +488,11 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
|
|||
TextureProvider.registerProviders();
|
||||
HWIDHandler.registerHandlers();
|
||||
PermissionsHandler.registerHandlers();
|
||||
Response.registerResponses();
|
||||
Component.registerComponents();
|
||||
ProtectHandler.registerHandlers();
|
||||
WebSocketService.registerResponses();
|
||||
HWIDProvider.registerHWIDs();
|
||||
DaoProvider.registerProviders();
|
||||
//LaunchServer.server = this;
|
||||
|
||||
// Set command handler
|
||||
|
@ -531,7 +510,6 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
|
|||
localCommandHandler = new StdCommandHandler(true);
|
||||
LogHelper.warning("JLine2 isn't in classpath, using std");
|
||||
}
|
||||
pro.gravit.launchserver.command.handler.CommandHandler.registerCommands(localCommandHandler, this);
|
||||
commandHandler = localCommandHandler;
|
||||
|
||||
// Set key pair
|
||||
|
@ -592,6 +570,8 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
|
|||
}
|
||||
config.permissionsHandler.init(this);
|
||||
config.hwidHandler.init();
|
||||
if(config.dao != null)
|
||||
config.dao.init(this);
|
||||
if (config.protectHandler != null) {
|
||||
config.protectHandler.checkLaunchServerLicense();
|
||||
}
|
||||
|
@ -611,10 +591,9 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
|
|||
mirrorManager = new MirrorManager();
|
||||
reloadManager = new ReloadManager();
|
||||
reconfigurableManager = new ReconfigurableManager();
|
||||
socketHookManager = new SocketHookManager();
|
||||
authHookManager = new AuthHookManager();
|
||||
configManager = new ConfigManager();
|
||||
userService = new UserService(this);
|
||||
certificateManager = new CertificateManager();
|
||||
GarbageManager.registerNeedGC(sessionManager);
|
||||
reloadManager.registerReloadable("launchServer", this);
|
||||
registerObject("permissionsHandler", config.permissionsHandler);
|
||||
|
@ -627,6 +606,8 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
|
|||
|
||||
Arrays.stream(config.mirrors).forEach(mirrorManager::addMirror);
|
||||
|
||||
pro.gravit.launchserver.command.handler.CommandHandler.registerCommands(localCommandHandler, this);
|
||||
|
||||
// init modules
|
||||
modulesManager.initModules();
|
||||
if (config.components != null) {
|
||||
|
@ -657,10 +638,6 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
|
|||
Files.createDirectory(profilesDir);
|
||||
syncProfilesDir();
|
||||
|
||||
|
||||
// Set server socket thread
|
||||
serverSocketHandler = new ServerSocketHandler(this, sessionManager);
|
||||
|
||||
// post init modules
|
||||
modulesManager.postInitModules();
|
||||
if (config.components != null) {
|
||||
|
@ -708,7 +685,6 @@ public void buildLauncherBinaries() throws IOException {
|
|||
}
|
||||
|
||||
public void close() {
|
||||
serverSocketHandler.close();
|
||||
|
||||
// Close handlers & providers
|
||||
config.close();
|
||||
|
@ -734,7 +710,7 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
|
|||
// Create new config
|
||||
LogHelper.info("Creating LaunchServer config");
|
||||
Config newConfig = new Config();
|
||||
newConfig.mirrors = new String[]{"http://mirror.gravitlauncher.ml/", "https://mirror.gravit.pro/"};
|
||||
newConfig.mirrors = new String[]{"https://mirror.gravit.pro/"};
|
||||
newConfig.launch4j = new ExeConf();
|
||||
newConfig.launch4j.enabled = true;
|
||||
newConfig.launch4j.copyright = "© GravitLauncher Team";
|
||||
|
@ -758,8 +734,6 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
|
|||
newConfig.protectHandler = new StdProtectHandler();
|
||||
if (testEnv) newConfig.permissionsHandler = new DefaultPermissionsHandler();
|
||||
else newConfig.permissionsHandler = new JsonFilePermissionsHandler();
|
||||
newConfig.legacyPort = 7240;
|
||||
newConfig.legacyBindAddress = "0.0.0.0";
|
||||
newConfig.binaryName = "Launcher";
|
||||
newConfig.whitelistRejectString = "Вас нет в белом списке";
|
||||
|
||||
|
@ -767,15 +741,13 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
|
|||
newConfig.netty.fileServerEnabled = true;
|
||||
newConfig.netty.binds = new NettyBindAddress[]{new NettyBindAddress("0.0.0.0", 9274)};
|
||||
newConfig.netty.performance = new NettyPerformanceConfig();
|
||||
newConfig.netty.performance.usingEpoll = JVMHelper.OS_TYPE == JVMHelper.OS.LINUX; //Only linux
|
||||
newConfig.netty.performance.bossThread = 2;
|
||||
newConfig.netty.performance.workerThread = 8;
|
||||
|
||||
newConfig.launcher = new LauncherConf();
|
||||
newConfig.launcher.guardType = "no";
|
||||
|
||||
newConfig.threadCoreCount = 0; // on your own
|
||||
newConfig.threadCount = JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors() >= 4 ? JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors() / 2 : JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors();
|
||||
|
||||
newConfig.enabledRadon = true;
|
||||
newConfig.genMappings = true;
|
||||
newConfig.enabledProGuard = true;
|
||||
|
@ -789,6 +761,11 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
|
|||
authLimiterComponent.rateLimitMilis = 8000;
|
||||
authLimiterComponent.message = "Превышен лимит авторизаций";
|
||||
newConfig.components.put("authLimiter", authLimiterComponent);
|
||||
RegLimiterComponent regLimiterComponent = new RegLimiterComponent();
|
||||
regLimiterComponent.rateLimit = 3;
|
||||
regLimiterComponent.rateLimitMilis = 1000 * 60 * 60 * 10; //Блок на 10 часов
|
||||
regLimiterComponent.message = "Превышен лимит регистраций";
|
||||
newConfig.components.put("regLimiter", regLimiterComponent);
|
||||
|
||||
// Set server address
|
||||
String address;
|
||||
|
@ -810,7 +787,6 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
|
|||
newConfig.projectName = "MineCraft";
|
||||
}
|
||||
|
||||
newConfig.legacyAddress = address;
|
||||
newConfig.netty.address = "ws://" + address + ":9274/api";
|
||||
newConfig.netty.downloadURL = "http://" + address + ":9274/%dirname%/";
|
||||
newConfig.netty.launcherURL = "http://" + address + ":9274/Launcher.jar";
|
||||
|
@ -841,12 +817,6 @@ public Set<Entry<String, SignedObjectHolder<HashedDir>>> getUpdateDirs() {
|
|||
return updatesDirMap.entrySet();
|
||||
}
|
||||
|
||||
|
||||
public void rebindServerSocket() {
|
||||
serverSocketHandler.close();
|
||||
CommonHelper.newThread("Server Socket Thread", false, serverSocketHandler).start();
|
||||
}
|
||||
|
||||
public void rebindNettyServerSocket() {
|
||||
nettyServerSocketHandler.close();
|
||||
CommonHelper.newThread("Netty Server Socket Thread", false, nettyServerSocketHandler).start();
|
||||
|
@ -862,7 +832,6 @@ public void run() {
|
|||
JVMHelper.RUNTIME.addShutdownHook(CommonHelper.newThread(null, false, this::close));
|
||||
CommonHelper.newThread("Command Thread", true, commandHandler).start();
|
||||
}
|
||||
rebindServerSocket();
|
||||
if (config.netty != null)
|
||||
rebindNettyServerSocket();
|
||||
modulesManager.finishModules();
|
||||
|
@ -954,9 +923,6 @@ public void registerObject(String name, Object object) {
|
|||
if (object instanceof NeedGarbageCollection) {
|
||||
GarbageManager.registerNeedGC((NeedGarbageCollection) object);
|
||||
}
|
||||
if (object instanceof JsonConfigurable) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterObject(String name, Object object) {
|
||||
|
@ -969,9 +935,6 @@ public void unregisterObject(String name, Object object) {
|
|||
if (object instanceof NeedGarbageCollection) {
|
||||
GarbageManager.unregisterNeedGC((NeedGarbageCollection) object);
|
||||
}
|
||||
if (object instanceof JsonConfigurable) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void fullyRestart() {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package pro.gravit.launchserver;
|
||||
|
||||
public interface Reconfigurable {
|
||||
void reconfig(String action, String[] args);
|
||||
import pro.gravit.utils.command.Command;
|
||||
|
||||
void printConfigHelp();
|
||||
import java.util.Map;
|
||||
|
||||
public interface Reconfigurable {
|
||||
Map<String, Command> getCommands();
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public void acceptVisitor(String className, ClassVisitor visitor) throws IOExcep
|
|||
public byte[] getClassData(String className) throws IOException {
|
||||
for (JarFile f : cp) {
|
||||
if (f.getEntry(className + ".class") != null) {
|
||||
byte[] bytes = null;
|
||||
byte[] bytes;
|
||||
try (InputStream in = f.getInputStream(f.getEntry(className + ".class"))) {
|
||||
bytes = IOHelper.read(in);
|
||||
}
|
||||
|
|
|
@ -8,31 +8,31 @@
|
|||
public class HibernateAuthHandler extends CachedAuthHandler {
|
||||
@Override
|
||||
protected Entry fetchEntry(String username) throws IOException {
|
||||
User user = srv.userService.findUserByUsername(username);
|
||||
User user = srv.config.dao.userService.findUserByUsername(username);
|
||||
if(user == null) return null;
|
||||
return new Entry(user.uuid, username, user.getAccessToken(), user.serverID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Entry fetchEntry(UUID uuid) throws IOException {
|
||||
User user = srv.userService.findUserByUUID(uuid);
|
||||
User user = srv.config.dao.userService.findUserByUUID(uuid);
|
||||
if(user == null) return null;
|
||||
return new Entry(user.uuid, user.username, user.getAccessToken(), user.serverID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException {
|
||||
User user = srv.userService.findUserByUUID(uuid);
|
||||
User user = srv.config.dao.userService.findUserByUUID(uuid);
|
||||
user.setAccessToken(accessToken);
|
||||
srv.userService.updateUser(user);
|
||||
srv.config.dao.userService.updateUser(user);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateServerID(UUID uuid, String serverID) throws IOException {
|
||||
User user = srv.userService.findUserByUUID(uuid);
|
||||
User user = srv.config.dao.userService.findUserByUUID(uuid);
|
||||
user.serverID = serverID;
|
||||
srv.userService.updateUser(user);
|
||||
srv.config.dao.userService.updateUser(user);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import pro.gravit.launcher.HWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
|
||||
public class AcceptHWIDHandler extends HWIDHandler {
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import pro.gravit.launcher.HWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
import pro.gravit.utils.ProviderMap;
|
||||
|
||||
public abstract class HWIDHandler implements AutoCloseable {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import pro.gravit.launcher.HWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
import pro.gravit.launcher.HWID;
|
||||
import pro.gravit.launcher.OshiHWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
import pro.gravit.launcher.hwid.OshiHWID;
|
||||
import pro.gravit.utils.HTTPRequest;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import pro.gravit.launcher.HWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
|
||||
public class MemoryHWIDHandler extends HWIDHandler {
|
||||
public class Entry {
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import pro.gravit.launcher.HWID;
|
||||
import pro.gravit.launcher.OshiHWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
import pro.gravit.launcher.hwid.OshiHWID;
|
||||
import pro.gravit.launchserver.auth.MySQLSourceConfig;
|
||||
import pro.gravit.utils.helper.CommonHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
|
|
@ -7,17 +7,17 @@ public class HibernatePermissionsHandler extends PermissionsHandler {
|
|||
|
||||
@Override
|
||||
public ClientPermissions getPermissions(String username) {
|
||||
User user = srv.userService.findUserByUsername(username);
|
||||
User user = srv.config.dao.userService.findUserByUsername(username);
|
||||
if(user == null) return ClientPermissions.DEFAULT;
|
||||
return user.getPermissions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermissions(String username, ClientPermissions permissions) {
|
||||
User user = srv.userService.findUserByUsername(username);
|
||||
User user = srv.config.dao.userService.findUserByUsername(username);
|
||||
if(user == null) return;
|
||||
user.setPermissions(permissions);
|
||||
srv.userService.updateUser(user);
|
||||
srv.config.dao.userService.updateUser(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package pro.gravit.launchserver.auth.protect;
|
||||
|
||||
import pro.gravit.launchserver.websocket.json.auth.AuthResponse;
|
||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
public class NoProtectHandler extends ProtectHandler {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package pro.gravit.launchserver.auth.protect;
|
||||
|
||||
import pro.gravit.launchserver.websocket.json.auth.AuthResponse;
|
||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
import pro.gravit.utils.ProviderMap;
|
||||
|
||||
public abstract class ProtectHandler {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package pro.gravit.launchserver.auth.protect;
|
||||
|
||||
import pro.gravit.launchserver.websocket.json.auth.AuthResponse;
|
||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
public class StdProtectHandler extends ProtectHandler {
|
||||
|
|
|
@ -4,12 +4,26 @@
|
|||
|
||||
import pro.gravit.launchserver.auth.AuthException;
|
||||
import pro.gravit.launchserver.dao.User;
|
||||
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
public class HibernateAuthProvider extends AuthProvider {
|
||||
public boolean autoReg;
|
||||
@Override
|
||||
public AuthProviderResult auth(String login, String password, String ip) throws Exception {
|
||||
User user = srv.userService.findUserByUsername(login);
|
||||
User user = srv.config.dao.userService.findUserByUsername(login);
|
||||
if(user == null && autoReg)
|
||||
{
|
||||
AuthHookManager.RegContext context = new AuthHookManager.RegContext(login, password, ip, false);
|
||||
if(srv.authHookManager.registraion.hook(context))
|
||||
{
|
||||
user = srv.config.dao.userService.registerNewUser(login, password);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new AuthException("Registration canceled. Try again later");
|
||||
}
|
||||
}
|
||||
if(user == null || !user.verifyPassword(password))
|
||||
{
|
||||
if(user ==null) throw new AuthException("Username incorrect");
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package pro.gravit.launchserver.auth.provider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import pro.gravit.launchserver.Reconfigurable;
|
||||
import pro.gravit.launchserver.auth.AuthException;
|
||||
import pro.gravit.utils.command.Command;
|
||||
import pro.gravit.utils.command.SubCommand;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
|
@ -36,31 +40,15 @@ public void close() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reconfig(String action, String[] args) {
|
||||
switch (action) {
|
||||
case "message":
|
||||
public Map<String, Command> getCommands() {
|
||||
Map<String, Command> commands = new HashMap<>();
|
||||
commands.put("message", new SubCommand() {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
message = args[0];
|
||||
LogHelper.info("New reject message: %s", message);
|
||||
break;
|
||||
case "whitelist.add":
|
||||
if (whitelist == null) whitelist = new ArrayList<>();
|
||||
whitelist.add(args[0]);
|
||||
break;
|
||||
case "whitelist.remove":
|
||||
if (whitelist == null) whitelist = new ArrayList<>();
|
||||
whitelist.remove(args[0]);
|
||||
break;
|
||||
case "whitelist.clear":
|
||||
whitelist.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printConfigHelp() {
|
||||
LogHelper.info("message [new message] - set message");
|
||||
LogHelper.info("whitelist.add [username] - add username to whitelist");
|
||||
LogHelper.info("whitelist.remove [username] - remove username into whitelist");
|
||||
LogHelper.info("whitelist.clear - clear whitelist");
|
||||
}
|
||||
});
|
||||
return commands;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public AuthProviderResult auth(String login, String password, String ip) throws
|
|||
// Match username
|
||||
Matcher matcher = pattern.matcher(currentResponse);
|
||||
return matcher.matches() && matcher.groupCount() >= 1 ?
|
||||
new AuthProviderResult(matcher.group("username"), SecurityHelper.randomStringToken(), usePermission ? new ClientPermissions(Long.getLong(matcher.group("permission"))) : srv.config.permissionsHandler.getPermissions(login)) :
|
||||
new AuthProviderResult(matcher.group("username"), SecurityHelper.randomStringToken(), usePermission ? new ClientPermissions(Long.parseLong(matcher.group("permission"))) : srv.config.permissionsHandler.getPermissions(login)) :
|
||||
authError(currentResponse);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ public static void apply(Path inputFile, Path addFile, ZipOutputStream output, L
|
|||
String filename = e.getName();
|
||||
output.putNextEntry(IOHelper.newZipEntry(e));
|
||||
if (filename.endsWith(".class")) {
|
||||
byte[] bytes = null;
|
||||
byte[] bytes;
|
||||
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(2048)) {
|
||||
IOHelper.transfer(input, outputStream);
|
||||
bytes = outputStream.toByteArray();
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class Command extends pro.gravit.utils.command.Command {
|
||||
|
||||
|
||||
|
@ -9,6 +11,12 @@ public abstract class Command extends pro.gravit.utils.command.Command {
|
|||
|
||||
|
||||
protected Command(LaunchServer server) {
|
||||
super();
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public Command(Map<String, pro.gravit.utils.command.Command> childCommands, LaunchServer server) {
|
||||
super(childCommands);
|
||||
this.server = server;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import pro.gravit.launcher.HWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import pro.gravit.launcher.HWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import pro.gravit.launcher.HWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
package pro.gravit.launchserver.command.basic;
|
||||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public final class LogConnectionsCommand extends Command {
|
||||
public LogConnectionsCommand(LaunchServer server) {
|
||||
super(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgsDescription() {
|
||||
return "[true/false]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsageDescription() {
|
||||
return "Enable or disable logging connections";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String... args) {
|
||||
boolean newValue;
|
||||
if (args.length >= 1) {
|
||||
newValue = Boolean.parseBoolean(args[0]);
|
||||
server.serverSocketHandler.logConnections = newValue;
|
||||
} else
|
||||
newValue = server.serverSocketHandler.logConnections;
|
||||
LogHelper.subInfo("Log connections: " + newValue);
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package pro.gravit.launchserver.command.basic;
|
||||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
|
||||
public final class RebindCommand extends Command {
|
||||
public RebindCommand(LaunchServer server) {
|
||||
super(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgsDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsageDescription() {
|
||||
return "Rebind server socket";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String... args) {
|
||||
server.rebindServerSocket();
|
||||
}
|
||||
}
|
|
@ -1,11 +1,16 @@
|
|||
package pro.gravit.launchserver.command.basic;
|
||||
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import pro.gravit.launcher.events.PingEvent;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.launchserver.websocket.NettyServerSocketHandler;
|
||||
import pro.gravit.launchserver.socket.handlers.NettyServerSocketHandler;
|
||||
import pro.gravit.utils.helper.CommonHelper;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
|
||||
public class TestCommand extends Command {
|
||||
public TestCommand(LaunchServer server) {
|
||||
super(server);
|
||||
|
@ -34,8 +39,18 @@ public void invoke(String... args) throws Exception {
|
|||
if (args[0].equals("stop")) {
|
||||
handler.close();
|
||||
}
|
||||
if (args[0].equals("eventAll")) {
|
||||
handler.nettyServer.frameHandler.service.sendObjectAll(new PingEvent());
|
||||
if(args[0].equals("genCA")) {
|
||||
server.certificateManager.generateCA();
|
||||
server.certificateManager.writePrivateKey(Paths.get("ca.key"), server.certificateManager.caKey);
|
||||
server.certificateManager.writeCertificate(Paths.get("ca.crt"), server.certificateManager.ca);
|
||||
}
|
||||
if(args[0].equals("genCert")) {
|
||||
verifyArgs(args, 2);
|
||||
String name = args[1];
|
||||
KeyPair pair = server.certificateManager.generateKeyPair();
|
||||
X509CertificateHolder cert = server.certificateManager.generateCertificate(name, pair.getPublic());
|
||||
server.certificateManager.writePrivateKey(Paths.get(name.concat(".key")), pair.getPrivate());
|
||||
server.certificateManager.writeCertificate(Paths.get(name.concat(".crt")), cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public String getUsageDescription() {
|
|||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
int count = 0;
|
||||
for(User user : server.userService.findAllUsers())
|
||||
for(User user : server.config.dao.userService.findAllUsers())
|
||||
{
|
||||
LogHelper.subInfo("[%s] UUID: %s", user.username, user.uuid.toString());
|
||||
count++;
|
||||
|
|
|
@ -24,7 +24,7 @@ public String getUsageDescription() {
|
|||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 1);
|
||||
User user = server.userService.findUserByUsername(args[0]);
|
||||
User user = server.config.dao.userService.findUserByUsername(args[0]);
|
||||
if(user == null)
|
||||
{
|
||||
LogHelper.error("User %s not found", args[0]);
|
||||
|
|
|
@ -29,7 +29,7 @@ public void invoke(String... args) throws Exception {
|
|||
user.username = args[0];
|
||||
user.setPassword(args[1]);
|
||||
user.uuid = UUID.randomUUID();
|
||||
server.userService.saveUser(user);
|
||||
server.config.dao.userService.saveUser(user);
|
||||
LogHelper.info("User %s registered. UUID: %s", user.username, user.uuid.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,14 +24,14 @@ public String getUsageDescription() {
|
|||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 2);
|
||||
User user = server.userService.findUserByUsername(args[0]);
|
||||
User user = server.config.dao.userService.findUserByUsername(args[0]);
|
||||
if(user == null)
|
||||
{
|
||||
LogHelper.error("User %s not found", args[1]);
|
||||
return;
|
||||
}
|
||||
user.setPassword(args[1]);
|
||||
server.userService.updateUser(user);
|
||||
server.config.dao.userService.updateUser(user);
|
||||
LogHelper.info("[%s] UUID: %s | New Password: %s", user.username, user.uuid.toString(), args[1]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,59 @@
|
|||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||
import pro.gravit.launchserver.auth.handler.CachedAuthHandler;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.utils.command.SubCommand;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class DumpEntryCacheCommand extends Command {
|
||||
public DumpEntryCacheCommand(LaunchServer server) {
|
||||
super(server);
|
||||
childCommands.put("load", new SubCommand() {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 2);
|
||||
AuthProviderPair pair = server.config.getAuthProviderPair(args[0]);
|
||||
if (pair == null) throw new IllegalStateException(String.format("Auth %s not found", args[0]));
|
||||
if (!(pair.handler instanceof CachedAuthHandler))
|
||||
throw new UnsupportedOperationException("This command used only CachedAuthHandler");
|
||||
CachedAuthHandler authHandler = (CachedAuthHandler) pair.handler;
|
||||
|
||||
LogHelper.info("CachedAuthHandler read from %s", args[0]);
|
||||
int size_entry;
|
||||
int size_username;
|
||||
try (Reader reader = IOHelper.newReader(Paths.get(args[1]))) {
|
||||
EntryAndUsername entryAndUsername = Launcher.gsonManager.configGson.fromJson(reader, EntryAndUsername.class);
|
||||
size_entry = entryAndUsername.entryCache.size();
|
||||
size_username = entryAndUsername.usernameCache.size();
|
||||
authHandler.loadEntryCache(entryAndUsername.entryCache);
|
||||
authHandler.loadUsernameCache(entryAndUsername.usernameCache);
|
||||
|
||||
}
|
||||
LogHelper.subInfo("Readed %d entryCache %d usernameCache", size_entry, size_username);
|
||||
}
|
||||
});
|
||||
childCommands.put("unload", new SubCommand() {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 2);
|
||||
AuthProviderPair pair = server.config.getAuthProviderPair(args[0]);
|
||||
if (pair == null) throw new IllegalStateException(String.format("Auth %s not found", args[0]));
|
||||
if (!(pair.handler instanceof CachedAuthHandler))
|
||||
throw new UnsupportedOperationException("This command used only CachedAuthHandler");
|
||||
CachedAuthHandler authHandler = (CachedAuthHandler) pair.handler;
|
||||
|
||||
LogHelper.info("CachedAuthHandler write to %s", args[1]);
|
||||
Map<UUID, CachedAuthHandler.Entry> entryCache = authHandler.getEntryCache();
|
||||
Map<String, UUID> usernamesCache = authHandler.getUsernamesCache();
|
||||
EntryAndUsername serializable = new EntryAndUsername();
|
||||
serializable.entryCache = entryCache;
|
||||
serializable.usernameCache = usernamesCache;
|
||||
try (Writer writer = IOHelper.newWriter(Paths.get(args[1]))) {
|
||||
Launcher.gsonManager.configGson.toJson(serializable, writer);
|
||||
}
|
||||
LogHelper.subInfo("Write %d entryCache, %d usernameCache", entryCache.size(), usernamesCache.size());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,37 +78,7 @@ public String getUsageDescription() {
|
|||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 3);
|
||||
AuthProviderPair pair = server.config.getAuthProviderPair(args[1]);
|
||||
if (pair == null) throw new IllegalStateException(String.format("Auth %s not found", args[1]));
|
||||
if (!(pair.handler instanceof CachedAuthHandler))
|
||||
throw new UnsupportedOperationException("This command used only CachedAuthHandler");
|
||||
CachedAuthHandler authHandler = (CachedAuthHandler) pair.handler;
|
||||
if (args[0].equals("unload")) {
|
||||
LogHelper.info("CachedAuthHandler write to %s", args[2]);
|
||||
Map<UUID, CachedAuthHandler.Entry> entryCache = authHandler.getEntryCache();
|
||||
Map<String, UUID> usernamesCache = authHandler.getUsernamesCache();
|
||||
EntryAndUsername serializable = new EntryAndUsername();
|
||||
serializable.entryCache = entryCache;
|
||||
serializable.usernameCache = usernamesCache;
|
||||
try (Writer writer = IOHelper.newWriter(Paths.get(args[1]))) {
|
||||
Launcher.gsonManager.configGson.toJson(serializable, writer);
|
||||
}
|
||||
LogHelper.subInfo("Write %d entryCache, %d usernameCache", entryCache.size(), usernamesCache.size());
|
||||
} else if (args[0].equals("load")) {
|
||||
LogHelper.info("CachedAuthHandler read from %s", args[1]);
|
||||
int size_entry = 0;
|
||||
int size_username = 0;
|
||||
try (Reader reader = IOHelper.newReader(Paths.get(args[1]))) {
|
||||
EntryAndUsername entryAndUsername = Launcher.gsonManager.configGson.fromJson(reader, EntryAndUsername.class);
|
||||
size_entry = entryAndUsername.entryCache.size();
|
||||
size_username = entryAndUsername.usernameCache.size();
|
||||
authHandler.loadEntryCache(entryAndUsername.entryCache);
|
||||
authHandler.loadUsernameCache(entryAndUsername.usernameCache);
|
||||
|
||||
}
|
||||
LogHelper.subInfo("Readed %d entryCache %d usernameCache", size_entry, size_username);
|
||||
}
|
||||
invokeSubcommands(args);
|
||||
}
|
||||
|
||||
public class EntryAndUsername {
|
||||
|
|
|
@ -13,12 +13,41 @@
|
|||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.utils.command.SubCommand;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class DumpSessionsCommand extends Command {
|
||||
public DumpSessionsCommand(LaunchServer server) {
|
||||
super(server);
|
||||
childCommands.put("load", new SubCommand() {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 1);
|
||||
LogHelper.info("Sessions read from %s", args[0]);
|
||||
int size;
|
||||
try (Reader reader = IOHelper.newReader(Paths.get(args[0]))) {
|
||||
Type setType = new TypeToken<HashSet<Client>>() {
|
||||
}.getType();
|
||||
Set<Client> clientSet = Launcher.gsonManager.configGson.fromJson(reader, setType);
|
||||
size = clientSet.size();
|
||||
server.sessionManager.loadSessions(clientSet);
|
||||
}
|
||||
LogHelper.subInfo("Readed %d sessions", size);
|
||||
}
|
||||
});
|
||||
childCommands.put("unload", new SubCommand() {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 1);
|
||||
LogHelper.info("Sessions write to %s", args[0]);
|
||||
Set<Client> clientSet = server.sessionManager.getSessions();
|
||||
try (Writer writer = IOHelper.newWriter(Paths.get(args[0]))) {
|
||||
Launcher.gsonManager.configGson.toJson(clientSet, writer);
|
||||
}
|
||||
LogHelper.subInfo("Write %d sessions", clientSet.size());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -33,25 +62,6 @@ public String getUsageDescription() {
|
|||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 2);
|
||||
if (args[0].equals("unload")) {
|
||||
LogHelper.info("Sessions write to %s", args[1]);
|
||||
Set<Client> clientSet = server.sessionManager.getSessions();
|
||||
try (Writer writer = IOHelper.newWriter(Paths.get(args[1]))) {
|
||||
Launcher.gsonManager.configGson.toJson(clientSet, writer);
|
||||
}
|
||||
LogHelper.subInfo("Write %d sessions", clientSet.size());
|
||||
} else if (args[0].equals("load")) {
|
||||
LogHelper.info("Sessions read from %s", args[1]);
|
||||
int size = 0;
|
||||
try (Reader reader = IOHelper.newReader(Paths.get(args[1]))) {
|
||||
Type setType = new TypeToken<HashSet<Client>>() {
|
||||
}.getType();
|
||||
Set<Client> clientSet = Launcher.gsonManager.configGson.fromJson(reader, setType);
|
||||
size = clientSet.size();
|
||||
server.sessionManager.loadSessions(clientSet);
|
||||
}
|
||||
LogHelper.subInfo("Readed %d sessions", size);
|
||||
}
|
||||
invokeSubcommands(args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
import pro.gravit.launchserver.command.auth.UnbanCommand;
|
||||
import pro.gravit.launchserver.command.auth.UsernameToUUIDCommand;
|
||||
import pro.gravit.launchserver.command.basic.BuildCommand;
|
||||
import pro.gravit.launchserver.command.basic.LogConnectionsCommand;
|
||||
import pro.gravit.launchserver.command.basic.ProguardCleanCommand;
|
||||
import pro.gravit.launchserver.command.basic.RebindCommand;
|
||||
import pro.gravit.launchserver.command.basic.RegenProguardDictCommand;
|
||||
import pro.gravit.launchserver.command.basic.RemoveMappingsProguardCommand;
|
||||
import pro.gravit.launchserver.command.basic.RestartCommand;
|
||||
|
@ -34,17 +32,7 @@
|
|||
import pro.gravit.launchserver.command.install.MultiCommand;
|
||||
import pro.gravit.launchserver.command.modules.LoadModuleCommand;
|
||||
import pro.gravit.launchserver.command.modules.ModulesCommand;
|
||||
import pro.gravit.launchserver.command.service.ComponentCommand;
|
||||
import pro.gravit.launchserver.command.service.ConfigCommand;
|
||||
import pro.gravit.launchserver.command.service.ConfigHelpCommand;
|
||||
import pro.gravit.launchserver.command.service.ConfigListCommand;
|
||||
import pro.gravit.launchserver.command.service.GetModulusCommand;
|
||||
import pro.gravit.launchserver.command.service.GetPermissionsCommand;
|
||||
import pro.gravit.launchserver.command.service.GivePermissionsCommand;
|
||||
import pro.gravit.launchserver.command.service.ReloadAllCommand;
|
||||
import pro.gravit.launchserver.command.service.ReloadCommand;
|
||||
import pro.gravit.launchserver.command.service.ReloadListCommand;
|
||||
import pro.gravit.launchserver.command.service.ServerStatusCommand;
|
||||
import pro.gravit.launchserver.command.service.*;
|
||||
import pro.gravit.utils.command.BaseCommandCategory;
|
||||
import pro.gravit.utils.command.basic.ClearCommand;
|
||||
import pro.gravit.utils.command.basic.DebugCommand;
|
||||
|
@ -60,14 +48,12 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
|
|||
basic.registerCommand("build", new BuildCommand(server));
|
||||
basic.registerCommand("stop", new StopCommand(server));
|
||||
basic.registerCommand("restart", new RestartCommand(server));
|
||||
basic.registerCommand("rebind", new RebindCommand(server));
|
||||
basic.registerCommand("debug", new DebugCommand());
|
||||
basic.registerCommand("clear", new ClearCommand(handler));
|
||||
basic.registerCommand("gc", new GCCommand());
|
||||
basic.registerCommand("proguardClean", new ProguardCleanCommand(server));
|
||||
basic.registerCommand("proguardDictRegen", new RegenProguardDictCommand(server));
|
||||
basic.registerCommand("proguardMappingsRemove", new RemoveMappingsProguardCommand(server));
|
||||
basic.registerCommand("logConnections", new LogConnectionsCommand(server));
|
||||
basic.registerCommand("loadModule", new LoadModuleCommand(server));
|
||||
basic.registerCommand("modules", new ModulesCommand(server));
|
||||
basic.registerCommand("test", new TestCommand(server));
|
||||
|
@ -119,8 +105,6 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
|
|||
service.registerCommand("reloadAll", new ReloadAllCommand(server));
|
||||
service.registerCommand("reloadList", new ReloadListCommand(server));
|
||||
service.registerCommand("config", new ConfigCommand(server));
|
||||
service.registerCommand("configHelp", new ConfigHelpCommand(server));
|
||||
service.registerCommand("configList", new ConfigListCommand(server));
|
||||
service.registerCommand("serverStatus", new ServerStatusCommand(server));
|
||||
service.registerCommand("checkInstall", new CheckInstallCommand(server));
|
||||
service.registerCommand("multi", new MultiCommand(server));
|
||||
|
@ -128,6 +112,7 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
|
|||
service.registerCommand("component", new ComponentCommand(server));
|
||||
service.registerCommand("givePermission", new GivePermissionsCommand(server));
|
||||
service.registerCommand("getPermissions", new GetPermissionsCommand(server));
|
||||
service.registerCommand("clients", new ClientsCommand(server));
|
||||
Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components");
|
||||
handler.registerCategory(serviceCategory);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public void invoke(String... args) throws IOException, CommandException {
|
|||
client.setTitle(dirName);
|
||||
client.setDir(dirName);
|
||||
try (BufferedWriter writer = IOHelper.newWriter(IOHelper.resolveIncremental(server.profilesDir,
|
||||
dirName, "cfg"))) {
|
||||
dirName, "json"))) {
|
||||
Launcher.gsonManager.configGson.toJson(client, writer);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package pro.gravit.launchserver.command.service;
|
||||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.WebSocketService;
|
||||
import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class ClientsCommand extends Command {
|
||||
public ClientsCommand(LaunchServer server) {
|
||||
super(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgsDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsageDescription() {
|
||||
return "Show all connected clients";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
WebSocketService service = server.nettyServerSocketHandler.nettyServer.service;
|
||||
service.channels.forEach((channel -> {
|
||||
WebSocketFrameHandler frameHandler = channel.pipeline().get(WebSocketFrameHandler.class);
|
||||
Client client = frameHandler.getClient();
|
||||
String ip = IOHelper.getIP(channel.remoteAddress());
|
||||
if(!client.isAuth)
|
||||
LogHelper.info("Channel %s | checkSign %s", ip, client.checkSign ? "true" : "false");
|
||||
else
|
||||
{
|
||||
LogHelper.info("Client name %s | ip %s", client.username == null ? "null" : client.username, ip);
|
||||
LogHelper.subInfo("Data: checkSign %s | isSecure %s | auth_id %s", client.checkSign ? "true" : "false", client.isSecure ? "true" : "false",
|
||||
client.auth_id);
|
||||
LogHelper.subInfo("Permissions: %s (long %d)", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.toLong());
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.launchserver.manangers.ReconfigurableManager;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class ConfigCommand extends Command {
|
||||
public ConfigCommand(LaunchServer server) {
|
||||
super(server);
|
||||
super(server.reconfigurableManager.getCommands(), server);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -21,10 +22,6 @@ public String getUsageDescription() {
|
|||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 2);
|
||||
LogHelper.info("Call %s module %s action", args[0], args[1]);
|
||||
String[] new_args = new String[args.length - 2];
|
||||
System.arraycopy(args, 2, new_args, 0, args.length - 2);
|
||||
server.reconfigurableManager.call(args[0], args[1], new_args);
|
||||
invokeSubcommands(args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package pro.gravit.launchserver.command.service;
|
||||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class ConfigHelpCommand extends Command {
|
||||
public ConfigHelpCommand(LaunchServer server) {
|
||||
super(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgsDescription() {
|
||||
return "[name]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsageDescription() {
|
||||
return "print help for config command";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 1);
|
||||
LogHelper.info("Help %s module", args[0]);
|
||||
server.reconfigurableManager.printHelp(args[0]);
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package pro.gravit.launchserver.command.service;
|
||||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
|
||||
public class ConfigListCommand extends Command {
|
||||
public ConfigListCommand(LaunchServer server) {
|
||||
super(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgsDescription() {
|
||||
return "[name]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsageDescription() {
|
||||
return "print help for config command";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String... args) {
|
||||
server.reconfigurableManager.printReconfigurables();
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
import pro.gravit.launcher.NeedGarbageCollection;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.auth.AuthResponse;
|
||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
import pro.gravit.utils.BiHookSet.Hook;
|
||||
import pro.gravit.utils.HookException;
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ public abstract class Component {
|
|||
public static void registerComponents() {
|
||||
if (!registredComp) {
|
||||
providers.register("authLimiter", AuthLimiterComponent.class);
|
||||
providers.register("regLimiter", RegLimiterComponent.class);
|
||||
providers.register("commandRemover", CommandRemoverComponent.class);
|
||||
providers.register("hibernate", HibernateConfiguratorComponent.class);
|
||||
registredComp = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package pro.gravit.launchserver.components;
|
||||
|
||||
import pro.gravit.launcher.NeedGarbageCollection;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
|
||||
import pro.gravit.utils.HookException;
|
||||
import pro.gravit.utils.HookSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class RegLimiterComponent extends Component implements NeedGarbageCollection, AutoCloseable {
|
||||
|
||||
public static final long TIMEOUT = 12 * 60 * 60 * 1000; //12 часов
|
||||
public transient LaunchServer launchServer;
|
||||
public int rateLimit;
|
||||
public int rateLimitMilis;
|
||||
public String message;
|
||||
public transient HookSet.Hook<AuthHookManager.RegContext> hook;
|
||||
|
||||
public transient HashMap<String, AuthLimiterComponent.AuthEntry> map = new HashMap<>();
|
||||
public List<String> excludeIps = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void preInit(LaunchServer launchServer) {
|
||||
this.launchServer = launchServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LaunchServer launchServer) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(LaunchServer launchServer) {
|
||||
launchServer.authHookManager.registraion.registerHook(context -> {
|
||||
if (isLimit(context.ip)) {
|
||||
throw new HookException(message);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void garbageCollection() {
|
||||
long time = System.currentTimeMillis();
|
||||
long max_timeout = Math.max(rateLimitMilis, TIMEOUT);
|
||||
map.entrySet().removeIf(e -> e.getValue().ts + max_timeout < time);
|
||||
}
|
||||
|
||||
public boolean isLimit(String ip) {
|
||||
if (excludeIps.contains(ip)) return false;
|
||||
if (map.containsKey(ip)) {
|
||||
AuthLimiterComponent.AuthEntry rate = map.get(ip);
|
||||
long currenttime = System.currentTimeMillis();
|
||||
if (rate.ts + rateLimitMilis < currenttime) rate.value = 0;
|
||||
if (rate.value >= rateLimit && rateLimit > 0) {
|
||||
rate.value++;
|
||||
rate.ts = currenttime;
|
||||
return true;
|
||||
}
|
||||
rate.value++;
|
||||
rate.ts = currenttime;
|
||||
return false;
|
||||
}
|
||||
map.put(ip, new AuthLimiterComponent.AuthEntry(1, System.currentTimeMillis()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
if(hook != null)
|
||||
launchServer.authHookManager.registraion.unregisterHook(hook);
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
public class LaunchServerRuntimeConfig {
|
||||
public String clientToken;
|
||||
public String oemUnlockKey;
|
||||
public String registerApiKey;
|
||||
|
||||
public void verify() {
|
||||
if (clientToken == null) LogHelper.error("[RuntimeConfig] clientToken must not be null");
|
||||
|
@ -13,5 +14,6 @@ public void verify() {
|
|||
|
||||
public void reset() {
|
||||
clientToken = SecurityHelper.randomStringToken();
|
||||
registerApiKey = SecurityHelper.randomStringToken();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package pro.gravit.launchserver.dao;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.dao.impl.DefaultUserDAOImpl;
|
||||
|
||||
public class LaunchServerDaoFactory {
|
||||
private static final Function<LaunchServer, UserDAO> defDao = DefaultUserDAOImpl::new;
|
||||
private static final Map<LaunchServer, Function<LaunchServer, UserDAO>> daos = new ConcurrentHashMap<>();
|
||||
|
||||
public static void setUserDaoProvider(LaunchServer srv, Function<LaunchServer, UserDAO> getDao) {
|
||||
daos.put(srv, getDao);
|
||||
}
|
||||
|
||||
public static UserDAO createUserDao(LaunchServer srv)
|
||||
{
|
||||
return daos.getOrDefault(srv, defDao).apply(srv);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package pro.gravit.launchserver.dao;
|
||||
|
||||
import pro.gravit.launcher.OshiHWID;
|
||||
import pro.gravit.launcher.hwid.OshiHWID;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package pro.gravit.launchserver.dao;
|
||||
|
||||
import pro.gravit.launcher.HWID;
|
||||
import pro.gravit.launcher.OshiHWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
import pro.gravit.launcher.hwid.OshiHWID;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.function.Supplier;
|
||||
|
|
|
@ -9,8 +9,8 @@ public class UserService {
|
|||
|
||||
private final UserDAO usersDao;
|
||||
|
||||
public UserService(LaunchServer server) {
|
||||
usersDao = LaunchServerDaoFactory.createUserDao(server);
|
||||
public UserService(UserDAO usersDAO) {
|
||||
this.usersDao = usersDAO;
|
||||
}
|
||||
|
||||
public User findUser(int id) {
|
||||
|
@ -24,6 +24,15 @@ public User findUserByUUID(UUID uuid) {
|
|||
return usersDao.findByUUID(uuid);
|
||||
}
|
||||
|
||||
public User registerNewUser(String username, String password)
|
||||
{
|
||||
User user = new User();
|
||||
user.username = username;
|
||||
user.setPassword(password);
|
||||
user.uuid = UUID.randomUUID();
|
||||
return user;
|
||||
}
|
||||
|
||||
public void saveUser(User user) {
|
||||
usersDao.save(user);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import pro.gravit.launcher.OshiHWID;
|
||||
import pro.gravit.launcher.hwid.OshiHWID;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.dao.User;
|
||||
import pro.gravit.launchserver.dao.UserDAO;
|
||||
|
|
|
@ -9,30 +9,29 @@
|
|||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.Transaction;
|
||||
|
||||
import pro.gravit.launcher.OshiHWID;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launcher.hwid.OshiHWID;
|
||||
import pro.gravit.launchserver.dao.User;
|
||||
import pro.gravit.launchserver.dao.UserDAO;
|
||||
import pro.gravit.launchserver.dao.UserHWID;
|
||||
import pro.gravit.launchserver.hibernate.SessionFactoryManager;
|
||||
|
||||
public class HibernateUserDAOImpl implements UserDAO {
|
||||
private final SessionFactoryManager manager;
|
||||
private final SessionFactory factory;
|
||||
|
||||
public HibernateUserDAOImpl(LaunchServer srv) {
|
||||
manager = SessionFactoryManager.forLaunchServer(srv);
|
||||
public HibernateUserDAOImpl(SessionFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public User findById(int id) {
|
||||
try (Session s = manager.fact.openSession()) {
|
||||
try (Session s = factory.openSession()) {
|
||||
return s.get(User.class, id);
|
||||
}
|
||||
}
|
||||
|
||||
public User findByUsername(String username) {
|
||||
EntityManager em = manager.fact.createEntityManager();
|
||||
EntityManager em = factory.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<User> personCriteria = cb.createQuery(User.class);
|
||||
|
@ -44,7 +43,7 @@ public User findByUsername(String username) {
|
|||
}
|
||||
|
||||
public User findByUUID(UUID uuid) {
|
||||
EntityManager em = manager.fact.createEntityManager();
|
||||
EntityManager em = factory.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<User> personCriteria = cb.createQuery(User.class);
|
||||
|
@ -57,7 +56,7 @@ public User findByUUID(UUID uuid) {
|
|||
|
||||
@Override
|
||||
public List<UserHWID> findHWID(OshiHWID hwid) {
|
||||
EntityManager em = manager.fact.createEntityManager();
|
||||
EntityManager em = factory.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<UserHWID> personCriteria = cb.createQuery(UserHWID.class);
|
||||
|
@ -77,7 +76,7 @@ public List<UserHWID> findHWID(OshiHWID hwid) {
|
|||
}
|
||||
|
||||
public void save(User user) {
|
||||
try (Session session = manager.fact.openSession()) {
|
||||
try (Session session = factory.openSession()) {
|
||||
Transaction tx1 = session.beginTransaction();
|
||||
session.save(user);
|
||||
tx1.commit();
|
||||
|
@ -85,7 +84,7 @@ public void save(User user) {
|
|||
}
|
||||
|
||||
public void update(User user) {
|
||||
try (Session session = manager.fact.openSession()) {
|
||||
try (Session session = factory.openSession()) {
|
||||
Transaction tx1 = session.beginTransaction();
|
||||
session.update(user);
|
||||
tx1.commit();
|
||||
|
@ -93,7 +92,7 @@ public void update(User user) {
|
|||
}
|
||||
|
||||
public void delete(User user) {
|
||||
try (Session session = manager.fact.openSession()) {
|
||||
try (Session session = factory.openSession()) {
|
||||
Transaction tx1 = session.beginTransaction();
|
||||
session.delete(user);
|
||||
tx1.commit();
|
||||
|
@ -102,7 +101,7 @@ public void delete(User user) {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<User> findAll() {
|
||||
try (Session s = manager.fact.openSession()) {
|
||||
try (Session s = factory.openSession()) {
|
||||
return (List<User>) s.createQuery("From User").list();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package pro.gravit.launchserver.dao.provider;
|
||||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.dao.UserDAO;
|
||||
import pro.gravit.launchserver.dao.UserService;
|
||||
import pro.gravit.utils.ProviderMap;
|
||||
|
||||
public abstract class DaoProvider {
|
||||
public static ProviderMap<DaoProvider> providers = new ProviderMap<>("DaoProvider");
|
||||
public UserDAO userDAO;
|
||||
public UserService userService;
|
||||
public static void registerProviders()
|
||||
{
|
||||
providers.register("hibernate", HibernateDaoProvider.class);
|
||||
}
|
||||
public abstract void init(LaunchServer server);
|
||||
}
|
|
@ -1,18 +1,16 @@
|
|||
package pro.gravit.launchserver.components;
|
||||
package pro.gravit.launchserver.dao.provider;
|
||||
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.dao.User;
|
||||
import pro.gravit.launchserver.dao.UserHWID;
|
||||
import pro.gravit.launchserver.dao.UserService;
|
||||
import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl;
|
||||
import pro.gravit.utils.helper.CommonHelper;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.hibernate.cfg.Configuration;
|
||||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.dao.LaunchServerDaoFactory;
|
||||
import pro.gravit.launchserver.dao.User;
|
||||
import pro.gravit.launchserver.dao.UserHWID;
|
||||
import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl;
|
||||
import pro.gravit.launchserver.hibernate.SessionFactoryManager;
|
||||
import pro.gravit.utils.helper.CommonHelper;
|
||||
|
||||
public class HibernateConfiguratorComponent extends Component {
|
||||
public class HibernateDaoProvider extends DaoProvider {
|
||||
public String driver;
|
||||
public String url;
|
||||
public String username;
|
||||
|
@ -20,9 +18,9 @@ public class HibernateConfiguratorComponent extends Component {
|
|||
public String pool_size;
|
||||
public String hibernateConfig;
|
||||
public boolean parallelHibernateInit;
|
||||
|
||||
@Override
|
||||
public void preInit(LaunchServer launchServer) {
|
||||
LaunchServerDaoFactory.setUserDaoProvider(launchServer, HibernateUserDAOImpl::new);
|
||||
public void init(LaunchServer server) {
|
||||
Runnable init = () -> {
|
||||
Configuration cfg = new Configuration()
|
||||
.addAnnotatedClass(User.class)
|
||||
|
@ -34,30 +32,12 @@ public void preInit(LaunchServer launchServer) {
|
|||
.setProperty("hibernate.connection.pool_size", pool_size);
|
||||
if(hibernateConfig != null)
|
||||
cfg.configure(Paths.get(hibernateConfig).toFile());
|
||||
SessionFactoryManager.forLaunchServer(launchServer).fact = cfg.buildSessionFactory();
|
||||
userDAO = new HibernateUserDAOImpl(cfg.buildSessionFactory());
|
||||
userService = new UserService(userDAO);
|
||||
};
|
||||
if(parallelHibernateInit)
|
||||
CommonHelper.newThread("Hibernate Thread", true, init);
|
||||
else
|
||||
init.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LaunchServer launchServer) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(LaunchServer launchServer) {
|
||||
//UserService service = new UserService();
|
||||
//List<User> users = service.findAllUsers();
|
||||
//User newUser = new User();
|
||||
//newUser.username = "VeryTestUser";
|
||||
//newUser.setPassword("12345");
|
||||
//service.saveUser(newUser);
|
||||
//for(User u : users)
|
||||
//{
|
||||
// LogHelper.info("Found User %s", u.username);
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package pro.gravit.launchserver.hibernate;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
|
||||
public class SessionFactoryManager {
|
||||
public SessionFactory fact;
|
||||
private static final Map<LaunchServer, SessionFactoryManager> sessionFactories = new ConcurrentHashMap<>();
|
||||
private static final Function<LaunchServer, SessionFactoryManager> cr = e -> new SessionFactoryManager();
|
||||
public static SessionFactoryManager forLaunchServer(LaunchServer srv) {
|
||||
return sessionFactories.computeIfAbsent(srv, cr);
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package pro.gravit.launchserver.legacy;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import pro.gravit.launcher.serialize.HInput;
|
||||
import pro.gravit.launcher.serialize.HOutput;
|
||||
import pro.gravit.launcher.serialize.SerializeLimits;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
|
||||
public final class PingResponse extends Response {
|
||||
public PingResponse(LaunchServer server, long id, HInput input, HOutput output, String ip, Client clientData) {
|
||||
super(server, id, input, output, ip, clientData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply() throws IOException {
|
||||
output.writeUnsignedByte(SerializeLimits.EXPECTED_BYTE);
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
package pro.gravit.launchserver.legacy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import pro.gravit.launcher.request.RequestException;
|
||||
import pro.gravit.launcher.request.RequestType;
|
||||
import pro.gravit.launcher.serialize.HInput;
|
||||
import pro.gravit.launcher.serialize.HOutput;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.legacy.update.LauncherResponse;
|
||||
import pro.gravit.launchserver.legacy.update.LegacyLauncherResponse;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public abstract class Response {
|
||||
@FunctionalInterface
|
||||
public interface Factory<R> {
|
||||
|
||||
Response newResponse(LaunchServer server, long id, HInput input, HOutput output, String ip, Client clientData);
|
||||
}
|
||||
|
||||
private static final Map<Integer, Factory<?>> RESPONSES = new ConcurrentHashMap<>(8);
|
||||
|
||||
public static Response getResponse(int type, LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||
return RESPONSES.get(type).newResponse(server, session, input, output, ip, clientData);
|
||||
}
|
||||
|
||||
public static void registerResponse(int type, Factory<?> factory) {
|
||||
RESPONSES.put(type, factory);
|
||||
}
|
||||
|
||||
public static void registerResponses() {
|
||||
registerResponse(RequestType.PING.getNumber(), PingResponse::new);
|
||||
registerResponse(RequestType.LEGACYLAUNCHER.getNumber(), LegacyLauncherResponse::new);
|
||||
registerResponse(RequestType.LAUNCHER.getNumber(), LauncherResponse::new);
|
||||
}
|
||||
|
||||
|
||||
public static void requestError(String message) throws RequestException {
|
||||
throw new RequestException(message);
|
||||
}
|
||||
|
||||
|
||||
protected final LaunchServer server;
|
||||
|
||||
|
||||
protected final HInput input;
|
||||
|
||||
|
||||
protected final HOutput output;
|
||||
|
||||
|
||||
protected final String ip;
|
||||
|
||||
protected final Client clientData;
|
||||
|
||||
|
||||
protected final long session;
|
||||
|
||||
protected Response(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||
this.server = server;
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.ip = ip;
|
||||
this.session = session;
|
||||
this.clientData = clientData;
|
||||
}
|
||||
|
||||
|
||||
protected final void debug(String message) {
|
||||
LogHelper.subDebug("#%d %s", session, message);
|
||||
}
|
||||
|
||||
|
||||
protected final void debug(String message, Object... args) {
|
||||
debug(String.format(message, args));
|
||||
}
|
||||
|
||||
|
||||
public abstract void reply() throws Exception;
|
||||
|
||||
|
||||
protected static void writeNoError(HOutput output) throws IOException {
|
||||
output.writeString("", 0);
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package pro.gravit.launchserver.legacy.update;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import pro.gravit.launcher.serialize.HInput;
|
||||
import pro.gravit.launcher.serialize.HOutput;
|
||||
import pro.gravit.launcher.serialize.SerializeLimits;
|
||||
import pro.gravit.launcher.serialize.signed.DigestBytesHolder;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.legacy.Response;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
|
||||
public final class LauncherResponse extends Response {
|
||||
|
||||
public LauncherResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||
super(server, session, input, output, ip, clientData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply() throws IOException {
|
||||
// Resolve launcher binary
|
||||
DigestBytesHolder bytes = (input.readBoolean() ? server.launcherEXEBinary : server.launcherBinary).getBytes();
|
||||
if (bytes == null) {
|
||||
requestError("Missing launcher binary");
|
||||
return;
|
||||
}
|
||||
byte[] digest = input.readByteArray(SerializeLimits.MAX_DIGEST);
|
||||
if (!Arrays.equals(bytes.getDigest(), digest)) {
|
||||
writeNoError(output);
|
||||
output.writeBoolean(true);
|
||||
output.writeByteArray(bytes.getBytes(), 0);
|
||||
clientData.checkSign = false;
|
||||
return;
|
||||
}
|
||||
writeNoError(output);
|
||||
output.writeBoolean(false);
|
||||
clientData.checkSign = true;
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package pro.gravit.launchserver.legacy.update;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import pro.gravit.launcher.serialize.HInput;
|
||||
import pro.gravit.launcher.serialize.HOutput;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.binary.LauncherBinary;
|
||||
import pro.gravit.launchserver.legacy.Response;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
public final class LegacyLauncherResponse extends Response {
|
||||
|
||||
public LegacyLauncherResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||
super(server, session, input, output, ip, clientData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply() throws IOException {
|
||||
// Resolve launcher binary
|
||||
LauncherBinary bytes = (input.readBoolean() ? server.launcherEXEBinary : server.launcherBinary);
|
||||
if (bytes == null) {
|
||||
requestError("Missing launcher binary");
|
||||
return;
|
||||
}
|
||||
writeNoError(output);
|
||||
|
||||
// Update launcher binary
|
||||
output.writeByteArray(bytes.getSign(), -SecurityHelper.RSA_KEY_LENGTH);
|
||||
output.flush();
|
||||
if (input.readBoolean()) {
|
||||
output.writeByteArray(bytes.getBytes().getBytes(), 0);
|
||||
return; // Launcher will be restarted
|
||||
}
|
||||
requestError("You must update");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package pro.gravit.launchserver.manangers;
|
||||
|
||||
|
||||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
import org.bouncycastle.asn1.x500.X500NameBuilder;
|
||||
import org.bouncycastle.asn1.x500.style.BCStyle;
|
||||
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
|
||||
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
|
||||
import org.bouncycastle.cert.CertIOException;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
||||
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
|
||||
import org.bouncycastle.crypto.params.ECKeyParameters;
|
||||
import org.bouncycastle.crypto.util.PrivateKeyFactory;
|
||||
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
|
||||
import org.bouncycastle.jce.ECNamedCurveTable;
|
||||
import org.bouncycastle.jce.spec.ECParameterSpec;
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.bouncycastle.operator.ContentSigner;
|
||||
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
|
||||
import org.bouncycastle.operator.OperatorCreationException;
|
||||
import org.bouncycastle.operator.bc.BcECContentSignerBuilder;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.bouncycastle.util.io.pem.PemObject;
|
||||
import org.bouncycastle.util.io.pem.PemWriter;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.file.Path;
|
||||
import java.security.*;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Date;
|
||||
|
||||
public class CertificateManager {
|
||||
public X509CertificateHolder ca;
|
||||
public AsymmetricKeyParameter caKey;
|
||||
|
||||
//public X509CertificateHolder server;
|
||||
//public AsymmetricKeyParameter serverKey;
|
||||
|
||||
public int validDays = 60;
|
||||
public int minusHours = 6;
|
||||
|
||||
public X509CertificateHolder generateCertificate(String subjectName, PublicKey subjectPublicKey) throws OperatorCreationException {
|
||||
SubjectPublicKeyInfo subjectPubKeyInfo = SubjectPublicKeyInfo.getInstance(subjectPublicKey.getEncoded());
|
||||
BigInteger serial = BigInteger.valueOf(SecurityHelper.newRandom().nextLong());
|
||||
Date startDate = Date.from(Instant.now().minus(minusHours, ChronoUnit.HOURS));
|
||||
Date endDate = Date.from(startDate.toInstant().plus(validDays, ChronoUnit.DAYS));
|
||||
|
||||
X500NameBuilder subject = new X500NameBuilder();
|
||||
subject.addRDN(BCStyle.CN, subjectName);
|
||||
X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder(ca.getSubject(), serial,
|
||||
startDate, endDate, subject.build(), subjectPubKeyInfo);
|
||||
|
||||
AlgorithmIdentifier sigAlgId = ca.getSignatureAlgorithm();
|
||||
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
|
||||
ContentSigner sigGen = new BcECContentSignerBuilder(sigAlgId, digAlgId).build(caKey);
|
||||
|
||||
return v3CertGen.build(sigGen);
|
||||
}
|
||||
|
||||
public void generateCA() throws NoSuchAlgorithmException, IOException, OperatorCreationException, InvalidAlgorithmParameterException {
|
||||
ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("secp384r1");
|
||||
KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
|
||||
generator.initialize(ecGenSpec, SecurityHelper.newRandom());
|
||||
KeyPair pair = generator.generateKeyPair();
|
||||
LocalDateTime startDate = LocalDate.now().atStartOfDay();
|
||||
|
||||
X509v3CertificateBuilder builder= new X509v3CertificateBuilder(
|
||||
new X500Name("CN=ca"),
|
||||
new BigInteger("0"),
|
||||
Date.from(startDate.atZone(ZoneId.systemDefault()).toInstant()),
|
||||
Date.from(startDate.plusDays(3650).atZone(ZoneId.systemDefault()).toInstant()),
|
||||
new X500Name("CN=ca"),
|
||||
SubjectPublicKeyInfo.getInstance(pair.getPublic().getEncoded()));
|
||||
JcaContentSignerBuilder csBuilder= new JcaContentSignerBuilder("SHA256WITHECDSA");
|
||||
ContentSigner signer = csBuilder.build(pair.getPrivate());
|
||||
ca = builder.build(signer);
|
||||
caKey = PrivateKeyFactory.createKey(pair.getPrivate().getEncoded());
|
||||
}
|
||||
|
||||
public KeyPair generateKeyPair() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
||||
ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("secp384r1");
|
||||
KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
|
||||
generator.initialize(ecGenSpec, SecurityHelper.newRandom());
|
||||
return generator.generateKeyPair();
|
||||
}
|
||||
|
||||
public void writePrivateKey(Path file, PrivateKey privateKey) throws IOException {
|
||||
try (PemWriter writer = new PemWriter(IOHelper.newWriter(file))) {
|
||||
writer.writeObject(new PemObject("PRIVATE KEY", privateKey.getEncoded()));
|
||||
}
|
||||
}
|
||||
|
||||
public void writePrivateKey(Path file, AsymmetricKeyParameter key) throws IOException {
|
||||
PrivateKeyInfo info = PrivateKeyInfoFactory.createPrivateKeyInfo(key);
|
||||
try (PemWriter writer = new PemWriter(IOHelper.newWriter(file))) {
|
||||
writer.writeObject(new PemObject("PRIVATE KEY", info.getEncoded()));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeCertificate(Path file, X509CertificateHolder holder) throws IOException {
|
||||
try (PemWriter writer = new PemWriter(IOHelper.newWriter(file))) {
|
||||
writer.writeObject(new PemObject("CERTIFICATE", holder.toASN1Structure().getEncoded()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,14 @@
|
|||
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import pro.gravit.launcher.hasher.HashedEntry;
|
||||
import pro.gravit.launcher.hasher.HashedEntryAdapter;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
import pro.gravit.launcher.hwid.HWIDProvider;
|
||||
import pro.gravit.launcher.managers.GsonManager;
|
||||
import pro.gravit.launcher.request.JsonResultSerializeAdapter;
|
||||
import pro.gravit.launcher.request.WebSocketEvent;
|
||||
import pro.gravit.launcher.request.websockets.ClientWebSocketService;
|
||||
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
||||
import pro.gravit.launchserver.auth.hwid.HWIDHandler;
|
||||
import pro.gravit.launchserver.auth.permissions.PermissionsHandler;
|
||||
|
@ -10,6 +17,9 @@
|
|||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||
import pro.gravit.launchserver.components.Component;
|
||||
import pro.gravit.launchserver.dao.provider.DaoProvider;
|
||||
import pro.gravit.launchserver.socket.WebSocketService;
|
||||
import pro.gravit.launchserver.socket.response.WebSocketServerResponse;
|
||||
import pro.gravit.utils.UniversalJsonAdapter;
|
||||
|
||||
public class LaunchServerGsonManager extends GsonManager {
|
||||
|
@ -23,5 +33,10 @@ public void registerAdapters(GsonBuilder builder) {
|
|||
builder.registerTypeAdapter(HWIDHandler.class, new UniversalJsonAdapter<>(HWIDHandler.providers));
|
||||
builder.registerTypeAdapter(Component.class, new UniversalJsonAdapter<>(Component.providers));
|
||||
builder.registerTypeAdapter(ProtectHandler.class, new UniversalJsonAdapter<>(ProtectHandler.providers));
|
||||
builder.registerTypeAdapter(DaoProvider.class, new UniversalJsonAdapter<>(DaoProvider.providers));
|
||||
builder.registerTypeAdapter(HWID.class, new UniversalJsonAdapter<>(HWIDProvider.hwids));
|
||||
builder.registerTypeAdapter(WebSocketServerResponse.class, new UniversalJsonAdapter<>(WebSocketService.providers));
|
||||
builder.registerTypeAdapter(WebSocketEvent.class, new JsonResultSerializeAdapter());
|
||||
//ClientWebSocketService.appendTypeAdapters(builder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,65 @@
|
|||
package pro.gravit.launchserver.manangers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import pro.gravit.launchserver.Reconfigurable;
|
||||
import pro.gravit.utils.command.Command;
|
||||
import pro.gravit.utils.command.CommandException;
|
||||
import pro.gravit.utils.command.basic.HelpCommand;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
import pro.gravit.utils.helper.VerifyHelper;
|
||||
|
||||
public class ReconfigurableManager {
|
||||
private final HashMap<String, Reconfigurable> RECONFIGURABLE = new HashMap<>();
|
||||
private class ReconfigurableVirtualCommand extends Command {
|
||||
public ReconfigurableVirtualCommand(Map<String, Command> childs) {
|
||||
super(childs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgsDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsageDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
invokeSubcommands(args);
|
||||
}
|
||||
}
|
||||
private final HashMap<String, Command> RECONFIGURABLE = new HashMap<>();
|
||||
|
||||
public void registerReconfigurable(String name, Reconfigurable reconfigurable) {
|
||||
VerifyHelper.putIfAbsent(RECONFIGURABLE, name.toLowerCase(), Objects.requireNonNull(reconfigurable, "adapter"),
|
||||
VerifyHelper.putIfAbsent(RECONFIGURABLE, name.toLowerCase(), new ReconfigurableVirtualCommand(reconfigurable.getCommands()),
|
||||
String.format("Reloadable has been already registered: '%s'", name));
|
||||
}
|
||||
|
||||
public Reconfigurable unregisterReconfigurable(String name) {
|
||||
return RECONFIGURABLE.remove(name);
|
||||
public void unregisterReconfigurable(String name) {
|
||||
RECONFIGURABLE.remove(name);
|
||||
}
|
||||
|
||||
public void printHelp(String name) {
|
||||
RECONFIGURABLE.get(name.toLowerCase()).printConfigHelp();
|
||||
public void call(String name, String action, String[] args) throws Exception
|
||||
{
|
||||
Command commands = RECONFIGURABLE.get(name);
|
||||
if(commands == null) throw new CommandException(String.format("Reconfigurable %s not found", name));
|
||||
Command command = commands.childCommands.get(action);
|
||||
if(command == null) throw new CommandException(String.format("Action %s.%s not found", name, action));
|
||||
command.invoke(args);
|
||||
}
|
||||
|
||||
public void call(String name, String action, String[] args) {
|
||||
RECONFIGURABLE.get(name.toLowerCase()).reconfig(action.toLowerCase(), args);
|
||||
public void printHelp(String name) throws CommandException
|
||||
{
|
||||
Command commands = RECONFIGURABLE.get(name);
|
||||
if(commands == null) throw new CommandException(String.format("Reconfigurable %s not found", name));
|
||||
HelpCommand.printSubCommandsHelp(name, commands);
|
||||
}
|
||||
|
||||
public void printReconfigurables() {
|
||||
LogHelper.info("Print reconfigurables");
|
||||
RECONFIGURABLE.forEach((k, v) -> LogHelper.subInfo(k));
|
||||
LogHelper.info("Found %d reconfigurables", RECONFIGURABLE.size());
|
||||
public Map<String, Command> getCommands()
|
||||
{
|
||||
return RECONFIGURABLE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package pro.gravit.launchserver.manangers.hook;
|
||||
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.auth.AuthResponse;
|
||||
import pro.gravit.launchserver.websocket.json.auth.CheckServerResponse;
|
||||
import pro.gravit.launchserver.websocket.json.auth.JoinServerResponse;
|
||||
import pro.gravit.launchserver.websocket.json.auth.SetProfileResponse;
|
||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
import pro.gravit.launchserver.socket.response.auth.CheckServerResponse;
|
||||
import pro.gravit.launchserver.socket.response.auth.JoinServerResponse;
|
||||
import pro.gravit.launchserver.socket.response.auth.SetProfileResponse;
|
||||
import pro.gravit.utils.BiHookSet;
|
||||
import pro.gravit.utils.HookSet;
|
||||
|
||||
public class AuthHookManager {
|
||||
public BiHookSet<AuthResponse.AuthContext, Client> preHook = new BiHookSet<>();
|
||||
|
@ -13,4 +14,18 @@ public class AuthHookManager {
|
|||
public BiHookSet<CheckServerResponse, Client> checkServerHook = new BiHookSet<>();
|
||||
public BiHookSet<JoinServerResponse, Client> joinServerHook = new BiHookSet<>();
|
||||
public BiHookSet<SetProfileResponse, Client> setProfileHook = new BiHookSet<>();
|
||||
public static class RegContext
|
||||
{
|
||||
public String login;
|
||||
public String password;
|
||||
public String ip;
|
||||
public boolean trustContext;
|
||||
public RegContext(String login, String password, String ip, boolean trustContext) {
|
||||
this.login = login;
|
||||
this.password = password;
|
||||
this.ip = ip;
|
||||
this.trustContext = trustContext;
|
||||
}
|
||||
}
|
||||
public HookSet<RegContext> registraion = new HookSet<>();
|
||||
}
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
package pro.gravit.launchserver.manangers.hook;
|
||||
|
||||
import java.net.Socket;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import pro.gravit.launcher.request.RequestException;
|
||||
import pro.gravit.launchserver.socket.SocketContext;
|
||||
|
||||
public class SocketHookManager {
|
||||
@FunctionalInterface
|
||||
public interface SocketPreHook {
|
||||
boolean preHook(SocketContext context); //Вернуть true если необходимо продолжть обработку, false если остановить обработку
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SocketPostHook {
|
||||
void postHook(SocketContext context);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SocketErrorHook {
|
||||
boolean errorHook(SocketContext context, RequestException e); //Вернуть true если необходимо продолжть обработку, false если остановить обработку
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SocketFatalErrorHook {
|
||||
boolean fatalErrorHook(Socket socket, Exception e); //Вернуть true если необходимо продолжть обработку, false если остановить обработку
|
||||
}
|
||||
|
||||
private Set<SocketPostHook> POST_HOOKS;
|
||||
private Set<SocketPreHook> PRE_HOOKS;
|
||||
private Set<SocketErrorHook> ERROR_HOOKS;
|
||||
private Set<SocketFatalErrorHook> FATALERROR_HOOKS;
|
||||
|
||||
public void registerPostHook(SocketPostHook hook) {
|
||||
if (POST_HOOKS == null) POST_HOOKS = new HashSet<>();
|
||||
POST_HOOKS.add(hook);
|
||||
}
|
||||
|
||||
public void registerPreHook(SocketPreHook hook) {
|
||||
if (PRE_HOOKS == null) PRE_HOOKS = new HashSet<>();
|
||||
PRE_HOOKS.add(hook);
|
||||
}
|
||||
|
||||
public void registerErrorHook(SocketErrorHook hook) {
|
||||
if (ERROR_HOOKS == null) ERROR_HOOKS = new HashSet<>();
|
||||
ERROR_HOOKS.add(hook);
|
||||
}
|
||||
|
||||
public void registerFatalErrorHook(SocketFatalErrorHook hook) {
|
||||
if (FATALERROR_HOOKS == null) FATALERROR_HOOKS = new HashSet<>();
|
||||
FATALERROR_HOOKS.add(hook);
|
||||
}
|
||||
|
||||
public boolean preHook(SocketContext context) {
|
||||
if (PRE_HOOKS == null) return true;
|
||||
for (SocketPreHook preHook : PRE_HOOKS) {
|
||||
if (!preHook.preHook(context)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void postHook(SocketContext context) {
|
||||
if (POST_HOOKS == null) return;
|
||||
for (SocketPostHook postHook : POST_HOOKS) {
|
||||
postHook.postHook(context);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean errorHook(SocketContext context, RequestException e) {
|
||||
if (ERROR_HOOKS == null) return true;
|
||||
for (SocketErrorHook errorHook : ERROR_HOOKS) {
|
||||
if (!errorHook.errorHook(context, e)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean fatalErrorHook(Socket socket, Exception e) {
|
||||
if (FATALERROR_HOOKS == null) return true;
|
||||
for (SocketFatalErrorHook errorHook : FATALERROR_HOOKS) {
|
||||
if (!errorHook.fatalErrorHook(socket, e)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket;
|
||||
package pro.gravit.launchserver.socket;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
|
@ -7,39 +7,52 @@
|
|||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.channel.group.DefaultChannelGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
|
||||
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||
import pro.gravit.launcher.request.Request;
|
||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
||||
import pro.gravit.launcher.request.websockets.StandartClientWebSocketService;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.websocket.fileserver.FileServerHandler;
|
||||
import pro.gravit.launchserver.socket.handlers.NettyIpForwardHandler;
|
||||
import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler;
|
||||
import pro.gravit.launchserver.socket.handlers.fileserver.FileServerHandler;
|
||||
import pro.gravit.utils.helper.JVMHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class LauncherNettyServer implements AutoCloseable {
|
||||
public final ServerBootstrap serverBootstrap;
|
||||
public final EventLoopGroup bossGroup;
|
||||
public final EventLoopGroup workerGroup;
|
||||
public WebSocketFrameHandler frameHandler = null;
|
||||
public final WebSocketService service;
|
||||
private static final String WEBSOCKET_PATH = "/api";
|
||||
|
||||
public LauncherNettyServer(LaunchServer server) {
|
||||
LaunchServer.NettyConfig config = server.config.netty;
|
||||
bossGroup = new NioEventLoopGroup(config.performance.bossThread);
|
||||
workerGroup = new NioEventLoopGroup(config.performance.workerThread);
|
||||
NettyObjectFactory.setUsingEpoll(config.performance.usingEpoll);
|
||||
if(config.performance.usingEpoll)
|
||||
{
|
||||
LogHelper.debug("Netty: Epoll enabled");
|
||||
}
|
||||
if(config.performance.usingEpoll && JVMHelper.OS_TYPE != JVMHelper.OS.LINUX)
|
||||
{
|
||||
LogHelper.error("netty,perfomance.usingEpoll work only Linux systems");
|
||||
}
|
||||
bossGroup = NettyObjectFactory.newEventLoopGroup(config.performance.bossThread);
|
||||
workerGroup = NettyObjectFactory.newEventLoopGroup(config.performance.workerThread);
|
||||
serverBootstrap = new ServerBootstrap();
|
||||
service = new WebSocketService(new DefaultChannelGroup(GlobalEventExecutor.INSTANCE), server);
|
||||
serverBootstrap.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.channel(NettyObjectFactory.getServerSocketChannelClass())
|
||||
.handler(new LoggingHandler(config.logLevel))
|
||||
.childHandler(new ChannelInitializer<NioSocketChannel>() {
|
||||
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
public void initChannel(NioSocketChannel ch) {
|
||||
public void initChannel(SocketChannel ch) {
|
||||
ChannelPipeline pipeline = ch.pipeline();
|
||||
NettyConnectContext context = new NettyConnectContext();
|
||||
//p.addLast(new LoggingHandler(LogLevel.INFO));
|
||||
|
@ -51,8 +64,7 @@ public void initChannel(NioSocketChannel ch) {
|
|||
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
|
||||
if (server.config.netty.fileServerEnabled)
|
||||
pipeline.addLast(new FileServerHandler(server.updatesDir, true));
|
||||
frameHandler = new WebSocketFrameHandler(context, server);
|
||||
pipeline.addLast(frameHandler);
|
||||
pipeline.addLast(new WebSocketFrameHandler(context, server, service));
|
||||
}
|
||||
});
|
||||
if (config.proxy != null && config.proxy.enabled) {
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket;
|
||||
package pro.gravit.launchserver.socket;
|
||||
|
||||
public class NettyConnectContext {
|
||||
public String ip = null;
|
|
@ -0,0 +1,31 @@
|
|||
package pro.gravit.launchserver.socket;
|
||||
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.ServerChannel;
|
||||
import io.netty.channel.epoll.EpollEventLoopGroup;
|
||||
import io.netty.channel.epoll.EpollServerSocketChannel;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
|
||||
public class NettyObjectFactory {
|
||||
private static boolean epoll = false;
|
||||
public static void setUsingEpoll(boolean value)
|
||||
{
|
||||
epoll = value;
|
||||
}
|
||||
public static EventLoopGroup newEventLoopGroup(int threads)
|
||||
{
|
||||
if(epoll)
|
||||
return new EpollEventLoopGroup(threads);
|
||||
else
|
||||
return new NioEventLoopGroup(threads);
|
||||
}
|
||||
public static Class<? extends ServerChannel> getServerSocketChannelClass()
|
||||
{
|
||||
if(epoll)
|
||||
return EpollServerSocketChannel.class;
|
||||
else
|
||||
return NioServerSocketChannel.class;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
package pro.gravit.launchserver.socket;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
|
||||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.launcher.request.RequestException;
|
||||
import pro.gravit.launcher.serialize.HInput;
|
||||
import pro.gravit.launcher.serialize.HOutput;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.legacy.Response;
|
||||
import pro.gravit.launchserver.manangers.SessionManager;
|
||||
import pro.gravit.launchserver.manangers.hook.SocketHookManager;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
public final class ResponseThread implements Runnable {
|
||||
class Handshake {
|
||||
int type;
|
||||
long session;
|
||||
|
||||
public Handshake(int type, long session) {
|
||||
this.type = type;
|
||||
this.session = session;
|
||||
}
|
||||
}
|
||||
|
||||
private final LaunchServer server;
|
||||
private final Socket socket;
|
||||
|
||||
private final SessionManager sessions;
|
||||
private final SocketHookManager socketHookManager;
|
||||
|
||||
public ResponseThread(LaunchServer server, long id, Socket socket, SessionManager sessionManager, SocketHookManager socketHookManager) throws SocketException {
|
||||
this.server = server;
|
||||
this.socket = socket;
|
||||
sessions = sessionManager;
|
||||
this.socketHookManager = socketHookManager;
|
||||
// Fix socket flags
|
||||
IOHelper.setSocketFlags(socket);
|
||||
}
|
||||
|
||||
private Handshake readHandshake(HInput input, HOutput output) throws IOException {
|
||||
boolean legacy = false;
|
||||
long session = 0;
|
||||
// Verify magic number
|
||||
int magicNumber = input.readInt();
|
||||
if (magicNumber != Launcher.PROTOCOL_MAGIC)
|
||||
if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY - 1) { // Previous launcher protocol
|
||||
session = 0;
|
||||
legacy = true;
|
||||
} else if (magicNumber == ServerSocketHandler.LEGACY_LAUNCHER_MAGIC) { // Previous launcher protocol
|
||||
session = 0;
|
||||
legacy = true;
|
||||
} else if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY) {
|
||||
|
||||
} else
|
||||
throw new IOException("Invalid Handshake");
|
||||
// Verify key modulus
|
||||
BigInteger keyModulus = input.readBigInteger(SecurityHelper.RSA_KEY_LENGTH + 1);
|
||||
if (!legacy) {
|
||||
session = input.readLong();
|
||||
sessions.updateClient(session);
|
||||
}
|
||||
if (!keyModulus.equals(server.privateKey.getModulus())) {
|
||||
output.writeBoolean(false);
|
||||
throw new IOException(String.format("#%d Key modulus mismatch", session));
|
||||
}
|
||||
// Read request type
|
||||
int type = input.readVarInt();
|
||||
if (!server.serverSocketHandler.onHandshake(session, type)) {
|
||||
output.writeBoolean(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Protocol successfully verified
|
||||
output.writeBoolean(true);
|
||||
output.flush();
|
||||
return new Handshake(type, session);
|
||||
}
|
||||
|
||||
private void respond(Integer type, HInput input, HOutput output, long session, String ip, Client clientData) throws Exception {
|
||||
if (server.serverSocketHandler.logConnections)
|
||||
LogHelper.info("Connection #%d from %s", session, ip);
|
||||
|
||||
// Choose response based on type
|
||||
Response response = Response.getResponse(type, server, session, input, output, ip, clientData);
|
||||
|
||||
// Reply
|
||||
response.reply();
|
||||
LogHelper.subDebug("#%d Replied", session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!server.serverSocketHandler.logConnections)
|
||||
LogHelper.debug("Connection from %s", IOHelper.getIP(socket.getRemoteSocketAddress()));
|
||||
|
||||
// Process connection
|
||||
boolean cancelled = false;
|
||||
Exception savedError = null;
|
||||
try (HInput input = new HInput(socket.getInputStream());
|
||||
HOutput output = new HOutput(socket.getOutputStream())) {
|
||||
Handshake handshake = readHandshake(input, output);
|
||||
if (handshake == null) { // Not accepted
|
||||
cancelled = true;
|
||||
return;
|
||||
}
|
||||
SocketContext context = new SocketContext();
|
||||
context.input = input;
|
||||
context.output = output;
|
||||
context.ip = IOHelper.getIP(socket.getRemoteSocketAddress());
|
||||
context.session = handshake.session;
|
||||
context.type = handshake.type;
|
||||
Client clientData = server.sessionManager.getOrNewClient(context.session);
|
||||
context.client = clientData;
|
||||
|
||||
// Start response
|
||||
if (socketHookManager.preHook(context)) {
|
||||
try {
|
||||
respond(handshake.type, input, output, handshake.session, context.ip, clientData);
|
||||
socketHookManager.postHook(context);
|
||||
} catch (RequestException e) {
|
||||
if (server.socketHookManager.errorHook(context, e)) {
|
||||
LogHelper.subDebug(String.format("#%d Request error: %s", handshake.session, e.getMessage()));
|
||||
if (e.getMessage() == null) LogHelper.error(e);
|
||||
output.writeString(e.getMessage(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
savedError = e;
|
||||
if (server.socketHookManager.fatalErrorHook(socket, e))
|
||||
LogHelper.error(e);
|
||||
} finally {
|
||||
IOHelper.close(socket);
|
||||
if (!cancelled)
|
||||
server.serverSocketHandler.onDisconnect(savedError);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
package pro.gravit.launchserver.socket;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.launcher.managers.GarbageManager;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.manangers.SessionManager;
|
||||
import pro.gravit.utils.helper.CommonHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public final class ServerSocketHandler implements Runnable, AutoCloseable {
|
||||
public interface Listener {
|
||||
|
||||
boolean onConnect(InetAddress address);
|
||||
|
||||
|
||||
void onDisconnect(Exception e);
|
||||
|
||||
|
||||
boolean onHandshake(long session, int type);
|
||||
}
|
||||
|
||||
private static final ThreadFactory THREAD_FACTORY = r -> CommonHelper.newThread("Network Thread", true, r);
|
||||
|
||||
|
||||
public volatile boolean logConnections = Boolean.getBoolean("launcher.logConnections");
|
||||
// Instance
|
||||
private final LaunchServer server;
|
||||
private final AtomicReference<ServerSocket> serverSocket = new AtomicReference<>();
|
||||
private final ExecutorService threadPool;
|
||||
|
||||
public final SessionManager sessionManager;
|
||||
private final AtomicLong idCounter = new AtomicLong(0L);
|
||||
public static int LEGACY_LAUNCHER_MAGIC = Launcher.PROTOCOL_MAGIC_LEGACY - 2;
|
||||
|
||||
private volatile Listener listener;
|
||||
|
||||
public ServerSocketHandler(LaunchServer server) {
|
||||
this(server, new SessionManager());
|
||||
GarbageManager.registerNeedGC(sessionManager);
|
||||
}
|
||||
|
||||
public ServerSocketHandler(LaunchServer server, SessionManager sessionManager) {
|
||||
this.server = server;
|
||||
threadPool = new ThreadPoolExecutor(server.config.threadCoreCount, Integer.MAX_VALUE,
|
||||
server.config.threadCount, TimeUnit.SECONDS,
|
||||
new SynchronousQueue<>(),
|
||||
THREAD_FACTORY);
|
||||
this.sessionManager = sessionManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
ServerSocket socket = serverSocket.getAndSet(null);
|
||||
if (socket != null) {
|
||||
LogHelper.info("Closing server socket listener");
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void onDisconnect(Exception e) {
|
||||
if (listener != null)
|
||||
listener.onDisconnect(e);
|
||||
}
|
||||
|
||||
/*package*/ boolean onHandshake(long session, int type) {
|
||||
return listener == null || listener.onHandshake(session, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LogHelper.info("Starting server socket thread");
|
||||
try (ServerSocket serverSocket = new ServerSocket()) {
|
||||
if (!this.serverSocket.compareAndSet(null, serverSocket))
|
||||
throw new IllegalStateException("Previous socket wasn't closed");
|
||||
|
||||
// Set socket params
|
||||
serverSocket.setReuseAddress(true);
|
||||
serverSocket.setPerformancePreferences(1, 0, 2);
|
||||
//serverSocket.setReceiveBufferSize(0x10000);
|
||||
serverSocket.bind(server.config.getSocketAddress());
|
||||
LogHelper.info("Server socket thread successfully started");
|
||||
|
||||
// Listen for incoming connections
|
||||
while (serverSocket.isBound()) {
|
||||
Socket socket = serverSocket.accept();
|
||||
|
||||
// Invoke pre-connect listener
|
||||
long id = idCounter.incrementAndGet();
|
||||
if (listener != null && !listener.onConnect(socket.getInetAddress())) {
|
||||
socket.close();
|
||||
continue; // Listener didn't accepted this connection
|
||||
}
|
||||
|
||||
|
||||
// Reply in separate thread
|
||||
threadPool.execute(new ResponseThread(server, id, socket, sessionManager, server.socketHookManager));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignore error after close/rebind
|
||||
if (serverSocket.get() != null)
|
||||
LogHelper.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setListener(Listener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package pro.gravit.launchserver.socket;
|
||||
|
||||
import pro.gravit.launcher.serialize.HInput;
|
||||
import pro.gravit.launcher.serialize.HOutput;
|
||||
|
||||
public class SocketContext {
|
||||
public HInput input;
|
||||
public HOutput output;
|
||||
public long session;
|
||||
public String ip;
|
||||
public Integer type;
|
||||
public Client client;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket;
|
||||
package pro.gravit.launchserver.socket;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
|
@ -6,73 +6,61 @@
|
|||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.group.ChannelGroup;
|
||||
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
||||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.launcher.events.ExceptionEvent;
|
||||
import pro.gravit.launcher.events.RequestEvent;
|
||||
import pro.gravit.launcher.events.request.AuthRequestEvent;
|
||||
import pro.gravit.launcher.events.request.ErrorRequestEvent;
|
||||
import pro.gravit.launcher.hasher.HashedEntry;
|
||||
import pro.gravit.launcher.hasher.HashedEntryAdapter;
|
||||
import pro.gravit.launcher.request.JsonResultSerializeAdapter;
|
||||
import pro.gravit.launcher.request.Request;
|
||||
import pro.gravit.launcher.request.RequestException;
|
||||
import pro.gravit.launcher.request.ResultInterface;
|
||||
import pro.gravit.launcher.request.WebSocketEvent;
|
||||
import pro.gravit.launcher.request.admin.ProxyRequest;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.JsonResponseAdapter;
|
||||
import pro.gravit.launchserver.websocket.json.JsonResponseInterface;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.websocket.json.admin.AddLogListenerResponse;
|
||||
import pro.gravit.launchserver.websocket.json.admin.ExecCommandResponse;
|
||||
import pro.gravit.launchserver.websocket.json.admin.ProxyCommandResponse;
|
||||
import pro.gravit.launchserver.websocket.json.auth.AuthResponse;
|
||||
import pro.gravit.launchserver.websocket.json.auth.CheckServerResponse;
|
||||
import pro.gravit.launchserver.websocket.json.auth.GetAvailabilityAuthResponse;
|
||||
import pro.gravit.launchserver.websocket.json.auth.JoinServerResponse;
|
||||
import pro.gravit.launchserver.websocket.json.auth.ProfilesResponse;
|
||||
import pro.gravit.launchserver.websocket.json.auth.RestoreSessionResponse;
|
||||
import pro.gravit.launchserver.websocket.json.auth.SetProfileResponse;
|
||||
import pro.gravit.launchserver.websocket.json.profile.BatchProfileByUsername;
|
||||
import pro.gravit.launchserver.websocket.json.profile.ProfileByUUIDResponse;
|
||||
import pro.gravit.launchserver.websocket.json.profile.ProfileByUsername;
|
||||
import pro.gravit.launchserver.websocket.json.secure.GetSecureTokenResponse;
|
||||
import pro.gravit.launchserver.websocket.json.secure.VerifySecureTokenResponse;
|
||||
import pro.gravit.launchserver.websocket.json.update.LauncherResponse;
|
||||
import pro.gravit.launchserver.websocket.json.update.UpdateListResponse;
|
||||
import pro.gravit.launchserver.websocket.json.update.UpdateResponse;
|
||||
import pro.gravit.launchserver.socket.response.WebSocketServerResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.admin.AddLogListenerResponse;
|
||||
import pro.gravit.launchserver.socket.response.admin.ExecCommandResponse;
|
||||
import pro.gravit.launchserver.socket.response.admin.ProxyCommandResponse;
|
||||
import pro.gravit.launchserver.socket.response.auth.*;
|
||||
import pro.gravit.launchserver.socket.response.profile.BatchProfileByUsername;
|
||||
import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse;
|
||||
import pro.gravit.launchserver.socket.response.profile.ProfileByUsername;
|
||||
import pro.gravit.launchserver.socket.response.secure.GetSecureTokenResponse;
|
||||
import pro.gravit.launchserver.socket.response.secure.VerifySecureTokenResponse;
|
||||
import pro.gravit.launchserver.socket.response.update.LauncherResponse;
|
||||
import pro.gravit.launchserver.socket.response.update.UpdateListResponse;
|
||||
import pro.gravit.launchserver.socket.response.update.UpdateResponse;
|
||||
import pro.gravit.utils.ProviderMap;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class WebSocketService {
|
||||
public final ChannelGroup channels;
|
||||
public static ProviderMap<WebSocketServerResponse> providers = new ProviderMap<>();
|
||||
|
||||
public WebSocketService(ChannelGroup channels, LaunchServer server, GsonBuilder gson) {
|
||||
public WebSocketService(ChannelGroup channels, LaunchServer server) {
|
||||
this.channels = channels;
|
||||
this.server = server;
|
||||
this.gsonBuiler = gson;
|
||||
this.gsonBuiler.registerTypeAdapter(JsonResponseInterface.class, new JsonResponseAdapter(this));
|
||||
this.gsonBuiler.registerTypeAdapter(ResultInterface.class, new JsonResultSerializeAdapter());
|
||||
this.gsonBuiler.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter());
|
||||
this.gson = gsonBuiler.create();
|
||||
//this.gsonBuiler.registerTypeAdapter(WebSocketServerResponse.class, new JsonResponseAdapter(this));
|
||||
//this.gsonBuiler.registerTypeAdapter(WebSocketEvent.class, new JsonResultSerializeAdapter());
|
||||
//this.gsonBuiler.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter());
|
||||
this.gson = Launcher.gsonManager.gson;
|
||||
}
|
||||
|
||||
private final LaunchServer server;
|
||||
private static final HashMap<String, Class> responses = new HashMap<>();
|
||||
private final Gson gson;
|
||||
private final GsonBuilder gsonBuiler;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) {
|
||||
public void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) {
|
||||
String request = frame.text();
|
||||
JsonResponseInterface response = gson.fromJson(request, JsonResponseInterface.class);
|
||||
WebSocketServerResponse response = gson.fromJson(request, WebSocketServerResponse.class);
|
||||
if (server.config.netty.proxy.enabled) {
|
||||
if (server.config.netty.proxy.requests.contains(response.getType())) {
|
||||
|
||||
|
@ -94,7 +82,7 @@ void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client,
|
|||
}
|
||||
proxyRequest.isCheckSign = client.checkSign;
|
||||
try {
|
||||
ResultInterface result = proxyRequest.request();
|
||||
WebSocketEvent result = proxyRequest.request();
|
||||
if (result instanceof AuthRequestEvent) {
|
||||
LogHelper.debug("Client auth params get successful");
|
||||
AuthRequestEvent authRequestEvent = (AuthRequestEvent) result;
|
||||
|
@ -128,7 +116,7 @@ void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client,
|
|||
process(ctx, response, client, ip);
|
||||
}
|
||||
|
||||
void process(ChannelHandlerContext ctx, JsonResponseInterface response, Client client, String ip) {
|
||||
void process(ChannelHandlerContext ctx, WebSocketServerResponse response, Client client, String ip) {
|
||||
if (response instanceof SimpleResponse) {
|
||||
SimpleResponse simpleResponse = (SimpleResponse) response;
|
||||
simpleResponse.server = server;
|
||||
|
@ -158,46 +146,43 @@ public Class getResponseClass(String type) {
|
|||
return responses.get(type);
|
||||
}
|
||||
|
||||
public void registerResponse(String key, Class responseInterfaceClass) {
|
||||
responses.put(key, responseInterfaceClass);
|
||||
}
|
||||
|
||||
public void registerClient(Channel channel) {
|
||||
channels.add(channel);
|
||||
}
|
||||
|
||||
public void registerResponses() {
|
||||
registerResponse("auth", AuthResponse.class);
|
||||
registerResponse("checkServer", CheckServerResponse.class);
|
||||
registerResponse("joinServer", JoinServerResponse.class);
|
||||
registerResponse("profiles", ProfilesResponse.class);
|
||||
registerResponse("launcher", LauncherResponse.class);
|
||||
registerResponse("updateList", UpdateListResponse.class);
|
||||
registerResponse("cmdExec", ExecCommandResponse.class);
|
||||
registerResponse("setProfile", SetProfileResponse.class);
|
||||
registerResponse("addLogListener", AddLogListenerResponse.class);
|
||||
registerResponse("update", UpdateResponse.class);
|
||||
registerResponse("restoreSession", RestoreSessionResponse.class);
|
||||
registerResponse("batchProfileByUsername", BatchProfileByUsername.class);
|
||||
registerResponse("profileByUsername", ProfileByUsername.class);
|
||||
registerResponse("profileByUUID", ProfileByUUIDResponse.class);
|
||||
registerResponse("getSecureToken", GetSecureTokenResponse.class);
|
||||
registerResponse("verifySecureToken", VerifySecureTokenResponse.class);
|
||||
registerResponse("getAvailabilityAuth", GetAvailabilityAuthResponse.class);
|
||||
registerResponse("proxy", ProxyCommandResponse.class);
|
||||
public static void registerResponses() {
|
||||
providers.register("auth", AuthResponse.class);
|
||||
providers.register("checkServer", CheckServerResponse.class);
|
||||
providers.register("joinServer", JoinServerResponse.class);
|
||||
providers.register("profiles", ProfilesResponse.class);
|
||||
providers.register("launcher", LauncherResponse.class);
|
||||
providers.register("updateList", UpdateListResponse.class);
|
||||
providers.register("cmdExec", ExecCommandResponse.class);
|
||||
providers.register("setProfile", SetProfileResponse.class);
|
||||
providers.register("addLogListener", AddLogListenerResponse.class);
|
||||
providers.register("update", UpdateResponse.class);
|
||||
providers.register("restoreSession", RestoreSessionResponse.class);
|
||||
providers.register("batchProfileByUsername", BatchProfileByUsername.class);
|
||||
providers.register("profileByUsername", ProfileByUsername.class);
|
||||
providers.register("profileByUUID", ProfileByUUIDResponse.class);
|
||||
providers.register("getSecureToken", GetSecureTokenResponse.class);
|
||||
providers.register("verifySecureToken", VerifySecureTokenResponse.class);
|
||||
providers.register("getAvailabilityAuth", GetAvailabilityAuthResponse.class);
|
||||
providers.register("proxy", ProxyCommandResponse.class);
|
||||
providers.register("register", RegisterResponse.class);
|
||||
}
|
||||
|
||||
public void sendObject(ChannelHandlerContext ctx, Object obj) {
|
||||
ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, ResultInterface.class)));
|
||||
ctx.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, WebSocketEvent.class)));
|
||||
}
|
||||
|
||||
public void sendObject(ChannelHandlerContext ctx, Object obj, Type type) {
|
||||
ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type)));
|
||||
ctx.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type)));
|
||||
}
|
||||
|
||||
public void sendObjectAll(Object obj) {
|
||||
for (Channel ch : channels) {
|
||||
ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, ResultInterface.class)));
|
||||
ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, WebSocketEvent.class)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,18 +193,18 @@ public void sendObjectAll(Object obj, Type type) {
|
|||
}
|
||||
|
||||
public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) {
|
||||
ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, ResultInterface.class))).addListener(ChannelFutureListener.CLOSE);
|
||||
ctx.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, WebSocketEvent.class))).addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
|
||||
public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj, Type type) {
|
||||
ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type))).addListener(ChannelFutureListener.CLOSE);
|
||||
ctx.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type))).addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
|
||||
public void sendEvent(EventResult obj) {
|
||||
channels.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj)));
|
||||
}
|
||||
|
||||
public static class EventResult implements ResultInterface {
|
||||
public static class EventResult implements WebSocketEvent {
|
||||
public EventResult() {
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket;
|
||||
package pro.gravit.launchserver.socket.handlers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
|||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.util.ReferenceCounted;
|
||||
import pro.gravit.launchserver.socket.NettyConnectContext;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class NettyIpForwardHandler extends MessageToMessageDecoder<HttpRequest> {
|
|
@ -1,9 +1,7 @@
|
|||
package pro.gravit.launchserver.websocket;
|
||||
package pro.gravit.launchserver.socket.handlers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
|
@ -12,12 +10,7 @@
|
|||
import java.security.SecureRandom;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
@ -27,9 +20,8 @@
|
|||
import pro.gravit.launcher.ssl.LauncherKeyStore;
|
||||
import pro.gravit.launcher.ssl.LauncherTrustManager;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.legacy.Response;
|
||||
import pro.gravit.launchserver.socket.LauncherNettyServer;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
import pro.gravit.utils.helper.VerifyHelper;
|
||||
|
||||
@SuppressWarnings({"unused", "rawtypes"})
|
||||
public final class NettyServerSocketHandler implements Runnable, AutoCloseable {
|
||||
|
@ -39,13 +31,8 @@ public final class NettyServerSocketHandler implements Runnable, AutoCloseable {
|
|||
|
||||
public LauncherNettyServer nettyServer;
|
||||
|
||||
private final AtomicReference<ServerSocket> serverSocket = new AtomicReference<>();
|
||||
|
||||
// API
|
||||
private final Map<String, Response.Factory> customResponses = new ConcurrentHashMap<>(2);
|
||||
private final AtomicLong idCounter = new AtomicLong(0L);
|
||||
private Set<Socket> sockets;
|
||||
private volatile Listener listener;
|
||||
|
||||
private transient final LaunchServer server;
|
||||
|
||||
|
@ -55,15 +42,7 @@ public NettyServerSocketHandler(LaunchServer server) {
|
|||
|
||||
@Override
|
||||
public void close() {
|
||||
ServerSocket socket = serverSocket.getAndSet(null);
|
||||
if (socket != null) {
|
||||
LogHelper.info("Closing server socket listener");
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
}
|
||||
//TODO: Close Impl
|
||||
}
|
||||
|
||||
public SSLContext SSLContextInit() throws NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, KeyManagementException, IOException, CertificateException {
|
||||
|
@ -149,37 +128,4 @@ public void run() {
|
|||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
public void registerCustomResponse(String name, Response.Factory factory) {
|
||||
VerifyHelper.verifyIDName(name);
|
||||
VerifyHelper.putIfAbsent(customResponses, name, Objects.requireNonNull(factory, "factory"),
|
||||
String.format("Custom response has been already registered: '%s'", name));
|
||||
}
|
||||
|
||||
|
||||
public void setListener(Listener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
/*package*/ void onDisconnect(long id, Exception e) {
|
||||
if (listener != null) {
|
||||
listener.onDisconnect(id, e);
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ boolean onHandshake(long id, Integer type) {
|
||||
return listener == null || listener.onHandshake(id, type);
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
||||
boolean onConnect(long id, InetAddress address);
|
||||
|
||||
|
||||
void onDisconnect(long id, Exception e);
|
||||
|
||||
|
||||
boolean onHandshake(long id, Integer type);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket;
|
||||
package pro.gravit.launchserver.socket.handlers;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -15,21 +15,21 @@
|
|||
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.NettyConnectContext;
|
||||
import pro.gravit.launchserver.socket.WebSocketService;
|
||||
import pro.gravit.utils.helper.CommonHelper;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
|
||||
public final LaunchServer srv;
|
||||
public static GsonBuilder builder = CommonHelper.newBuilder();
|
||||
public final WebSocketService service;
|
||||
public NettyConnectContext context;
|
||||
|
||||
public WebSocketFrameHandler(NettyConnectContext context, LaunchServer srv) {
|
||||
public WebSocketFrameHandler(NettyConnectContext context, LaunchServer srv, WebSocketService service) {
|
||||
this.context = context;
|
||||
this.srv = srv;
|
||||
service = new WebSocketService(new DefaultChannelGroup(GlobalEventExecutor.INSTANCE), srv, builder);
|
||||
service.registerResponses();
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
private Client client;
|
||||
|
@ -41,6 +41,8 @@ public void setClient(Client client) {
|
|||
this.client = client;
|
||||
}
|
||||
|
||||
public Client getClient() { return client; }
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) {
|
||||
LogHelper.dev("New client %s", IOHelper.getIP(ctx.channel().remoteAddress()));
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.fileserver;
|
||||
package pro.gravit.launchserver.socket.handlers.fileserver;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.fileserver;
|
||||
package pro.gravit.launchserver.socket.handlers.fileserver;
|
||||
|
||||
import static io.netty.handler.codec.http.HttpMethod.GET;
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
|
||||
|
@ -17,6 +17,7 @@
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
@ -45,7 +46,6 @@
|
|||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpUtil;
|
||||
import io.netty.handler.codec.http.LastHttpContent;
|
||||
import io.netty.handler.ssl.SslHandler;
|
||||
import io.netty.handler.stream.ChunkedFile;
|
||||
import io.netty.util.CharsetUtil;
|
||||
|
||||
|
@ -55,6 +55,7 @@ public class FileServerHandler extends SimpleChannelInboundHandler<FullHttpReque
|
|||
public static final String HTTP_DATE_GMT_TIMEZONE = "GMT";
|
||||
public static final String READ = "r";
|
||||
public static final int HTTP_CACHE_SECONDS = 60;
|
||||
private static final boolean OLD_ALGO = Boolean.parseBoolean(System.getProperty("launcher.fileserver.oldalgo", "true"));
|
||||
private final Path base;
|
||||
private final boolean fullOut;
|
||||
|
||||
|
@ -143,11 +144,12 @@ public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) thr
|
|||
// Write the content.
|
||||
ChannelFuture sendFileFuture;
|
||||
ChannelFuture lastContentFuture;
|
||||
if (ctx.pipeline().get(SslHandler.class) == null) {
|
||||
if (OLD_ALGO) {
|
||||
sendFileFuture =
|
||||
ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise());
|
||||
// Write the end marker.
|
||||
lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
|
||||
lastContentFuture.addListener(new ClosingChannelFutureListener(raf));
|
||||
} else {
|
||||
sendFileFuture =
|
||||
ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)),
|
||||
|
@ -158,7 +160,6 @@ public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) thr
|
|||
|
||||
// Decide whether to close the connection or not.
|
||||
if (!HttpUtil.isKeepAlive(request)) {
|
||||
lastContentFuture.addListener(new ClosingChannelFutureListener(raf));
|
||||
lastContentFuture.addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
}
|
||||
|
@ -188,15 +189,7 @@ private static String sanitizeUri(String uri) {
|
|||
// Convert file separators.
|
||||
uri = uri.replace(File.separatorChar, '/');
|
||||
|
||||
// Simplistic dumb security check.
|
||||
// You will have to do something serious in the production environment.
|
||||
if (uri.contains(File.separator + '.') ||
|
||||
uri.contains('.' + File.separator) ||
|
||||
uri.charAt(0) == '.' || uri.charAt(uri.length() - 1) == '.' ||
|
||||
INSECURE_URI.matcher(uri).matches()) {
|
||||
return null;
|
||||
}
|
||||
return uri.substring(1);
|
||||
return Paths.get(uri).normalize().toString().substring(1);
|
||||
}
|
||||
|
||||
private static final Pattern ALLOWED_FILE_NAME = Pattern.compile("[^-\\._]?[^<>&\\\"]*");
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.json;
|
||||
package pro.gravit.launchserver.socket.response;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -6,10 +6,9 @@
|
|||
import pro.gravit.launcher.events.RequestEvent;
|
||||
import pro.gravit.launcher.events.request.ErrorRequestEvent;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.WebSocketService;
|
||||
import pro.gravit.launchserver.socket.WebSocketService;
|
||||
|
||||
public abstract class SimpleResponse implements JsonResponseInterface {
|
||||
public abstract class SimpleResponse implements WebSocketServerResponse {
|
||||
public UUID requestUUID;
|
||||
public transient LaunchServer server;
|
||||
public transient WebSocketService service;
|
||||
|
@ -31,9 +30,4 @@ public void sendError(String errorMessage) {
|
|||
event.requestUUID = requestUUID;
|
||||
service.sendObject(ctx, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package pro.gravit.launchserver.websocket.json;
|
||||
package pro.gravit.launchserver.socket.response;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.request.websockets.RequestInterface;
|
||||
import pro.gravit.launcher.request.websockets.WebSocketRequest;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
|
||||
public interface JsonResponseInterface extends RequestInterface {
|
||||
public interface WebSocketServerResponse extends WebSocketRequest {
|
||||
String getType();
|
||||
|
||||
void execute(ChannelHandlerContext ctx, Client client) throws Exception;
|
|
@ -1,9 +1,9 @@
|
|||
package pro.gravit.launchserver.websocket.json.admin;
|
||||
package pro.gravit.launchserver.socket.response.admin;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.LogEvent;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class AddLogListenerResponse extends SimpleResponse {
|
|
@ -1,9 +1,9 @@
|
|||
package pro.gravit.launchserver.websocket.json.admin;
|
||||
package pro.gravit.launchserver.socket.response.admin;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.ExecCommandRequestEvent;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
public class ExecCommandResponse extends SimpleResponse {
|
||||
public String cmd;
|
|
@ -1,12 +1,12 @@
|
|||
package pro.gravit.launchserver.websocket.json.admin;
|
||||
package pro.gravit.launchserver.socket.response.admin;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.JsonResponseInterface;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.WebSocketServerResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
public class ProxyCommandResponse extends SimpleResponse {
|
||||
public JsonResponseInterface response;
|
||||
public WebSocketServerResponse response;
|
||||
public long session;
|
||||
public boolean isCheckSign;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.json.auth;
|
||||
package pro.gravit.launchserver.socket.response.auth;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Collection;
|
||||
|
@ -9,7 +9,8 @@
|
|||
import javax.crypto.IllegalBlockSizeException;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.OshiHWID;
|
||||
import pro.gravit.launcher.hwid.HWID;
|
||||
import pro.gravit.launcher.hwid.OshiHWID;
|
||||
import pro.gravit.launcher.events.request.AuthRequestEvent;
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
import pro.gravit.launchserver.auth.AuthException;
|
||||
|
@ -18,8 +19,8 @@
|
|||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
||||
import pro.gravit.launchserver.auth.provider.AuthProviderResult;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.websocket.json.profile.ProfileByUUIDResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse;
|
||||
import pro.gravit.utils.HookException;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
@ -46,7 +47,7 @@ public AuthResponse(String login, String password, String auth_id, OshiHWID hwid
|
|||
public String auth_id;
|
||||
public boolean initProxy;
|
||||
public ConnectTypes authType;
|
||||
public OshiHWID hwid;
|
||||
public HWID hwid;
|
||||
|
||||
public enum ConnectTypes {
|
||||
SERVER, CLIENT, BOT
|
||||
|
@ -76,7 +77,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
|||
AuthProviderPair pair;
|
||||
if (auth_id.isEmpty()) pair = server.config.getAuthProviderPair();
|
||||
else pair = server.config.getAuthProviderPair(auth_id);
|
||||
AuthContext context = new AuthContext(0, login, password.length(), customText, client, ip, null, authType);
|
||||
AuthContext context = new AuthContext(0, login, password.length(), customText, client, null, ip, authType);
|
||||
AuthProvider provider = pair.provider;
|
||||
server.authHookManager.preHook.hook(context, clientData);
|
||||
provider.preAuth(login, password, customText, ip);
|
||||
|
@ -104,6 +105,10 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
|||
clientData.permissions = aresult.permissions;
|
||||
clientData.auth_id = auth_id;
|
||||
clientData.updateAuth(server);
|
||||
if(result.playerProfile != null)
|
||||
clientData.username = result.playerProfile.username;
|
||||
else
|
||||
clientData.username = login;
|
||||
result.accessToken = aresult.accessToken;
|
||||
result.permissions = clientData.permissions;
|
||||
if (authType == ConnectTypes.BOT && !clientData.permissions.canBot) {
|
|
@ -1,11 +1,11 @@
|
|||
package pro.gravit.launchserver.websocket.json.auth;
|
||||
package pro.gravit.launchserver.socket.response.auth;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.CheckServerRequestEvent;
|
||||
import pro.gravit.launchserver.auth.AuthException;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.websocket.json.profile.ProfileByUUIDResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse;
|
||||
import pro.gravit.utils.HookException;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.json.auth;
|
||||
package pro.gravit.launchserver.socket.response.auth;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -7,7 +7,7 @@
|
|||
import pro.gravit.launcher.events.request.GetAvailabilityAuthRequestEvent;
|
||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
public class GetAvailabilityAuthResponse extends SimpleResponse {
|
||||
@Override
|
|
@ -1,10 +1,10 @@
|
|||
package pro.gravit.launchserver.websocket.json.auth;
|
||||
package pro.gravit.launchserver.socket.response.auth;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.JoinServerRequestEvent;
|
||||
import pro.gravit.launchserver.auth.AuthException;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.utils.HookException;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package pro.gravit.launchserver.websocket.json.auth;
|
||||
package pro.gravit.launchserver.socket.response.auth;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.ErrorRequestEvent;
|
||||
import pro.gravit.launcher.events.request.ProfilesRequestEvent;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
public class ProfilesResponse extends SimpleResponse {
|
||||
@Override
|
|
@ -0,0 +1,48 @@
|
|||
package pro.gravit.launchserver.socket.response.auth;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launchserver.dao.User;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
public class RegisterResponse extends SimpleResponse {
|
||||
public String login;
|
||||
public String password;
|
||||
public byte[] verifyHash;
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception
|
||||
{
|
||||
byte[] normalHash = registerHash(login, server.runtime.registerApiKey);
|
||||
if(!( client.isAuth && client.permissions.canAdmin ) && !Arrays.equals(normalHash, verifyHash))
|
||||
{
|
||||
sendError("Hash invalid");
|
||||
return;
|
||||
}
|
||||
User checkUser = server.config.dao.userService.findUserByUsername(login);
|
||||
if(checkUser != null)
|
||||
{
|
||||
sendError("User already register");
|
||||
return;
|
||||
}
|
||||
User user = new User();
|
||||
user.username = login;
|
||||
user.setPassword(password);
|
||||
user.uuid = UUID.randomUUID();
|
||||
server.config.dao.userService.saveUser(user);
|
||||
}
|
||||
@Override
|
||||
public String getType() {
|
||||
return "register";
|
||||
}
|
||||
public static byte[] registerHash(String login, String secret) throws NoSuchAlgorithmException {
|
||||
String text = login.concat("+").concat(secret);
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
return digest.digest(text.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package pro.gravit.launchserver.websocket.json.auth;
|
||||
package pro.gravit.launchserver.socket.response.auth;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.LauncherNetworkAPI;
|
||||
import pro.gravit.launcher.events.request.RestoreSessionRequestEvent;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.WebSocketFrameHandler;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
public class RestoreSessionResponse extends SimpleResponse {
|
||||
@LauncherNetworkAPI
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.json.auth;
|
||||
package pro.gravit.launchserver.socket.response.auth;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
|||
import pro.gravit.launcher.events.request.SetProfileRequestEvent;
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.utils.HookException;
|
||||
|
||||
public class SetProfileResponse extends SimpleResponse {
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.json.profile;
|
||||
package pro.gravit.launchserver.socket.response.profile;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
|||
import pro.gravit.launcher.events.request.BatchProfileByUsernameRequestEvent;
|
||||
import pro.gravit.launcher.profiles.PlayerProfile;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class BatchProfileByUsername extends SimpleResponse {
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.json.profile;
|
||||
package pro.gravit.launchserver.socket.response.profile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
@ -10,7 +10,7 @@
|
|||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class ProfileByUUIDResponse extends SimpleResponse {
|
|
@ -1,11 +1,11 @@
|
|||
package pro.gravit.launchserver.websocket.json.profile;
|
||||
package pro.gravit.launchserver.socket.response.profile;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.ProfileByUsernameRequestEvent;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class ProfileByUsername extends SimpleResponse {
|
|
@ -1,9 +1,9 @@
|
|||
package pro.gravit.launchserver.websocket.json.secure;
|
||||
package pro.gravit.launchserver.socket.response.secure;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.GetSecureTokenRequestEvent;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
public class GetSecureTokenResponse extends SimpleResponse {
|
||||
@Override
|
|
@ -1,9 +1,9 @@
|
|||
package pro.gravit.launchserver.websocket.json.secure;
|
||||
package pro.gravit.launchserver.socket.response.secure;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.VerifySecureTokenRequestEvent;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
public class VerifySecureTokenResponse extends SimpleResponse {
|
||||
public String secureToken;
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.json.update;
|
||||
package pro.gravit.launchserver.socket.response.update;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
@ -6,7 +6,7 @@
|
|||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.LauncherRequestEvent;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.utils.Version;
|
||||
|
||||
public class LauncherResponse extends SimpleResponse {
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.json.update;
|
||||
package pro.gravit.launchserver.socket.response.update;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
@ -8,7 +8,7 @@
|
|||
import pro.gravit.launcher.hasher.HashedDir;
|
||||
import pro.gravit.launcher.serialize.signed.SignedObjectHolder;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
public class UpdateListResponse extends SimpleResponse {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launchserver.websocket.json.update;
|
||||
package pro.gravit.launchserver.socket.response.update;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.ErrorRequestEvent;
|
||||
|
@ -8,7 +8,8 @@
|
|||
import pro.gravit.launcher.serialize.signed.SignedObjectHolder;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.websocket.json.SimpleResponse;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
|
||||
public class UpdateResponse extends SimpleResponse {
|
||||
public String dirName;
|
||||
|
@ -38,7 +39,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
|||
service.sendObject(ctx, new ErrorRequestEvent(String.format("Directory %s not found", dirName)));
|
||||
return;
|
||||
}
|
||||
String url = server.config.netty.downloadURL.replace("%dirname%", dirName);
|
||||
String url = server.config.netty.downloadURL.replace("%dirname%", IOHelper.urlEncode(dirName));
|
||||
boolean zip = false;
|
||||
if (server.config.netty.bindings.get(dirName) != null) {
|
||||
LaunchServer.NettyUpdatesBind bind = server.config.netty.bindings.get(dirName);
|
|
@ -1,44 +0,0 @@
|
|||
package pro.gravit.launchserver.websocket.json;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
|
||||
import pro.gravit.launchserver.websocket.WebSocketService;
|
||||
|
||||
public class JsonResponseAdapter implements JsonSerializer<JsonResponseInterface>, JsonDeserializer<JsonResponseInterface> {
|
||||
private final WebSocketService service;
|
||||
private static final String PROP_NAME = "type";
|
||||
|
||||
public JsonResponseAdapter(WebSocketService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public JsonResponseInterface deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
|
||||
Class<JsonResponseInterface> cls = service.getResponseClass(typename);
|
||||
|
||||
|
||||
return (JsonResponseInterface) context.deserialize(json, cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(JsonResponseInterface src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
// note : won't work, you must delegate this
|
||||
JsonObject jo = context.serialize(src).getAsJsonObject();
|
||||
|
||||
String classPath = src.getType();
|
||||
jo.add(PROP_NAME, new JsonPrimitive(classPath));
|
||||
|
||||
return jo;
|
||||
}
|
||||
}
|
|
@ -3,12 +3,12 @@
|
|||
import pro.gravit.launcher.LauncherNetworkAPI;
|
||||
import pro.gravit.launcher.events.request.LogEvent;
|
||||
import pro.gravit.launcher.request.Request;
|
||||
import pro.gravit.launcher.request.websockets.RequestInterface;
|
||||
import pro.gravit.launcher.request.websockets.WebSocketRequest;
|
||||
import pro.gravit.utils.command.Command;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class LogListenerCommand extends Command {
|
||||
public class LogListenerRequest implements RequestInterface {
|
||||
public class LogListenerRequest implements WebSocketRequest {
|
||||
@LauncherNetworkAPI
|
||||
public LogHelper.OutputTypes outputType;
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
dependencies {
|
||||
pack project(':LauncherAuthlib')
|
||||
bundle 'com.github.oshi:oshi-core:3.13.0'
|
||||
bundle 'com.jfoenix:jfoenix:8.0.8'
|
||||
bundle 'de.jensd:fontawesomefx:8.9'
|
||||
bundle 'org.apache.httpcomponents:httpclient:4.5.7'
|
||||
pack 'io.netty:netty-codec-http:4.1.36.Final'
|
||||
|
|
|
@ -16,6 +16,12 @@ var config = {
|
|||
autoEnterDefault: false, // Should autoEnter be enabled by default?
|
||||
fullScreenDefault: false, // Should fullScreen be enabled by default?
|
||||
ramDefault: 1024, // Default RAM amount (0 for auto)
|
||||
|
||||
jvm: {
|
||||
enable: false,
|
||||
jvmMustdie32Dir: "jre-8u202-win32",
|
||||
jvmMustdie64Dir: "jre-8u202-win64",
|
||||
}
|
||||
};
|
||||
|
||||
DirBridge.dir = DirBridge.getLauncherDir(config.dir);
|
||||
|
|
|
@ -136,6 +136,9 @@ function initConsoleScene() {
|
|||
var appendFunction = function(line) javafx.application.Platform.runLater(function() output.appendText(line));
|
||||
consoleMenu.lookup("#send").setOnAction(function(){
|
||||
execCommand(text.getText());
|
||||
if (text.getText() == "clear") {
|
||||
output.setText("");
|
||||
}
|
||||
text.setText("");
|
||||
});
|
||||
FunctionalBridge.addPlainOutput(function(string) {
|
||||
|
@ -255,7 +258,7 @@ function verifyLauncher(e) {
|
|||
var iter = 0;
|
||||
authTypes = {};
|
||||
result.list.forEach(function(auth_type, i, arr) {
|
||||
var serverAuth = new com.jfoenix.controls.JFXComboBox();
|
||||
var serverAuth = new javafx.scene.control.ComboBox();
|
||||
serverAuth.getStyleClass().add("authOptions");
|
||||
authOptions.getItems().add(auth_type.displayName);
|
||||
authTypes[auth_type.displayName] = auth_type.name;
|
||||
|
@ -302,7 +305,31 @@ function doAuth(login, rsaPassword, auth_type) {
|
|||
function doUpdate(profile, pp, accessToken) {
|
||||
var digest = profile.isUpdateFastCheck();
|
||||
overlay.swap(0, update.overlay, function(event) {
|
||||
|
||||
if (config.jvm.enable) {
|
||||
makeSetProfileRequest(profile, function() {
|
||||
ClientLauncher.setProfile(profile);
|
||||
var jvmDir = settings.updatesDir.resolve(jvmDirName);
|
||||
update.resetOverlay("Обновление файлов JVM");
|
||||
makeUpdateRequest(jvmDirName, jvmDir, null, digest, function(jvmHDir) {
|
||||
ClientLauncher.setJavaBinPath(jvmDir);
|
||||
update.resetOverlay("Обновление файлов ресурсов");
|
||||
var assetDirName = profile.getAssetDir();
|
||||
var assetDir = settings.updatesDir.resolve(assetDirName);
|
||||
var assetMatcher = profile.getAssetUpdateMatcher();
|
||||
makeUpdateRequest(assetDirName, assetDir, assetMatcher, digest, function(assetHDir) {
|
||||
settings.putHDir(assetDirName, assetDir, assetHDir.hdir);
|
||||
update.resetOverlay("Обновление файлов клиента");
|
||||
var clientDirName = profile.getDir();
|
||||
var clientDir = settings.updatesDir.resolve(clientDirName);
|
||||
var clientMatcher = profile.getClientUpdateMatcher();
|
||||
makeUpdateRequest(clientDirName, clientDir, clientMatcher, digest, function(clientHDir) {
|
||||
settings.putHDir(clientDirName, clientDir, clientHDir.hdir);
|
||||
doLaunchClient(assetDir, assetHDir.hdir, clientDir, clientHDir.hdir, profile, pp, accessToken);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
update.resetOverlay("Обновление файлов ресурсов");
|
||||
var assetDirName = profile.getAssetDir();
|
||||
var assetDir = settings.updatesDir.resolve(assetDirName);
|
||||
|
@ -322,6 +349,7 @@ function doUpdate(profile, pp, accessToken) {
|
|||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue