diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 00000000..001df928 --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,82 @@ +name: push +on: + push: + create: + tags: + - v* +jobs: + launcher: + name: Launcher + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Cache Gradle + uses: actions/cache@v1 + with: + path: ~/.gradle/caches + key: gravit-${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}-launcher + + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew build + + - name: Create artifacts + run: | + mkdir -p artifacts/modules + cd LaunchServer/build/libs/ + zip -r -9 ../../../artifacts/libraries.zip * -x "LaunchServer.jar" -x "LaunchServer-clean.jar" + cp LaunchServer.jar ../../../artifacts/LaunchServer.jar + cd ../../../ServerWrapper/build/libs + cp ServerWrapper.jar ../../../artifacts/ServerWrapper.jar + cd ../../../LauncherAuthlib/build/libs + cp LauncherAuthlib.jar ../../../artifacts/LauncherAuthlib.jar + cd ../../../ + cp modules/*_module/build/libs/*.jar artifacts/modules + cp modules/*_swmodule/build/libs/*.jar artifacts/modules + cp modules/*_lmodule/build/libs/*.jar artifacts/modules + + - name: Upload artifacts + uses: actions/upload-artifact@v1 + with: + name: Launcher + path: artifacts + + - name: Create release + id: create_release + uses: actions/create-release@v1 + if: github.event_name == 'create' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: GravitLauncher ${{ github.ref }} + draft: false + prerelease: false + + - name: Pack release + if: github.event_name == 'create' + run: | + cd artifacts/ + zip -r -9 ../Release.zip * + + - name: Upload release + if: github.event_name == 'create' + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./Release.zip + asset_name: Release.zip + asset_content_type: application/zip diff --git a/.gitignore b/.gitignore index 1369af48..46a38783 100644 --- a/.gitignore +++ b/.gitignore @@ -109,3 +109,4 @@ cmd.bat cmd.sh ## PVS Studio .PVS-Studio/ +project/target diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 794e62e6..00000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,90 +0,0 @@ -image: gradle:jdk11 - -stages: - - build - - test - - deploy -variables: - GRADLE_OPTS: "-Dorg.gradle.daemon=false" - -before_script: - - apt-get -y update - - 'which zip || ( apt-get -y install zip )' - - 'which git || ( apt-get -y install git )' - - export GRADLE_USER_HOME=`pwd`/.gradle - - chmod +x gradlew - - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' - - eval $(ssh-agent -s) - - echo "$SSH_PRIVATE_KEY" | base64 -d | ssh-add - > /dev/null - - mkdir -p ~/.ssh - - chmod 700 ~/.ssh - - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config - - git submodule sync - - mv modules modules_cache || true - - git submodule update --init --recursive --force - - cp -a modules_cache/* modules/ || true -build: - stage: build - script: - - gradle assemble - after_script: - - mkdir -p artifacts/modules - - cd LaunchServer/build/libs/ - - zip -r -9 ../../../artifacts/libraries.zip * -x "LaunchServer.jar" -x "LaunchServer-clean.jar" - - cp LaunchServer.jar ../../../artifacts/LaunchServer.jar - - cd ../../../ServerWrapper/build/libs - - cp ServerWrapper.jar ../../../artifacts/ServerWrapper.jar - - cd ../../../LauncherAuthlib/build/libs - - cp LauncherAuthlib.jar ../../../artifacts/LauncherAuthlib.jar - - cd ../../../ - - cp modules/*_module/build/libs/*.jar artifacts/modules - - cp modules/*_swmodule/build/libs/*.jar artifacts/modules - - cp modules/*_lmodule/build/libs/*.jar artifacts/modules - cache: - key: "$CI_COMMIT_REF_NAME" - paths: - - .gradle - - LaunchServer/build - - Launcher/build - - LauncherCore/build - - LauncherAPI/build - - LauncherAuthlib/build - - modules/*_*module/build - artifacts: - expire_in: 6 week - paths: - - artifacts - -test: - stage: test - script: - - gradle check - cache: - key: "$CI_COMMIT_REF_NAME" - policy: pull - paths: - - .gradle - - LaunchServer/build - - Launcher/build - - LauncherCore/build - - LauncherAPI/build - - LauncherAuthlib/build - - modules/*_*module/build - -deploy-demo: - stage: deploy - only: [dev] - script: - - gradle build - - eval $(ssh $SSH_USER@$SSH_HOST 'cd $SSH_DIR && cat deploy.sh') - cache: - key: "$CI_COMMIT_REF_NAME" - policy: pull - paths: - - .gradle - - LaunchServer/build - - Launcher/build - - LauncherCore/build - - LauncherAPI/build - - LauncherAuthlib/build - - modules/*_*module/build \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index f70ed106..e491e098 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "modules"] path = modules - url = git@github.com:GravitLauncher/LauncherModules.git + url = https://github.com/GravitLauncher/LauncherModules.git diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5822178d..00000000 --- a/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -language: java -dist: trusty -jdk: - - openjdk11 -# Use https (public access) instead of git for git-submodules. This modifies only Travis-CI behavior! -# disable the default submodule logic -git: - submodules: false -# use sed to replace the SSH URL with the public URL, then init and update submodules -before_install: - - sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules - - git submodule update --init --recursive -# gradle -before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ -cache: - directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ -script: - - ./gradlew build diff --git a/LaunchServer/build.gradle b/LaunchServer/build.gradle index ea5dcb76..bab04afc 100644 --- a/LaunchServer/build.gradle +++ b/LaunchServer/build.gradle @@ -100,7 +100,7 @@ pack project(':LauncherAPI') exclude group: 'org.slf4j' } launch4j('net.sf.launch4j:launch4j:' + rootProject['verLaunch4j'] + ':workdir-win32') { transitive = false } - launch4j('net.sf.launch4j:launch4j:' + rootProject['verLaunch4j'] + 'workdir-linux') { transitive = false } + launch4j('net.sf.launch4j:launch4j:' + rootProject['verLaunch4j'] + ':workdir-linux64') { transitive = false } compileOnlyA group: 'com.google.guava', name: 'guava', version: rootProject['verGuavaC'] // Do not update (laggy deps). diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index c0a511f1..a6cfed89 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -98,7 +98,6 @@ public void reload(ReloadType type) throws Exception { LogHelper.debug("Init components"); config.components.forEach((k, v) -> { LogHelper.subDebug("Init component %s", k); - registerObject("component.".concat(k), v); v.init(this); }); LogHelper.debug("Init components successful"); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/PostgreSQLSourceConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/PostgreSQLSourceConfig.java index b6180efb..9de90848 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/PostgreSQLSourceConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/PostgreSQLSourceConfig.java @@ -43,8 +43,8 @@ public synchronized Connection getConnection() throws SQLException { PGSimpleDataSource postgresqlSource = new PGSimpleDataSource(); // Set credentials - postgresqlSource.setServerName(address); - postgresqlSource.setPortNumber(port); + postgresqlSource.setServerNames(new String[] {address}); //TODO support multinode PostgreSQL DB + postgresqlSource.setPortNumbers(new int[] {port}); postgresqlSource.setUser(username); postgresqlSource.setPassword(password); postgresqlSource.setDatabaseName(database); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/JsonAuthProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/JsonAuthProvider.java index 2bdc5dd0..7716ca42 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/JsonAuthProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/JsonAuthProvider.java @@ -21,6 +21,7 @@ public static class authResult { String username; String error; long permissions; + long flags; } public static class authRequest { @@ -54,7 +55,7 @@ public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface p authResult result = gson.fromJson(content, authResult.class); if (result.username != null) - return new AuthProviderResult(result.username, SecurityHelper.randomStringToken(), new ClientPermissions(result.permissions)); + return new AuthProviderResult(result.username, SecurityHelper.randomStringToken(), new ClientPermissions(result.permissions, result.flags)); else if (result.error != null) return authError(result.error); else diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/MySQLAuthProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/MySQLAuthProvider.java index aae966bf..1fe7558d 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/MySQLAuthProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/MySQLAuthProvider.java @@ -20,6 +20,7 @@ public final class MySQLAuthProvider extends AuthProvider { private String query; private String message; private String[] queryParams; + private boolean flagsEnabled; @Override public void init(LaunchServer srv) { @@ -41,7 +42,8 @@ public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface p // Execute SQL query s.setQueryTimeout(MySQLSourceConfig.TIMEOUT); try (ResultSet set = s.executeQuery()) { - return set.next() ? new AuthProviderResult(set.getString(1), SecurityHelper.randomStringToken(), new ClientPermissions(set.getLong(2))) : authError(message); + return set.next() ? new AuthProviderResult(set.getString(1), SecurityHelper.randomStringToken(), new ClientPermissions( + set.getLong(2), flagsEnabled ? set.getLong(3) : 0)) : authError(message); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/PostgreSQLAuthProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/PostgreSQLAuthProvider.java index 3599f249..32581d59 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/PostgreSQLAuthProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/PostgreSQLAuthProvider.java @@ -19,6 +19,7 @@ public final class PostgreSQLAuthProvider extends AuthProvider { private String query; private String message; private String[] queryParams; + private boolean flagsEnabled; @Override public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws SQLException, AuthException { @@ -32,7 +33,8 @@ public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface p // Execute SQL query s.setQueryTimeout(PostgreSQLSourceConfig.TIMEOUT); try (ResultSet set = s.executeQuery()) { - return set.next() ? new AuthProviderResult(set.getString(1), SecurityHelper.randomStringToken(), new ClientPermissions(set.getLong(2))) : authError(message); + return set.next() ? new AuthProviderResult(set.getString(1), SecurityHelper.randomStringToken(), new ClientPermissions( + set.getLong(2), flagsEnabled ? set.getLong(3) : 0)) : authError(message); } } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RejectAuthProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RejectAuthProvider.java index aaf60d3b..ae04a567 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RejectAuthProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RejectAuthProvider.java @@ -22,7 +22,7 @@ public RejectAuthProvider(String message) { } private String message; - private ArrayList whitelist; + private ArrayList whitelist = new ArrayList<>(); @Override public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws AuthException { @@ -46,11 +46,20 @@ public Map getCommands() { Map commands = new HashMap<>(); commands.put("message", new SubCommand() { @Override - public void invoke(String... args) { + public void invoke(String... args) throws Exception { + verifyArgs(args, 1); message = args[0]; LogHelper.info("New reject message: %s", message); } }); + commands.put("whirelist.add", new SubCommand() { + @Override + public void invoke(String... args) throws Exception { + verifyArgs(args, 1); + whitelist.add(args[0]); + LogHelper.info("%s added to whitelist", args[0]); + } + }); return commands; } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RequestAuthProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RequestAuthProvider.java index e0f489bb..28f3a22e 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RequestAuthProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RequestAuthProvider.java @@ -19,6 +19,7 @@ public final class RequestAuthProvider extends AuthProvider { private String url; private transient Pattern pattern; private String response; + private boolean flagsEnabled; @Override public void init(LaunchServer srv) { @@ -36,7 +37,8 @@ public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface p // Match username Matcher matcher = pattern.matcher(currentResponse); return matcher.matches() && matcher.groupCount() >= 1 ? - new AuthProviderResult(matcher.group("username"), SecurityHelper.randomStringToken(), new ClientPermissions(Long.parseLong(matcher.group("permission")))) : + new AuthProviderResult(matcher.group("username"), SecurityHelper.randomStringToken(), new ClientPermissions( + Long.parseLong(matcher.group("permissions")), flagsEnabled ? Long.parseLong(matcher.group("flags")) : 0)) : authError(currentResponse); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java index 8a6c032e..7eb27214 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java @@ -52,6 +52,7 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand updates.registerCommand("syncBinaries", new SyncBinariesCommand(server)); updates.registerCommand("syncUpdates", new SyncUpdatesCommand(server)); updates.registerCommand("syncProfiles", new SyncProfilesCommand(server)); + updates.registerCommand("saveProfiles", new SaveProfilesCommand(server)); Category updatesCategory = new Category(updates, "updates", "Update and Sync Management"); handler.registerCategory(updatesCategory); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/SaveProfilesCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/SaveProfilesCommand.java new file mode 100644 index 00000000..d22e7d3a --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/SaveProfilesCommand.java @@ -0,0 +1,64 @@ +package pro.gravit.launchserver.command.hash; + +import pro.gravit.launcher.Launcher; +import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launchserver.LaunchServer; +import pro.gravit.launchserver.command.Command; +import pro.gravit.utils.helper.IOHelper; +import pro.gravit.utils.helper.LogHelper; + +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.UUID; + +public class SaveProfilesCommand extends Command { + public SaveProfilesCommand(LaunchServer server) { + super(server); + } + + @Override + public String getArgsDescription() { + return "[profile names...]"; + } + + @Override + public String getUsageDescription() { + return "load and save profile"; + } + + @Override + public void invoke(String... args) throws Exception { + verifyArgs(args, 1); + if(args.length > 0) + { + for(String profileName : args) + { + Path profilePath = server.profilesDir.resolve(profileName.concat(".json")); + if(!Files.exists(profilePath)) + { + LogHelper.error("Profile %s not found", profilePath.toString()); + return; + } + ClientProfile profile; + try(Reader reader = IOHelper.newReader(profilePath)) + { + profile = Launcher.gsonManager.configGson.fromJson(reader, ClientProfile.class); + } + saveProfile(profile, profilePath); + LogHelper.info("Profile %s save successful", profilePath.toString()); + } + server.syncProfilesDir(); + } + } + public static void saveProfile(ClientProfile profile, Path path) throws IOException + { + if(profile.getUUID() == null) profile.setUUID(UUID.randomUUID()); + try(Writer w = IOHelper.newWriter(path)) + { + Launcher.gsonManager.configGson.toJson(profile, w); + } + } +} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/UnindexAssetCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/UnindexAssetCommand.java index ffe36636..5c4e811a 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/UnindexAssetCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/UnindexAssetCommand.java @@ -16,8 +16,6 @@ import java.util.Map; public final class UnindexAssetCommand extends Command { - private static final JsonParser parser = new JsonParser(); - public UnindexAssetCommand(LaunchServer server) { super(server); } @@ -51,7 +49,7 @@ public void invoke(String... args) throws Exception { JsonObject objects; LogHelper.subInfo("Reading asset index file: '%s'", indexFileName); try (BufferedReader reader = IOHelper.newReader(IndexAssetCommand.resolveIndexFile(inputAssetDir, indexFileName))) { - objects = parser.parse(reader).getAsJsonObject().get("objects").getAsJsonObject(); + objects = JsonParser.parseReader(reader).getAsJsonObject().get("objects").getAsJsonObject(); } // Restore objects diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java index 6d52c664..9772a46a 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java @@ -36,7 +36,7 @@ public void invoke(String... args) { LogHelper.info("Client name %s | ip %s | connectUUID %s", client.username == null ? "null" : client.username, ip, frameHandler.getConnectUUID()); LogHelper.subInfo("Data: checkSign %s | auth_id %s", client.checkSign ? "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()); + LogHelper.subInfo("Permissions: %s (permissions %d | flags %d)", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.permissions, client.permissions == null ? 0 : client.permissions.flags); } })); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java index c71cf184..0c81b263 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java @@ -5,6 +5,7 @@ import pro.gravit.launcher.Launcher; import pro.gravit.launcher.LauncherConfig; import pro.gravit.launchserver.LaunchServer; +import pro.gravit.launchserver.Reconfigurable; import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.auth.handler.MemoryAuthHandler; import pro.gravit.launchserver.auth.protect.ProtectHandler; @@ -124,8 +125,10 @@ public void init(LaunchServer.ReloadType type) { for (Map.Entry provider : auth.entrySet()) { provider.getValue().init(server, provider.getKey()); } - if (dao != null) + if (dao != null) { + server.registerObject("dao", dao); dao.init(server); + } if (protectHandler != null) { protectHandler.checkLaunchServerLicense(); } @@ -149,6 +152,7 @@ public void close(LaunchServer.ReloadType type) { server.unregisterObject("auth.".concat(pair.name).concat(".provider"), pair.provider); server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler); server.unregisterObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider); + pair.close(); } } if (type.equals(LaunchServer.ReloadType.FULL)) { @@ -166,10 +170,16 @@ public void close(LaunchServer.ReloadType type) { } catch (Exception e) { LogHelper.error(e); } - try { - for (AuthProviderPair p : auth.values()) p.close(); - } catch (IOException e) { - LogHelper.error(e); + if(dao != null) { + server.unregisterObject("dao", dao); + if(dao instanceof AutoCloseable) + { + try { + ((AutoCloseable) dao).close(); + } catch (Exception e) { + LogHelper.error(e); + } + } } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/impl/UserHibernateImpl.java b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/impl/UserHibernateImpl.java index 6094d391..3b3d4ef7 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/impl/UserHibernateImpl.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/impl/UserHibernateImpl.java @@ -12,7 +12,7 @@ import java.util.Arrays; import java.util.UUID; -@Entity +@Entity(name = "User") @Table(name = "users") public class UserHibernateImpl implements User { @Id @@ -29,6 +29,7 @@ public class UserHibernateImpl implements User { public String serverID; private String password_salt; public long permissions; + public long flags; public void setPassword(String password) { password_salt = SecurityHelper.randomStringAESKey(); @@ -55,11 +56,12 @@ public boolean verifyPassword(String password) { } public ClientPermissions getPermissions() { - return new ClientPermissions(permissions); + return new ClientPermissions(permissions, flags); } public void setPermissions(ClientPermissions permissions) { - this.permissions = permissions.toLong(); + this.permissions = permissions.permissions; + this.flags = permissions.flags; } public String getAccessToken() { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/provider/HibernateDaoProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/provider/HibernateDaoProvider.java index 88be2ad5..3d4eb72b 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/provider/HibernateDaoProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/provider/HibernateDaoProvider.java @@ -2,14 +2,22 @@ import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; +import pro.gravit.launcher.ClientPermissions; import pro.gravit.launchserver.LaunchServer; +import pro.gravit.launchserver.Reconfigurable; +import pro.gravit.launchserver.dao.User; import pro.gravit.launchserver.dao.impl.UserHibernateImpl; import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl; +import pro.gravit.utils.command.Command; +import pro.gravit.utils.command.SubCommand; import pro.gravit.utils.helper.CommonHelper; +import pro.gravit.utils.helper.LogHelper; import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; -public class HibernateDaoProvider extends DaoProvider { +public class HibernateDaoProvider extends DaoProvider implements Reconfigurable, AutoCloseable { public String driver; public String url; public String username; @@ -42,4 +50,72 @@ public void init(LaunchServer server) { else init.run(); } + + @Override + public Map getCommands() { + Map commands = new HashMap<>(); + commands.put("getallusers", new SubCommand() { + @Override + public void invoke(String... args) throws Exception { + int count = 0; + for (User user : userDAO.findAll()) { + LogHelper.subInfo("[%s] UUID: %s", user.getUsername(), user.getUuid().toString()); + count++; + } + LogHelper.info("Print %d users", count); + } + }); + commands.put("getuser", new SubCommand() { + @Override + public void invoke(String... args) throws Exception { + verifyArgs(args, 1); + User user = userDAO.findByUsername(args[0]); + if (user == null) { + LogHelper.error("User %s not found", args[0]); + return; + } + LogHelper.info("[%s] UUID: %s | permissions %s", user.getUsername(), user.getUuid().toString(), user.getPermissions() == null ? "null" : user.getPermissions().toString()); + } + }); + commands.put("givepermission", new SubCommand() { + @Override + public void invoke(String... args) throws Exception { + verifyArgs(args, 3); + User user = userDAO.findByUsername(args[0]); + if (user == null) { + LogHelper.error("User %s not found", args[0]); + return; + } + ClientPermissions permissions = user.getPermissions(); + long perm = Long.parseLong(args[1]); + boolean value = Boolean.parseBoolean(args[2]); + permissions.setPermission(perm, value); + user.setPermissions(permissions); + userDAO.update(user); + } + }); + commands.put("giveflag", new SubCommand() { + @Override + public void invoke(String... args) throws Exception { + verifyArgs(args, 3); + User user = userDAO.findByUsername(args[0]); + if (user == null) { + LogHelper.error("User %s not found", args[0]); + return; + } + ClientPermissions permissions = user.getPermissions(); + long perm = Long.parseLong(args[1]); + boolean value = Boolean.parseBoolean(args[2]); + permissions.setFlag(perm, value); + user.setPermissions(permissions); + userDAO.update(user); + } + }); + return commands; + } + + @Override + public void close() throws Exception { + sessionFactory.close(); + } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/AddLogListenerResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/AddLogListenerResponse.java index 5a54843c..00e8482f 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/AddLogListenerResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/AddLogListenerResponse.java @@ -1,6 +1,7 @@ package pro.gravit.launchserver.socket.response.admin; import io.netty.channel.ChannelHandlerContext; +import pro.gravit.launcher.ClientPermissions; import pro.gravit.launcher.events.request.LogEvent; import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.response.SimpleResponse; @@ -20,7 +21,7 @@ public void execute(ChannelHandlerContext ctx, Client client) { sendError("Access denied"); return; } - if (!client.permissions.canAdmin) { + if (!client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) { sendError("Access denied"); return; } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/ExecCommandResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/ExecCommandResponse.java index 9c7a3d44..b8d34d38 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/ExecCommandResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/ExecCommandResponse.java @@ -1,6 +1,7 @@ package pro.gravit.launchserver.socket.response.admin; import io.netty.channel.ChannelHandlerContext; +import pro.gravit.launcher.ClientPermissions; import pro.gravit.launcher.events.request.ExecCommandRequestEvent; import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.response.SimpleResponse; @@ -15,7 +16,7 @@ public String getType() { @Override public void execute(ChannelHandlerContext ctx, Client client) { - if (!client.isAuth || !client.permissions.canAdmin) { + if (!client.isAuth || !client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) { sendError("Access denied"); return; } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java index 91d98be7..e528915e 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java @@ -1,6 +1,7 @@ package pro.gravit.launchserver.socket.response.auth; import io.netty.channel.ChannelHandlerContext; +import pro.gravit.launcher.ClientPermissions; import pro.gravit.launcher.events.RequestEvent; import pro.gravit.launcher.events.request.ExitRequestEvent; import pro.gravit.launchserver.socket.Client; @@ -17,7 +18,7 @@ public String getType() { @Override public void execute(ChannelHandlerContext ctx, Client client) throws Exception { - if(username != null && ( !client.isAuth || client.permissions == null || !client.permissions.canAdmin )) + if(username != null && ( !client.isAuth || client.permissions == null || !client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN) )) { sendError("Permissions denied"); return; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RegisterResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RegisterResponse.java index e0567e48..91496d21 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RegisterResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RegisterResponse.java @@ -1,6 +1,7 @@ package pro.gravit.launchserver.socket.response.auth; import io.netty.channel.ChannelHandlerContext; +import pro.gravit.launcher.ClientPermissions; import pro.gravit.launchserver.dao.User; import pro.gravit.launchserver.dao.impl.UserHibernateImpl; import pro.gravit.launchserver.socket.Client; @@ -21,7 +22,7 @@ public class RegisterResponse extends SimpleResponse { @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)) { + if (!(client.isAuth && client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) && !Arrays.equals(normalHash, verifyHash)) { sendError("Hash invalid"); return; } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/SetPasswordResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/SetPasswordResponse.java index f1d9838e..0e77d64b 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/SetPasswordResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/SetPasswordResponse.java @@ -1,6 +1,7 @@ package pro.gravit.launchserver.socket.response.auth; import io.netty.channel.ChannelHandlerContext; +import pro.gravit.launcher.ClientPermissions; import pro.gravit.launcher.events.request.SetPasswordRequestEvent; import pro.gravit.launchserver.dao.User; import pro.gravit.launchserver.socket.Client; @@ -26,7 +27,7 @@ public void execute(ChannelHandlerContext ctx, Client client) { sendError("You not authorized"); return; } - if (username != null && !client.permissions.canAdmin) { + if (username != null && !client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) { sendError("You not admin"); return; } diff --git a/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java b/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java index 21bdbc27..c931a392 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java +++ b/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java @@ -1,6 +1,5 @@ package pro.gravit.launcher; -import pro.gravit.launcher.client.ClientLauncher; import pro.gravit.launcher.client.ClientModuleManager; import pro.gravit.launcher.client.DirBridge; import pro.gravit.launcher.utils.DirWatcher; @@ -72,10 +71,13 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep tryAddModule(findPath, "javafx.graphics", builder); tryAddModule(findPath, "javafx.fxml", builder); tryAddModule(findPath, "javafx.controls", builder); + boolean useSwing = tryAddModule(findPath, "javafx.swing", builder); String modulePath = builder.toString(); if (!modulePath.isEmpty()) { args.add("--add-modules"); - args.add("javafx.base,javafx.fxml,javafx.controls,jdk.unsupported"); + String javaModules = "javafx.base,javafx.fxml,javafx.controls,jdk.unsupported"; + if(useSwing) javaModules = javaModules.concat(",javafx.swing"); + args.add(javaModules); args.add("--module-path"); args.add(modulePath); } diff --git a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java index e788bf37..c465f175 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java +++ b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java @@ -4,11 +4,13 @@ import pro.gravit.launcher.client.events.ClientEngineInitPhase; import pro.gravit.launcher.client.events.ClientExitPhase; import pro.gravit.launcher.client.events.ClientPreGuiPhase; +import pro.gravit.launcher.guard.LauncherGuardInterface; import pro.gravit.launcher.guard.LauncherGuardManager; +import pro.gravit.launcher.guard.LauncherNoGuard; +import pro.gravit.launcher.guard.LauncherWrapperGuard; import pro.gravit.launcher.gui.NoRuntimeProvider; import pro.gravit.launcher.gui.RuntimeProvider; import pro.gravit.launcher.managers.ClientGsonManager; -import pro.gravit.launcher.managers.ClientHookManager; import pro.gravit.launcher.managers.ConsoleManager; import pro.gravit.launcher.modules.events.PreConfigPhase; import pro.gravit.launcher.request.Request; @@ -40,6 +42,7 @@ public static X509Certificate[] getCertificates(Class clazz) { public static final AtomicBoolean IS_CLIENT = new AtomicBoolean(false); public static ClientLauncherProcess.ClientParams clientParams; + public static LauncherGuardInterface guard; public static void checkClass(Class clazz) throws SecurityException { LauncherTrustManager trustManager = Launcher.getConfig().trustManager; @@ -146,11 +149,11 @@ private LauncherEngine() { public void start(String... args) throws Throwable { //Launcher.modulesManager = new ClientModuleManager(this); + LauncherEngine.guard = tryGetStdGuard(); ClientPreGuiPhase event = new ClientPreGuiPhase(null); LauncherEngine.modulesManager.invokeEvent(event); runtimeProvider = event.runtimeProvider; if (runtimeProvider == null) runtimeProvider = new NoRuntimeProvider(); - ClientHookManager.initGuiHook.hook(runtimeProvider); runtimeProvider.init(false); //runtimeProvider.preLoad(); if (Request.service == null) { @@ -186,6 +189,18 @@ public void start(String... args) throws Throwable { runtimeProvider.run(args); } + public static LauncherGuardInterface tryGetStdGuard() + { + switch (Launcher.getConfig().guardType) + { + case "no": + return new LauncherNoGuard(); + case "wrapper": + return new LauncherWrapperGuard(); + } + return null; + } + public static LauncherEngine clientInstance() { return new LauncherEngine(); } diff --git a/Launcher/src/main/java/pro/gravit/launcher/api/AuthService.java b/Launcher/src/main/java/pro/gravit/launcher/api/AuthService.java index b6e08d02..225cee08 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/api/AuthService.java +++ b/Launcher/src/main/java/pro/gravit/launcher/api/AuthService.java @@ -12,10 +12,6 @@ public class AuthService { public static ClientProfile profile; public static boolean isAdmin() { - return permissions.canAdmin; - } - - public static boolean isServer() { - return permissions.canServer; + return permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN); } } diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncher.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncher.java deleted file mode 100644 index 8e9a4593..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncher.java +++ /dev/null @@ -1,685 +0,0 @@ -package pro.gravit.launcher.client; - -import pro.gravit.launcher.*; -import pro.gravit.launcher.api.AuthService; -import pro.gravit.launcher.api.ClientService; -import pro.gravit.launcher.client.events.ClientLaunchPhase; -import pro.gravit.launcher.client.events.ClientLauncherInitPhase; -import pro.gravit.launcher.client.events.ClientLauncherPostInitPhase; -import pro.gravit.launcher.guard.LauncherGuardManager; -import pro.gravit.launcher.hasher.FileNameMatcher; -import pro.gravit.launcher.hasher.HashedDir; -import pro.gravit.launcher.managers.ClientGsonManager; -import pro.gravit.launcher.managers.ClientHookManager; -import pro.gravit.launcher.modules.events.PreConfigPhase; -import pro.gravit.launcher.patches.FMLPatcher; -import pro.gravit.launcher.profiles.ClientProfile; -import pro.gravit.launcher.profiles.PlayerProfile; -import pro.gravit.launcher.request.Request; -import pro.gravit.launcher.request.RequestException; -import pro.gravit.launcher.request.auth.RestoreSessionRequest; -import pro.gravit.launcher.serialize.HInput; -import pro.gravit.launcher.serialize.HOutput; -import pro.gravit.launcher.serialize.stream.StreamObject; -import pro.gravit.launcher.utils.DirWatcher; -import pro.gravit.utils.Version; -import pro.gravit.utils.helper.*; -import pro.gravit.utils.helper.JVMHelper.OS; - -import javax.swing.*; -import java.io.IOException; -import java.lang.ProcessBuilder.Redirect; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.net.*; -import java.nio.file.FileVisitResult; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.attribute.PosixFilePermission; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public final class ClientLauncher { - - - public static int getClientJVMBits() { - return LauncherGuardManager.guard.getClientJVMBits(); - } - - private static final class ClassPathFileVisitor extends SimpleFileVisitor { - private final Stream.Builder result; - - private ClassPathFileVisitor(Stream.Builder result) { - this.result = result; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (IOHelper.hasExtension(file, "jar") || IOHelper.hasExtension(file, "zip")) - result.accept(file); - return super.visitFile(file, attrs); - } - } - - public static final class Params extends StreamObject { - // Client paths - - public final Path assetDir; - - public final Path clientDir; - - // Client params - - public final PlayerProfile pp; - - public final String accessToken; - - public final boolean autoEnter; - - public final boolean fullScreen; - - public final int ram; - - public final int width; - - public final int height; - - public final long session; - - - public Params(byte[] launcherDigest, Path assetDir, Path clientDir, PlayerProfile pp, String accessToken, - boolean autoEnter, boolean fullScreen, int ram, int width, int height) { - // Client paths - this.assetDir = assetDir; - this.clientDir = clientDir; - // Client params - this.pp = pp; - this.accessToken = accessToken; - this.autoEnter = autoEnter; - this.fullScreen = fullScreen; - this.ram = ram; - this.width = width; - this.height = height; - this.session = Request.getSession(); - } - - - public Params(HInput input) throws Exception { - session = input.readLong(); - // Client paths - assetDir = IOHelper.toPath(input.readString(0)); - clientDir = IOHelper.toPath(input.readString(0)); - // Client params - pp = new PlayerProfile(input); - byte[] encryptedAccessToken = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH); - accessToken = new String(SecurityHelper.decrypt(Launcher.getConfig().secretKeyClient.getBytes(), encryptedAccessToken)); - autoEnter = input.readBoolean(); - fullScreen = input.readBoolean(); - ram = input.readVarInt(); - width = input.readVarInt(); - height = input.readVarInt(); - } - - @Override - public void write(HOutput output) throws IOException { - output.writeLong(session); - // Client paths - output.writeString(assetDir.toString(), 0); - output.writeString(clientDir.toString(), 0); - pp.write(output); - try { - output.writeByteArray(SecurityHelper.encrypt(Launcher.getConfig().secretKeyClient.getBytes(), accessToken.getBytes()), SecurityHelper.CRYPTO_MAX_LENGTH); - } catch (Exception e) { - LogHelper.error(e); - } - output.writeBoolean(autoEnter); - output.writeBoolean(fullScreen); - output.writeVarInt(ram); - output.writeVarInt(width); - output.writeVarInt(height); - } - } - - private static final String SOCKET_HOST = "127.0.0.1"; - private static final int SOCKET_PORT = Launcher.getConfig().clientPort; - private static final String MAGICAL_INTEL_OPTION = "-XX:HeapDumpPath=ThisTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump"; - - private static Path JavaBinPath; - @SuppressWarnings("unused") - private static final Set BIN_POSIX_PERMISSIONS = Collections.unmodifiableSet(EnumSet.of( - PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE, // Owner - PosixFilePermission.GROUP_READ, PosixFilePermission.GROUP_EXECUTE, // Group - PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_EXECUTE // Others - )); - // Constants - private static final Path NATIVES_DIR = IOHelper.toPath("natives"); - private static final Path RESOURCEPACKS_DIR = IOHelper.toPath("resourcepacks"); - private static ClientClassLoader classLoader; - - public static class ClientUserProperties { - - String[] skinURL; - - String[] skinDigest; - - String[] cloakURL; - - String[] cloakDigest; - } - - public static Path getJavaBinPath() { - return JavaBinPath; - } - - private static void addClientArgs(Collection args, ClientProfile profile, Params params) { - PlayerProfile pp = params.pp; - - // Add version-dependent args - ClientProfile.Version version = profile.getVersion(); - Collections.addAll(args, "--username", pp.username); - if (version.compareTo(ClientProfile.Version.MC172) >= 0) { - Collections.addAll(args, "--uuid", Launcher.toHash(pp.uuid)); - Collections.addAll(args, "--accessToken", params.accessToken); - - // Add 1.7.10+ args (user properties, asset index) - if (version.compareTo(ClientProfile.Version.MC1710) >= 0) { - // Add user properties - Collections.addAll(args, "--userType", "mojang"); - ClientUserProperties properties = new ClientUserProperties(); - if (pp.skin != null) { - properties.skinURL = new String[]{pp.skin.url}; - properties.skinDigest = new String[]{SecurityHelper.toHex(pp.skin.digest)}; - } - if (pp.cloak != null) { - properties.cloakURL = new String[]{pp.cloak.url}; - properties.cloakDigest = new String[]{SecurityHelper.toHex(pp.cloak.digest)}; - } - Collections.addAll(args, "--userProperties", Launcher.gsonManager.gson.toJson(properties)); - - // Add asset index - Collections.addAll(args, "--assetIndex", profile.getAssetIndex()); - } - } else - Collections.addAll(args, "--session", params.accessToken); - - // Add version and dirs args - Collections.addAll(args, "--version", profile.getVersion().name); - Collections.addAll(args, "--gameDir", params.clientDir.toString()); - Collections.addAll(args, "--assetsDir", params.assetDir.toString()); - Collections.addAll(args, "--resourcePackDir", params.clientDir.resolve(RESOURCEPACKS_DIR).toString()); - if (version.compareTo(ClientProfile.Version.MC194) >= 0) - Collections.addAll(args, "--versionType", "Launcher v" + Version.getVersion().getVersionString()); - - // Add server args - if (params.autoEnter) { - Collections.addAll(args, "--server", profile.getServerAddress()); - Collections.addAll(args, "--port", Integer.toString(profile.getServerPort())); - } - profile.pushOptionalClientArgs(args); - // Add window size args - if (params.fullScreen) - Collections.addAll(args, "--fullscreen", Boolean.toString(true)); - if (params.width > 0 && params.height > 0) { - Collections.addAll(args, "--width", Integer.toString(params.width)); - Collections.addAll(args, "--height", Integer.toString(params.height)); - } - } - - - public static void setJavaBinPath(Path javaBinPath) { - JavaBinPath = javaBinPath; - } - - private static void addClientLegacyArgs(Collection args, ClientProfile profile, Params params) { - args.add(params.pp.username); - args.add(params.accessToken); - - // Add args for tweaker - Collections.addAll(args, "--version", profile.getVersion().name); - Collections.addAll(args, "--gameDir", params.clientDir.toString()); - Collections.addAll(args, "--assetsDir", params.assetDir.toString()); - } - - - public static void checkJVMBitsAndVersion() { - if (JVMHelper.JVM_BITS != JVMHelper.OS_BITS) { - String error = String.format("У Вас установлена Java %d, но Ваша система определена как %d. Установите Java правильной разрядности", JVMHelper.JVM_BITS, JVMHelper.OS_BITS); - LogHelper.error(error); - if (Launcher.getConfig().isWarningMissArchJava) - JOptionPane.showMessageDialog(null, error); - } - String jvmVersion = JVMHelper.RUNTIME_MXBEAN.getVmVersion(); - LogHelper.info(jvmVersion); - if (jvmVersion.startsWith("10.") || jvmVersion.startsWith("9.") || jvmVersion.startsWith("11.")) { - String error = String.format("У Вас установлена Java %s. Для правильной работы необходима Java 8", JVMHelper.RUNTIME_MXBEAN.getVmVersion()); - LogHelper.error(error); - if (Launcher.getConfig().isWarningMissArchJava) - JOptionPane.showMessageDialog(null, error); - } - } - - - public static boolean isLaunched() { - return Launcher.LAUNCHED.get(); - } - - private static void launch(ClientProfile profile, Params params) throws Throwable { - // Add client args - Collection args = new LinkedList<>(); - if (profile.getVersion().compareTo(ClientProfile.Version.MC164) >= 0) - addClientArgs(args, profile, params); - else { - addClientLegacyArgs(args, profile, params); - System.setProperty("minecraft.applet.TargetDirectory", params.clientDir.toString()); - } - Collections.addAll(args, profile.getClientArgs()); - List copy = new ArrayList<>(args); - for (int i = 0, l = copy.size(); i < l; i++) { - String s = copy.get(i); - if (i + 1 < l && ("--accessToken".equals(s) || "--session".equals(s))) { - copy.set(i + 1, "censored"); - } - } - LogHelper.debug("Args: " + copy); - // Resolve main class and method - Class mainClass = classLoader.loadClass(profile.getMainClass()); - for(URL u : classLoader.getURLs()) - { - LogHelper.info("ClassLoader URL: %s", u.toString()); - } - FMLPatcher.apply(); - MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)).asFixedArity(); - Launcher.LAUNCHED.set(true); - JVMHelper.fullGC(); - // Invoke main method - try { - mainMethod.invokeWithArguments((Object) args.toArray(new String[0])); - LogHelper.debug("Main exit successful"); - } catch (Throwable e) { - LogHelper.error(e); - throw e; - } finally { - LauncherEngine.exitLauncher(0); - } - - } - - private static Process process = null; - private static boolean clientStarted = false; - private static Thread writeParamsThread; - - public static void setWriteParamsThread(Thread writeParamsThread) { - ClientLauncher.writeParamsThread = writeParamsThread; - ClientLauncher.writeParamsThread.start(); - } - - public static Process getProcess() { - return process; - } - - public static void setClientStarted() { - clientStarted = true; - } - - public static PlayerProfile playerProfile; - - - public static Process launch( - HashedDir assetHDir, HashedDir clientHDir, - ClientProfile profile, Params params, boolean pipeOutput) throws Throwable { - LogHelper.debug("Writing ClientLauncher params"); - ClientLauncherContext context = new ClientLauncherContext(); - clientStarted = false; - container.write(new ParamContainer(params, profile, assetHDir, clientHDir)); - checkJVMBitsAndVersion(); - LogHelper.debug("Resolving JVM binary"); - Path javaBin = LauncherGuardManager.getGuardJavaBinPath(); - context.javaBin = javaBin; - context.clientProfile = profile; - context.playerProfile = params.pp; - context.args.add(javaBin.toString()); - context.args.add(MAGICAL_INTEL_OPTION); - if (params.ram > 0) { - context.args.add("-Xms" + params.ram + 'M'); - context.args.add("-Xmx" + params.ram + 'M'); - } - context.args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled()))); - context.args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled()))); - context.args.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, Boolean.toString(LogHelper.isDevEnabled()))); - context.args.add(JVMHelper.jvmProperty(LogHelper.NO_JANSI_PROPERTY, "true")); // Отключаем JAnsi для нормального вывода в DEBUG окно - JVMHelper.addSystemPropertyToArgs(context.args, DirBridge.CUSTOMDIR_PROPERTY); - JVMHelper.addSystemPropertyToArgs(context.args, DirBridge.USE_CUSTOMDIR_PROPERTY); - JVMHelper.addSystemPropertyToArgs(context.args, DirBridge.USE_OPTDIR_PROPERTY); - JVMHelper.addSystemPropertyToArgs(context.args, DirWatcher.IGN_OVERFLOW); - if (JVMHelper.OS_TYPE == OS.MUSTDIE) { - if (JVMHelper.OS_VERSION.startsWith("10.")) { - LogHelper.debug("MustDie 10 fix is applied"); - context.args.add(JVMHelper.jvmProperty("os.name", "Windows 10")); - context.args.add(JVMHelper.jvmProperty("os.version", "10.0")); - } - } - // Add classpath and main class - context.pathLauncher = IOHelper.getCodeSource(ClientLauncher.class).toString(); - context.args.add(ClientLauncherWrapper.MAGIC_ARG); - Collections.addAll(context.args, profile.getJvmArgs()); - profile.pushOptionalJvmArgs(context.args); - context.args.add("-Djava.library.path=".concat(params.clientDir.resolve(NATIVES_DIR).toString())); // Add Native Path - //context.args.add("-javaagent:".concat(pathLauncher)); - ClientHookManager.clientLaunchHook.hook(context); - LauncherGuardManager.guard.addCustomParams(context); - context.args.add(ClientLauncher.class.getName()); - ClientHookManager.clientLaunchFinallyHook.hook(context); - - // Print commandline debug message - LogHelper.debug("Commandline: " + context.args); - - // Build client process - LogHelper.debug("Launching client instance"); - ProcessBuilder builder = new ProcessBuilder(context.args); - context.builder = builder; - LauncherGuardManager.guard.addCustomEnv(context); - //else - //builder.environment().put("CLASSPATH", classPathString.toString()); - EnvHelper.addEnv(builder); - builder.directory(params.clientDir.toFile()); - builder.inheritIO(); - if (pipeOutput) { - builder.redirectErrorStream(true); - builder.redirectOutput(Redirect.PIPE); - } - List command = builder.command(); - // Let's rock! - ClientHookManager.preStartHook.hook(context, builder); - process = builder.start(); - if (builder.command() != command) { - LogHelper.error("Something strange cheating..."); - System.exit(100); - clientStarted = false; - return null; - } - if (ClientHookManager.postStartHook.hook(context, builder)) return process; - if (!pipeOutput) { - for (int i = 0; i < 50; ++i) { - if (!process.isAlive()) { - int exitCode = process.exitValue(); - LogHelper.error("Process exit code %d", exitCode); - if (writeParamsThread != null && writeParamsThread.isAlive()) writeParamsThread.interrupt(); - break; - } - if (clientStarted) { - break; - } - Thread.sleep(200); - } - if (!clientStarted) { - LogHelper.error("Client did not start properly. Enable debug mode for more information"); - } - } - clientStarted = false; - return process; - } - - public static class ClientLaunchContext { - public final Params params; - public final ClientProfile profile; - public final HashedDir assetHDir, clientHDir; - public DirWatcher assetWatcher, clientWatcher; - - - public ClientLaunchContext(Params params, ClientProfile profile, HashedDir assetHDir, HashedDir clientHDir) { - this.params = params; - this.profile = profile; - this.assetHDir = assetHDir; - this.clientHDir = clientHDir; - } - } - - - public static void main(String... args) throws Throwable { - LauncherEngine.IS_CLIENT.set(true); - LauncherEngine engine = LauncherEngine.clientInstance(); - LauncherEngine.checkClass(LauncherEngine.class); - LauncherEngine.checkClass(LauncherAgent.class); - LauncherEngine.checkClass(ClientLauncher.class); - LauncherEngine.modulesManager = new ClientModuleManager(); - LauncherConfig.initModules(LauncherEngine.modulesManager); //INIT - LauncherEngine.modulesManager.initModules(null); - initGson(LauncherEngine.modulesManager); - LauncherEngine.verifyNoAgent(); - LauncherEngine.modulesManager.invokeEvent(new PreConfigPhase()); - JVMHelper.verifySystemProperties(ClientLauncher.class, true); - EnvHelper.checkDangerousParams(); - JVMHelper.checkStackTrace(ClientLauncher.class); - LogHelper.printVersion("Client Launcher"); - engine.readKeys(); - LauncherGuardManager.initGuard(true); - LogHelper.debug("Reading ClientLauncher params"); - ParamContainer p = container.read(); - Params params = p.params; - ClientProfile profile = p.profile; - HashedDir assetHDir = p.assetHDir, clientHDir = p.clientHDir; - ClientLaunchContext context = new ClientLaunchContext(params, profile, assetHDir, clientHDir); - Launcher.profile = profile; - AuthService.profile = profile; - playerProfile = params.pp; - Request.setSession(params.session); - checkJVMBitsAndVersion(); - LauncherEngine.modulesManager.invokeEvent(new ClientLauncherInitPhase(context)); - // Verify ClientLauncher sign and classpath - LogHelper.debug("Verifying ClientLauncher sign and classpath"); - URL[] classpath = resolveClassPath(params.clientDir, profile.getClassPath()); - classLoader = new ClientClassLoader(classpath, ClassLoader.getSystemClassLoader()); - profile.pushOptionalClassPath(cp -> { - LinkedList optionalClassPath = resolveClassPathList(params.clientDir, cp); - for (Path classpathURL : optionalClassPath) { - classLoader.addURL(classpathURL.normalize().toAbsolutePath().toUri().toURL()); - } - }); - Thread.currentThread().setContextClassLoader(classLoader); - classLoader.nativePath = params.clientDir.resolve(NATIVES_DIR).toString(); - // Start client with WatchService monitoring - boolean digest = !profile.isUpdateFastCheck(); - LogHelper.debug("Restore sessions"); - RestoreSessionRequest request = new RestoreSessionRequest(Request.getSession()); - request.request(); - Request.service.reconnectCallback = () -> - { - LogHelper.debug("WebSocket connect closed. Try reconnect"); - try { - Request.service.open(); - LogHelper.debug("Connect to %s", Launcher.getConfig().address); - } catch (Exception e) { - LogHelper.error(e); - throw new RequestException(String.format("Connect error: %s", e.getMessage() != null ? e.getMessage() : "null")); - } - try { - RestoreSessionRequest request1 = new RestoreSessionRequest(Request.getSession()); - request1.request(); - } catch (Exception e) { - LogHelper.error(e); - } - }; - AuthService.username = params.pp.username; - AuthService.uuid = params.pp.uuid; - ClientService.classLoader = classLoader; - ClientService.nativePath = classLoader.nativePath; - classLoader.addURL(IOHelper.getCodeSource(ClientLauncher.class).toUri().toURL()); - //classForName(classLoader, "com.google.common.collect.ForwardingMultimap"); - ClientService.baseURLs = classLoader.getURLs(); - LogHelper.debug("Starting JVM and client WatchService"); - FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher(); - FileNameMatcher clientMatcher = profile.getClientUpdateMatcher(); - try (DirWatcher assetWatcher = new DirWatcher(params.assetDir, assetHDir, assetMatcher, digest); - DirWatcher clientWatcher = new DirWatcher(params.clientDir, clientHDir, clientMatcher, digest)) { - // Verify current state of all dirs - //verifyHDir(IOHelper.JVM_DIR, jvmHDir.object, null, digest); - //for (OptionalFile s : Launcher.profile.getOptional()) { - // if (params.updateOptional.contains(s)) s.mark = true; - // else hdir.removeR(s.file); - //} - context.assetWatcher = assetWatcher; - context.clientWatcher = clientWatcher; - Launcher.profile.pushOptionalFile(clientHDir, false); - LauncherEngine.modulesManager.invokeEvent(new ClientLauncherPostInitPhase(context)); - // Start WatchService, and only then client - CommonHelper.newThread("Asset Directory Watcher", true, assetWatcher).start(); - CommonHelper.newThread("Client Directory Watcher", true, clientWatcher).start(); - verifyHDir(params.assetDir, assetHDir, assetMatcher, digest); - verifyHDir(params.clientDir, clientHDir, clientMatcher, digest); - LauncherEngine.modulesManager.invokeEvent(new ClientLaunchPhase(context)); - launch(profile, params); - } - } - public static void classForName(ClassLoader loader, String name) - { - try { - Class.forName(name, false, loader); - } catch (ClassNotFoundException ignored) { - } - } - - private static URL[] resolveClassPath(Path clientDir, String... classPath) throws IOException { - return resolveClassPathStream(clientDir, classPath).map(IOHelper::toURL).toArray(URL[]::new); - } - - private static LinkedList resolveClassPathList(Path clientDir, String... classPath) throws IOException { - return resolveClassPathStream(clientDir, classPath).collect(Collectors.toCollection(LinkedList::new)); - } - - private static Stream resolveClassPathStream(Path clientDir, String... classPath) throws IOException { - Stream.Builder builder = Stream.builder(); - for (String classPathEntry : classPath) { - Path path = clientDir.resolve(IOHelper.toPath(classPathEntry.replace(IOHelper.CROSS_SEPARATOR, IOHelper.PLATFORM_SEPARATOR))); - if (IOHelper.isDir(path)) { // Recursive walking and adding - IOHelper.walk(path, new ClassPathFileVisitor(builder), false); - continue; - } - builder.accept(path); - } - return builder.build(); - } - - private static void initGson(ClientModuleManager moduleManager) { - Launcher.gsonManager = new ClientGsonManager(moduleManager); - Launcher.gsonManager.initGson(); - } - - - public static void setProfile(ClientProfile profile) { - Launcher.profile = profile; - LogHelper.debug("New Profile name: %s", profile.getTitle()); - } - - public static void verifyHDir(Path dir, HashedDir hdir, FileNameMatcher matcher, boolean digest) throws IOException { - //if (matcher != null) - // matcher = matcher.verifyOnly(); - - // Hash directory and compare (ignore update-only matcher entries, it will break offline-mode) - HashedDir currentHDir = new HashedDir(dir, matcher, true, digest); - HashedDir.Diff diff = hdir.diff(currentHDir, matcher); - if (!diff.isSame()) { - /*AtomicBoolean isFoundFile = new AtomicBoolean(false); - diff.extra.walk(File.separator, (e,k,v) -> { - if(v.getType().equals(HashedEntry.Type.FILE)) { LogHelper.error("Extra file %s", e); isFoundFile.set(true); } - else LogHelper.error("Extra %s", e); - }); - diff.mismatch.walk(File.separator, (e,k,v) -> { - if(v.getType().equals(HashedEntry.Type.FILE)) { LogHelper.error("Mismatch file %s", e); isFoundFile.set(true); } - else LogHelper.error("Mismatch %s", e); - }); - if(isFoundFile.get())*/ - throw new SecurityException(String.format("Forbidden modification: '%s'", IOHelper.getFileName(dir))); - } - } - - private ClientLauncher() { - } - - public interface ParamsAPI { - ParamContainer read() throws Exception; - - void write(ParamContainer p) throws Exception; - } - - public static ParamsAPI container = new ParamsAPI() { - @Override - public ParamContainer read() throws Exception { - ParamContainer p; - try (Socket socket = IOHelper.newSocket()) { - socket.connect(new InetSocketAddress(SOCKET_HOST, SOCKET_PORT)); - try (HInput input = new HInput(socket.getInputStream())) { - p = new ParamContainer(input); - } - } - return p; - } - - @Override - public void write(ParamContainer p) throws Exception { - setWriteParamsThread(CommonHelper.newThread("Client params writter", true, () -> - { - try { - try (ServerSocket socket = new ServerSocket()) { - socket.setReuseAddress(true); - socket.setSoTimeout(30000); - socket.bind(new InetSocketAddress(SOCKET_HOST, SOCKET_PORT)); - Socket client = socket.accept(); - if (process == null) { - LogHelper.error("Process is null"); - return; - } - if (!process.isAlive()) { - LogHelper.error("Process is not alive"); - JOptionPane.showMessageDialog(null, "Client Process crashed", "Launcher", JOptionPane.ERROR_MESSAGE); - return; - } - try (HOutput output = new HOutput(client.getOutputStream())) { - p.write(output); - } - clientStarted = true; - } - } catch (IOException e) { - LogHelper.error(e); - } - })); - } - - }; - - public static class ParamContainer extends StreamObject { - - public ParamContainer(HInput input) throws Exception { - params = new Params(input); - profile = Launcher.gsonManager.gson.fromJson(input.readString(0), ClientProfile.class); - assetHDir = new HashedDir(input); - clientHDir = new HashedDir(input); - ClientHookManager.paramsInputHook.hook(input); - } - - public ParamContainer() { - } - - public ParamContainer(Params params, ClientProfile profile, HashedDir assetHDir, HashedDir clientHDir) { - this.params = params; - this.profile = profile; - this.assetHDir = assetHDir; - this.clientHDir = clientHDir; - } - - public Params params; - public ClientProfile profile; - public HashedDir assetHDir, clientHDir; - - @Override - public void write(HOutput output) throws IOException { - params.write(output); - output.writeString(Launcher.gsonManager.gson.toJson(profile), 0); - assetHDir.write(output); - clientHDir.write(output); - ClientHookManager.paramsOutputHook.hook(output); - } - } -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherContext.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherContext.java deleted file mode 100644 index a618e529..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherContext.java +++ /dev/null @@ -1,19 +0,0 @@ -package pro.gravit.launcher.client; - -import pro.gravit.launcher.profiles.ClientProfile; -import pro.gravit.launcher.profiles.PlayerProfile; - -import java.nio.file.Path; -import java.util.LinkedList; -import java.util.List; - -public class ClientLauncherContext { - public Path javaBin; - public final List args = new LinkedList<>(); - public String pathLauncher; - public ProcessBuilder builder; - public Process process; - public ClientProfile clientProfile; - public PlayerProfile playerProfile; - public ClientLauncher.Params params; -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java index f08b1fc5..11476144 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java @@ -6,9 +6,7 @@ import pro.gravit.launcher.LauncherEngine; import pro.gravit.launcher.api.AuthService; import pro.gravit.launcher.api.ClientService; -import pro.gravit.launcher.client.events.ClientLaunchPhase; -import pro.gravit.launcher.client.events.ClientLauncherInitPhase; -import pro.gravit.launcher.client.events.ClientLauncherPostInitPhase; +import pro.gravit.launcher.client.events.client.*; import pro.gravit.launcher.guard.LauncherGuardManager; import pro.gravit.launcher.hasher.FileNameMatcher; import pro.gravit.launcher.hasher.HashedDir; @@ -34,7 +32,6 @@ import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; -import java.security.spec.InvalidKeySpecException; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -59,6 +56,10 @@ private static ClientLauncherProcess.ClientParams readParams(SocketAddress addre public static void main(String[] args) throws Throwable { LauncherEngine.IS_CLIENT.set(true); LauncherEngine engine = LauncherEngine.clientInstance(); + JVMHelper.verifySystemProperties(ClientLauncherEntryPoint.class, true); + EnvHelper.checkDangerousParams(); + JVMHelper.checkStackTrace(ClientLauncherEntryPoint.class); + LogHelper.printVersion("Client Launcher"); LauncherEngine.checkClass(LauncherEngine.class); LauncherEngine.checkClass(LauncherAgent.class); LauncherEngine.checkClass(ClientLauncherEntryPoint.class); @@ -68,10 +69,6 @@ public static void main(String[] args) throws Throwable { initGson(LauncherEngine.modulesManager); LauncherEngine.verifyNoAgent(); LauncherEngine.modulesManager.invokeEvent(new PreConfigPhase()); - JVMHelper.verifySystemProperties(ClientLauncherEntryPoint.class, true); - EnvHelper.checkDangerousParams(); - JVMHelper.checkStackTrace(ClientLauncherEntryPoint.class); - LogHelper.printVersion("Client Launcher"); engine.readKeys(); LauncherGuardManager.initGuard(true); LogHelper.debug("Reading ClientLauncher params"); @@ -82,7 +79,7 @@ public static void main(String[] args) throws Throwable { LauncherEngine.clientParams = params; Request.setSession(params.session); checkJVMBitsAndVersion(); - LauncherEngine.modulesManager.invokeEvent(new ClientLauncherInitPhase(null)); + LauncherEngine.modulesManager.invokeEvent(new ClientProcessInitPhase(engine, params)); Path clientDir = Paths.get(params.clientDir); Path assetDir = Paths.get(params.assetDir); @@ -98,6 +95,7 @@ public static void main(String[] args) throws Throwable { classLoader = new ClientClassLoader(classpath.toArray(new URL[0]), ClassLoader.getSystemClassLoader()); Thread.currentThread().setContextClassLoader(classLoader); classLoader.nativePath = clientDir.resolve("natives").toString(); + LauncherEngine.modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(engine, classLoader, profile)); // Start client with WatchService monitoring boolean digest = !profile.isUpdateFastCheck(); LogHelper.debug("Restore sessions"); @@ -127,6 +125,7 @@ public static void main(String[] args) throws Throwable { classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL()); //classForName(classLoader, "com.google.common.collect.ForwardingMultimap"); ClientService.baseURLs = classLoader.getURLs(); + LauncherEngine.modulesManager.invokeEvent(new ClientProcessReadyEvent(engine, params)); LogHelper.debug("Starting JVM and client WatchService"); FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher(); FileNameMatcher clientMatcher = profile.getClientUpdateMatcher(); @@ -144,6 +143,7 @@ public static void main(String[] args) throws Throwable { CommonHelper.newThread("Client Directory Watcher", true, clientWatcher).start(); verifyHDir(assetDir, params.assetHDir, assetMatcher, digest); verifyHDir(clientDir, params.clientHDir, clientMatcher, digest); + LauncherEngine.modulesManager.invokeEvent(new ClientProcessLaunchEvent(engine, params)); launch(profile, params); } } @@ -244,6 +244,7 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa LogHelper.info("ClassLoader URL: %s", u.toString()); } FMLPatcher.apply(); + LauncherEngine.modulesManager.invokeEvent(new ClientProcessPreInvokeMainClassEvent(params, profile, args)); MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)).asFixedArity(); Launcher.LAUNCHED.set(true); JVMHelper.fullGC(); diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java index 1a7bb5ba..a1c7ad02 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java @@ -1,7 +1,12 @@ package pro.gravit.launcher.client; import pro.gravit.launcher.Launcher; -import pro.gravit.launcher.guard.LauncherGuardManager; +import pro.gravit.launcher.LauncherEngine; +import pro.gravit.launcher.LauncherNetworkAPI; +import pro.gravit.launcher.client.events.client.ClientProcessBuilderCreateEvent; +import pro.gravit.launcher.client.events.client.ClientProcessBuilderLaunchedEvent; +import pro.gravit.launcher.client.events.client.ClientProcessBuilderParamsWrittedEvent; +import pro.gravit.launcher.client.events.client.ClientProcessBuilderPreLaunchEvent; import pro.gravit.launcher.hasher.HashedDir; import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.launcher.profiles.PlayerProfile; @@ -10,10 +15,7 @@ import pro.gravit.utils.Version; import pro.gravit.utils.helper.*; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.OutputStream; -import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; @@ -24,9 +26,9 @@ public class ClientLauncherProcess { private transient Process process; private final transient Boolean[] waitWriteParams = new Boolean[] {false}; - public final Path executeFile; - public final Path workDir; - public final Path javaDir; + public Path executeFile; + public Path workDir; + public Path javaDir; public final ClientParams params = new ClientParams(); public final List jvmArgs = new LinkedList<>(); public final List systemClientArgs = new LinkedList<>(); @@ -42,18 +44,24 @@ public ClientLauncherProcess(Path executeFile, Path workDir, Path javaDir, Strin this.mainClass = mainClass; } + public ClientLauncherProcess(Path clientDir, Path assetDir, Path javaDir, + ClientProfile profile, PlayerProfile playerProfile, String accessToken, + HashedDir clientHDir, HashedDir assetHDir, HashedDir jvmHDir) { + this(clientDir, assetDir, javaDir, clientDir.resolve("resourcepacks"), profile, playerProfile, accessToken, clientHDir, assetHDir, jvmHDir); + } + public ClientLauncherProcess(Path clientDir, Path assetDir, ClientProfile profile, PlayerProfile playerProfile, String accessToken, HashedDir clientHDir, HashedDir assetHDir, HashedDir jvmHDir) { - this(clientDir, assetDir, clientDir.resolve("resourcepacks"), profile, playerProfile, accessToken, clientHDir, assetHDir, jvmHDir); + this(clientDir, assetDir, Paths.get(System.getProperty("java.home")), clientDir.resolve("resourcepacks"), profile, playerProfile, accessToken, clientHDir, assetHDir, jvmHDir); } - public ClientLauncherProcess(Path clientDir, Path assetDir, Path resourcePackDir, + public ClientLauncherProcess(Path clientDir, Path assetDir, Path javaDir, Path resourcePackDir, ClientProfile profile, PlayerProfile playerProfile, String accessToken, HashedDir clientHDir, HashedDir assetHDir, HashedDir jvmHDir) { - this.executeFile = LauncherGuardManager.getGuardJavaBinPath(); this.workDir = clientDir.toAbsolutePath(); - this.javaDir = Paths.get(System.getProperty("java.home")); + this.javaDir = javaDir; + this.executeFile = IOHelper.resolveJavaBin(this.javaDir); this.mainClass = ClientLauncherEntryPoint.class.getName(); this.params.clientDir = this.workDir.toString(); this.params.resourcePackDir = resourcePackDir.toAbsolutePath().toString(); @@ -78,6 +86,7 @@ private void applyClientProfile() this.jvmArgs.add("-Xmx" + params.ram + 'M'); } this.params.session = Request.getSession(); + LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderCreateEvent(this)); } @@ -128,6 +137,18 @@ public void addClientArgs(Collection args) } + public static class ClientUserProperties { + @LauncherNetworkAPI + public String[] skinURL; + @LauncherNetworkAPI + public String[] skinDigest; + @LauncherNetworkAPI + public String[] cloakURL; + @LauncherNetworkAPI + public String[] cloakDigest; + } + + public void addClientLegacyArgs(Collection args) { args.add(playerProfile.username); args.add(accessToken); @@ -151,7 +172,7 @@ private void addModernClientArgs(Collection args) { if (version.compareTo(ClientProfile.Version.MC1710) >= 0) { // Add user properties Collections.addAll(args, "--userType", "mojang"); - ClientLauncher.ClientUserProperties properties = new ClientLauncher.ClientUserProperties(); + ClientUserProperties properties = new ClientUserProperties(); if (playerProfile.skin != null) { properties.skinURL = new String[]{playerProfile.skin.url}; properties.skinDigest = new String[]{SecurityHelper.toHex(playerProfile.skin.digest)}; @@ -193,6 +214,8 @@ private void addModernClientArgs(Collection args) { } public void start(boolean pipeOutput) throws IOException, InterruptedException { if(isStarted) throw new IllegalStateException("Process already started"); + if(LauncherEngine.guard != null) LauncherEngine.guard.applyGuardParams(this); + LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderPreLaunchEvent(this)); List processArgs = new LinkedList<>(); processArgs.add(executeFile.toString()); processArgs.addAll(jvmArgs); @@ -212,6 +235,7 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException { LogHelper.debug("Commandline: %s", Arrays.toString(processArgs.toArray())); ProcessBuilder processBuilder = new ProcessBuilder(processArgs); EnvHelper.addEnv(processBuilder); + processBuilder.environment().put("JAVA_HOME", javaDir.toAbsolutePath().toString()); processBuilder.environment().putAll(systemEnv); processBuilder.directory(workDir.toFile()); processBuilder.inheritIO(); @@ -220,6 +244,7 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException { processBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE); } process = processBuilder.start(); + LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderLaunchedEvent(this)); isStarted = true; } public void runWriteParams(SocketAddress address) throws IOException @@ -242,6 +267,7 @@ public void runWriteParams(SocketAddress address) throws IOException params.javaHDir.write(output); } } + LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderParamsWrittedEvent(this)); } public Process getProcess() { diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java b/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java index 43f689d0..bec7a5ae 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java @@ -20,7 +20,6 @@ import java.util.regex.Pattern; public final class ServerPinger { - private final JsonParser parser = new JsonParser(); public static final class Result { @@ -184,7 +183,7 @@ private Result modernPing(HInput input, HOutput output) throws IOException { } // Parse JSON response - JsonObject object = parser.parse(response).getAsJsonObject(); + JsonObject object = JsonParser.parseString(response).getAsJsonObject(); JsonObject playersObject = object.get("players").getAsJsonObject(); int online = playersObject.get("online").getAsInt(); int max = playersObject.get("max").getAsInt(); diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/ClientLaunchPhase.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/ClientLaunchPhase.java deleted file mode 100644 index 10db8ba1..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/client/events/ClientLaunchPhase.java +++ /dev/null @@ -1,12 +0,0 @@ -package pro.gravit.launcher.client.events; - -import pro.gravit.launcher.client.ClientLauncher; -import pro.gravit.launcher.modules.LauncherModule; - -public class ClientLaunchPhase extends LauncherModule.Event { - public final ClientLauncher.ClientLaunchContext context; - - public ClientLaunchPhase(ClientLauncher.ClientLaunchContext context) { - this.context = context; - } -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/ClientLauncherInitPhase.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/ClientLauncherInitPhase.java deleted file mode 100644 index 83eea342..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/client/events/ClientLauncherInitPhase.java +++ /dev/null @@ -1,12 +0,0 @@ -package pro.gravit.launcher.client.events; - -import pro.gravit.launcher.client.ClientLauncher; -import pro.gravit.launcher.modules.events.InitPhase; - -public class ClientLauncherInitPhase extends InitPhase { - public final ClientLauncher.ClientLaunchContext context; - - public ClientLauncherInitPhase(ClientLauncher.ClientLaunchContext context) { - this.context = context; - } -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/ClientLauncherPostInitPhase.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/ClientLauncherPostInitPhase.java deleted file mode 100644 index 952ad735..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/client/events/ClientLauncherPostInitPhase.java +++ /dev/null @@ -1,12 +0,0 @@ -package pro.gravit.launcher.client.events; - -import pro.gravit.launcher.client.ClientLauncher; -import pro.gravit.launcher.modules.events.PostInitPhase; - -public class ClientLauncherPostInitPhase extends PostInitPhase { - public final ClientLauncher.ClientLaunchContext context; - - public ClientLauncherPostInitPhase(ClientLauncher.ClientLaunchContext context) { - this.context = context; - } -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderCreateEvent.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderCreateEvent.java new file mode 100644 index 00000000..2fe33846 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderCreateEvent.java @@ -0,0 +1,12 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.client.ClientLauncherProcess; +import pro.gravit.launcher.modules.LauncherModule; + +public class ClientProcessBuilderCreateEvent extends LauncherModule.Event { + public final ClientLauncherProcess processBuilder; + + public ClientProcessBuilderCreateEvent(ClientLauncherProcess processBuilder) { + this.processBuilder = processBuilder; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderLaunchedEvent.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderLaunchedEvent.java new file mode 100644 index 00000000..dc5e4ffc --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderLaunchedEvent.java @@ -0,0 +1,12 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.client.ClientLauncherProcess; +import pro.gravit.launcher.modules.LauncherModule; + +public class ClientProcessBuilderLaunchedEvent extends LauncherModule.Event { + public final ClientLauncherProcess processBuilder; + + public ClientProcessBuilderLaunchedEvent(ClientLauncherProcess processBuilder) { + this.processBuilder = processBuilder; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderParamsWrittedEvent.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderParamsWrittedEvent.java new file mode 100644 index 00000000..bb535568 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderParamsWrittedEvent.java @@ -0,0 +1,12 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.client.ClientLauncherProcess; +import pro.gravit.launcher.modules.LauncherModule; + +public class ClientProcessBuilderParamsWrittedEvent extends LauncherModule.Event { + public final ClientLauncherProcess process; + + public ClientProcessBuilderParamsWrittedEvent(ClientLauncherProcess process) { + this.process = process; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderPreLaunchEvent.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderPreLaunchEvent.java new file mode 100644 index 00000000..2b9b1025 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessBuilderPreLaunchEvent.java @@ -0,0 +1,12 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.client.ClientLauncherProcess; +import pro.gravit.launcher.modules.LauncherModule; + +public class ClientProcessBuilderPreLaunchEvent extends LauncherModule.Event { + public final ClientLauncherProcess processBuilder; + + public ClientProcessBuilderPreLaunchEvent(ClientLauncherProcess processBuilder) { + this.processBuilder = processBuilder; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessClassLoaderEvent.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessClassLoaderEvent.java new file mode 100644 index 00000000..3cffc0aa --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessClassLoaderEvent.java @@ -0,0 +1,17 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.LauncherEngine; +import pro.gravit.launcher.modules.LauncherModule; +import pro.gravit.launcher.profiles.ClientProfile; + +public class ClientProcessClassLoaderEvent extends LauncherModule.Event { + public final LauncherEngine clientInstance; + public final ClassLoader clientClassLoader; + public final ClientProfile profile; + + public ClientProcessClassLoaderEvent(LauncherEngine clientInstance, ClassLoader clientClassLoader, ClientProfile profile) { + this.clientInstance = clientInstance; + this.clientClassLoader = clientClassLoader; + this.profile = profile; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessInitPhase.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessInitPhase.java new file mode 100644 index 00000000..69378d97 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessInitPhase.java @@ -0,0 +1,15 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.LauncherEngine; +import pro.gravit.launcher.client.ClientLauncherProcess; +import pro.gravit.launcher.modules.events.InitPhase; + +public class ClientProcessInitPhase extends InitPhase { + public final LauncherEngine clientInstance; + public final ClientLauncherProcess.ClientParams params; + + public ClientProcessInitPhase(LauncherEngine clientInstance, ClientLauncherProcess.ClientParams params) { + this.clientInstance = clientInstance; + this.params = params; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessLaunchEvent.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessLaunchEvent.java new file mode 100644 index 00000000..5e66f7f6 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessLaunchEvent.java @@ -0,0 +1,15 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.LauncherEngine; +import pro.gravit.launcher.client.ClientLauncherProcess; +import pro.gravit.launcher.modules.LauncherModule; + +public class ClientProcessLaunchEvent extends LauncherModule.Event { + public final LauncherEngine clientInstance; + public final ClientLauncherProcess.ClientParams params; + + public ClientProcessLaunchEvent(LauncherEngine clientInstance, ClientLauncherProcess.ClientParams params) { + this.clientInstance = clientInstance; + this.params = params; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessPreInvokeMainClassEvent.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessPreInvokeMainClassEvent.java new file mode 100644 index 00000000..0ac25094 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessPreInvokeMainClassEvent.java @@ -0,0 +1,19 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.client.ClientLauncherProcess; +import pro.gravit.launcher.modules.LauncherModule; +import pro.gravit.launcher.profiles.ClientProfile; + +import java.util.Collection; + +public class ClientProcessPreInvokeMainClassEvent extends LauncherModule.Event { + public final ClientLauncherProcess.ClientParams params; + public final ClientProfile profile; + public final Collection args; + + public ClientProcessPreInvokeMainClassEvent(ClientLauncherProcess.ClientParams params, ClientProfile profile, Collection args) { + this.params = params; + this.profile = profile; + this.args = args; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessReadyEvent.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessReadyEvent.java new file mode 100644 index 00000000..046951a6 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessReadyEvent.java @@ -0,0 +1,16 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.LauncherEngine; +import pro.gravit.launcher.client.ClientLauncherProcess; +import pro.gravit.launcher.modules.events.PostInitPhase; +import pro.gravit.launcher.profiles.ClientProfile; + +public class ClientProcessReadyEvent extends PostInitPhase { + public final LauncherEngine clientInstance; + public final ClientLauncherProcess.ClientParams params; + + public ClientProcessReadyEvent(LauncherEngine clientInstance, ClientLauncherProcess.ClientParams params) { + this.clientInstance = clientInstance; + this.params = params; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuardInterface.java b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuardInterface.java index e0be7852..b277d656 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuardInterface.java +++ b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuardInterface.java @@ -1,21 +1,9 @@ package pro.gravit.launcher.guard; -import pro.gravit.launcher.client.ClientLauncherContext; - -import java.nio.file.Path; +import pro.gravit.launcher.client.ClientLauncherProcess; public interface LauncherGuardInterface { String getName(); - Path getJavaBinPath(); - - int getClientJVMBits(); - - void init(boolean clientInstance); - - void addCustomParams(ClientLauncherContext context); - - void addCustomEnv(ClientLauncherContext context); - - void setProtectToken(String token); + void applyGuardParams(ClientLauncherProcess process); } diff --git a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuardManager.java b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuardManager.java index 6b4e763b..65dc653a 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuardManager.java +++ b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuardManager.java @@ -9,31 +9,5 @@ public class LauncherGuardManager { public static LauncherGuardInterface guard; public static void initGuard(boolean clientInstance) { - if(guard == null) - { - LauncherConfig config = Launcher.getConfig(); - switch (config.guardType) { - case "stdguard": { - guard = new LauncherStdGuard(); - break; - } - case "wrapper": { - guard = new LauncherWrapperGuard(); - break; - } - case "java": { - guard = new LauncherJavaGuard(); - break; - } - default: { - guard = new LauncherNoGuard(); - } - } - } - guard.init(clientInstance); - } - - public static Path getGuardJavaBinPath() { - return guard.getJavaBinPath(); } } diff --git a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherJavaGuard.java b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherJavaGuard.java deleted file mode 100644 index 8b4a013e..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherJavaGuard.java +++ /dev/null @@ -1,51 +0,0 @@ -package pro.gravit.launcher.guard; - -import pro.gravit.launcher.client.ClientLauncher; -import pro.gravit.launcher.client.ClientLauncherContext; -import pro.gravit.utils.helper.IOHelper; -import pro.gravit.utils.helper.JVMHelper; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collections; - -public class LauncherJavaGuard implements LauncherGuardInterface { - @Override - public String getName() { - return "java"; - } - - @Override - public Path getJavaBinPath() { - if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) - return IOHelper.resolveJavaBin(ClientLauncher.getJavaBinPath()); - else - return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home"))); - } - - @Override - public int getClientJVMBits() { - return JVMHelper.OS_BITS; - } - - @Override - public void init(boolean clientInstance) { - - } - - @Override - public void addCustomParams(ClientLauncherContext context) { - Collections.addAll(context.args, "-cp"); - Collections.addAll(context.args, context.pathLauncher); - } - - @Override - public void addCustomEnv(ClientLauncherContext context) { - - } - - @Override - public void setProtectToken(String token) { - //Skip - } -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherNoGuard.java b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherNoGuard.java index 2ca267a9..2e2d8789 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherNoGuard.java +++ b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherNoGuard.java @@ -1,13 +1,6 @@ package pro.gravit.launcher.guard; -import pro.gravit.launcher.client.ClientLauncherContext; -import pro.gravit.utils.helper.IOHelper; -import pro.gravit.utils.helper.JVMHelper; -import pro.gravit.utils.helper.LogHelper; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collections; +import pro.gravit.launcher.client.ClientLauncherProcess; public class LauncherNoGuard implements LauncherGuardInterface { @Override @@ -16,33 +9,7 @@ public String getName() { } @Override - public Path getJavaBinPath() { - return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home"))); - } - - @Override - public int getClientJVMBits() { - return JVMHelper.JVM_BITS; - } - - @Override - public void init(boolean clientInstance) { - LogHelper.warning("Using noGuard interface"); - } - - @Override - public void addCustomParams(ClientLauncherContext context) { - Collections.addAll(context.args, "-cp"); - Collections.addAll(context.args, context.pathLauncher); - } - - @Override - public void addCustomEnv(ClientLauncherContext context) { - - } - - @Override - public void setProtectToken(String token) { - //Skip + public void applyGuardParams(ClientLauncherProcess process) { + //IGNORED } } diff --git a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherStdGuard.java b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherStdGuard.java deleted file mode 100644 index 96d17677..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherStdGuard.java +++ /dev/null @@ -1,85 +0,0 @@ -package pro.gravit.launcher.guard; - -import pro.gravit.launcher.Launcher; -import pro.gravit.launcher.LauncherConfig; -import pro.gravit.launcher.client.ClientLauncher; -import pro.gravit.launcher.client.ClientLauncherContext; -import pro.gravit.launcher.client.DirBridge; -import pro.gravit.utils.helper.IOHelper; -import pro.gravit.utils.helper.JVMHelper; -import pro.gravit.utils.helper.UnpackHelper; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collections; -import java.util.Map; - -//Стандартный интерфейс для всех AntiInject -public class LauncherStdGuard implements LauncherGuardInterface { - public String protectToken; - public Path javaBinPath; - - @Override - public String getName() { - return "stdguard"; - } - - @Override - public Path getJavaBinPath() { - if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) { - javaBinPath = ClientLauncher.getJavaBinPath(); - String projectName = Launcher.getConfig().projectName; - String wrapperUnpackName = (javaBinPath == null ? JVMHelper.JVM_BITS : JVMHelper.OS_BITS) == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe"); - return DirBridge.getGuardDir().resolve(wrapperUnpackName); - } else - return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home"))); - } - - @Override - public int getClientJVMBits() { - //При использовании GravitGuard без своей джавы - //Если при запуске лаунчера используется 32 бит джава, а ОС 64бит - //То в окне настроек будет отображаться >1.5Гб доступной памяти - //Однако при выставлении >1.5Гб JVM x32 работать откажеться - return JVMHelper.OS_BITS; - } - - @Override - public void init(boolean clientInstance) { - try { - String projectName = Launcher.getConfig().projectName; - UnpackHelper.unpack(Launcher.getResourceURL("wrapper64.exe", "guard"), DirBridge.getGuardDir().resolve(projectName.concat("64.exe"))); - UnpackHelper.unpack(Launcher.getResourceURL("AntiInject64.dll", "guard"), DirBridge.getGuardDir().resolve("AntiInject64.dll")); - - UnpackHelper.unpack(Launcher.getResourceURL("wrapper32.exe", "guard"), DirBridge.getGuardDir().resolve(projectName.concat("32.exe"))); - UnpackHelper.unpack(Launcher.getResourceURL("AntiInject32.dll", "guard"), DirBridge.getGuardDir().resolve("AntiInject32.dll")); - } catch (IOException e) { - throw new SecurityException(e); - } - } - - @Override - public void addCustomParams(ClientLauncherContext context) { - Collections.addAll(context.args, "-Djava.class.path=".concat(context.pathLauncher)); - } - - @Override - public void addCustomEnv(ClientLauncherContext context) { - Map env = context.builder.environment(); - if (javaBinPath == null) - env.put("JAVA_HOME", System.getProperty("java.home")); - else - env.put("JAVA_HOME", javaBinPath.toAbsolutePath().toString()); - LauncherConfig config = Launcher.getConfig(); - env.put("GUARD_USERNAME", context.playerProfile.username); - env.put("GUARD_PROJECTNAME", config.projectName); - if (protectToken != null) - env.put("GUARD_TOKEN", protectToken); - } - - @Override - public void setProtectToken(String token) { - protectToken = token; - } -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherWrapperGuard.java b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherWrapperGuard.java index fe841e79..50c042be 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherWrapperGuard.java +++ b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherWrapperGuard.java @@ -1,45 +1,30 @@ package pro.gravit.launcher.guard; import pro.gravit.launcher.Launcher; -import pro.gravit.launcher.LauncherConfig; -import pro.gravit.launcher.client.ClientLauncherContext; +import pro.gravit.launcher.client.ClientLauncherProcess; import pro.gravit.launcher.client.DirBridge; -import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.JVMHelper; import pro.gravit.utils.helper.UnpackHelper; import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collections; -import java.util.Map; public class LauncherWrapperGuard implements LauncherGuardInterface { - public String protectToken; - @Override public String getName() { return "wrapper"; } @Override - public Path getJavaBinPath() { + public void applyGuardParams(ClientLauncherProcess process) { if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) { String projectName = Launcher.getConfig().projectName; String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe"); - return DirBridge.getGuardDir().resolve(wrapperUnpackName); - } else - return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home"))); + process.executeFile = DirBridge.getGuardDir().resolve(wrapperUnpackName); + } } - @Override - public int getClientJVMBits() { - return JVMHelper.JVM_BITS; - } - - @Override - public void init(boolean clientInstance) { + public LauncherWrapperGuard() { try { String wrapperName = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe"; String projectName = Launcher.getConfig().projectName; @@ -51,25 +36,4 @@ public void init(boolean clientInstance) { throw new SecurityException(e); } } - - @Override - public void addCustomParams(ClientLauncherContext context) { - Collections.addAll(context.args, "-Djava.class.path=".concat(context.pathLauncher)); - } - - @Override - public void addCustomEnv(ClientLauncherContext context) { - Map env = context.builder.environment(); - env.put("JAVA_HOME", System.getProperty("java.home")); - LauncherConfig config = Launcher.getConfig(); - env.put("GUARD_USERNAME", context.playerProfile.username); - env.put("GUARD_PROJECTNAME", config.projectName); - if (protectToken != null) - env.put("GUARD_TOKEN", protectToken); - } - - @Override - public void setProtectToken(String token) { - protectToken = token; - } } diff --git a/Launcher/src/main/java/pro/gravit/launcher/managers/ClientHookManager.java b/Launcher/src/main/java/pro/gravit/launcher/managers/ClientHookManager.java deleted file mode 100644 index c273a983..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/managers/ClientHookManager.java +++ /dev/null @@ -1,20 +0,0 @@ -package pro.gravit.launcher.managers; - -import pro.gravit.launcher.client.ClientLauncherContext; -import pro.gravit.launcher.gui.RuntimeProvider; -import pro.gravit.launcher.serialize.HInput; -import pro.gravit.launcher.serialize.HOutput; -import pro.gravit.utils.BiHookSet; -import pro.gravit.utils.HookSet; - -public class ClientHookManager { - public static final HookSet initGuiHook = new HookSet<>(); - public static final HookSet paramsInputHook = new HookSet<>(); - public static final HookSet paramsOutputHook = new HookSet<>(); - - public static final HookSet clientLaunchHook = new HookSet<>(); - public static final HookSet clientLaunchFinallyHook = new HookSet<>(); - - public static final BiHookSet preStartHook = new BiHookSet<>(); - public static final BiHookSet postStartHook = new BiHookSet<>(); -} diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/ClientPermissions.java b/LauncherAPI/src/main/java/pro/gravit/launcher/ClientPermissions.java index db3ddd3a..5bb005d1 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/ClientPermissions.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/ClientPermissions.java @@ -8,73 +8,104 @@ public class ClientPermissions { public static final ClientPermissions DEFAULT = new ClientPermissions(); - @LauncherNetworkAPI - public boolean canAdmin; - @LauncherNetworkAPI - public boolean canServer; - @LauncherNetworkAPI - public final boolean canUSR1; - @LauncherNetworkAPI - public final boolean canUSR2; - @LauncherNetworkAPI - public final boolean canUSR3; - @LauncherNetworkAPI - public boolean canBot; + public long permissions; + public long flags; + public enum PermissionConsts + { + ADMIN(0x01), + MANAGEMENT(0x02); + public final long mask; + + PermissionConsts(long mask) { + this.mask = mask; + } + } + public enum FlagConsts + { + SYSTEM(0x01), + BANNED(0x02), + UNTRUSTED(0x04), + HIDDEN(0x08); + public final long mask; + + FlagConsts(long mask) { + this.mask = mask; + } + } public ClientPermissions(HInput input) throws IOException { this(input.readLong()); } public ClientPermissions() { - canAdmin = false; - canServer = false; - canUSR1 = false; - canUSR2 = false; - canUSR3 = false; - canBot = false; + } - public ClientPermissions(long data) { - canAdmin = (data & (1)) != 0; - canServer = (data & (1 << 1)) != 0; - canUSR1 = (data & (1 << 2)) != 0; - canUSR2 = (data & (1 << 3)) != 0; - canUSR3 = (data & (1 << 4)) != 0; - canBot = (data & (1 << 5)) != 0; + public ClientPermissions(long permissions) { + this.permissions = permissions; } + public ClientPermissions(long permissions, long flags) { + this.permissions = permissions; + this.flags = flags; + } public long toLong() { - long result = 0; - result |= !canAdmin ? 0 : 1; - result |= !canServer ? 0 : (1 << 1); - result |= !canUSR1 ? 0 : (1 << 2); - result |= !canUSR2 ? 0 : (1 << 3); - result |= !canUSR3 ? 0 : (1 << 4); - result |= !canBot ? 0 : (1 << 5); - return result; + return permissions; } public static ClientPermissions getSuperuserAccount() { ClientPermissions perm = new ClientPermissions(); - perm.canServer = true; - perm.canAdmin = true; return perm; } - + @Deprecated public void write(HOutput output) throws IOException { output.writeLong(toLong()); } + //Read methods + public final boolean isPermission(PermissionConsts con) + { + return (permissions & con.mask) != 0; + } + public final boolean isPermission(long mask) + { + return (permissions & mask) != 0; + } + public final boolean isFlag(FlagConsts con) + { + return (flags & con.mask) != 0; + } + public final boolean isFlag(long mask) + { + return (flags & mask) != 0; + } + //Write methods + public final void setPermission(PermissionConsts con, boolean value) + { + if(value) this.permissions |= con.mask; + else this.permissions &= ~con.mask; + } + public final void setPermission(long mask, boolean value) + { + if(value) this.permissions |= mask; + else this.permissions &= ~mask; + } + public final void setFlag(FlagConsts con, boolean value) + { + if(value) this.flags |= con.mask; + else this.flags &= ~con.mask; + } + public final void setFlag(long mask, boolean value) + { + if(value) this.flags |= mask; + else this.flags &= ~mask; + } + + + @Override public String toString() { - return new StringJoiner(", ", ClientPermissions.class.getSimpleName() + "[", "]") - .add("canAdmin=" + canAdmin) - .add("canServer=" + canServer) - .add("canUSR1=" + canUSR1) - .add("canUSR2=" + canUSR2) - .add("canUSR3=" + canUSR3) - .add("canBot=" + canBot) - .toString(); + return String.format("permissions %d | flags %d", permissions, flags); } } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java index c24186d0..59a2c7ee 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -5,6 +5,7 @@ import pro.gravit.launcher.hasher.HashedDir; import pro.gravit.launcher.profiles.optional.OptionalDepend; import pro.gravit.launcher.profiles.optional.OptionalFile; +import pro.gravit.launcher.profiles.optional.OptionalTrigger; import pro.gravit.launcher.profiles.optional.OptionalType; import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.VerifyHelper; @@ -444,6 +445,16 @@ public void verify() { if (s == null) throw new IllegalArgumentException(String.format("Found null entry in updateOptional.%s.dependenciesFile", f.name)); } + if(f.triggers != null) + { + for(OptionalTrigger trigger : f.triggers) + { + if(trigger == null) + throw new IllegalArgumentException(String.format("Found null entry in updateOptional.%s.triggers", f.name)); + if(trigger.type == null) + throw new IllegalArgumentException(String.format("trigger.type must not be null in updateOptional.%s.triggers", f.name)); + } + } } } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/StdWebSocketService.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/StdWebSocketService.java index dfb5eecf..0987f911 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/StdWebSocketService.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/StdWebSocketService.java @@ -25,6 +25,10 @@ public void registerEventHandler(EventHandler handler) { eventHandlers.add(handler); } + public void unregisterEventHandler(EventHandler handler) + { + eventHandlers.remove(handler); + } public void processEventHandlers(T event) { for(EventHandler handler : eventHandlers) diff --git a/LauncherAuthlib/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java b/LauncherAuthlib/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java index b75e9014..4cc26f90 100644 --- a/LauncherAuthlib/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java +++ b/LauncherAuthlib/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java @@ -28,7 +28,6 @@ import java.util.UUID; public class YggdrasilMinecraftSessionService extends BaseMinecraftSessionService { - public static final JsonParser JSON_PARSER = new JsonParser(); public static final boolean NO_TEXTURES = Boolean.parseBoolean("launcher.com.mojang.authlib.noTextures"); public static void fillTextureProperties(GameProfile profile, PlayerProfile pp) { @@ -62,7 +61,7 @@ private static void getTexturesMojang(Map statusCode || statusCode > 300) { LogHelper.error("JsonRequest failed. Server response code %d", statusCode); diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Version.java b/LauncherCore/src/main/java/pro/gravit/utils/Version.java index d0323266..ffb7c94a 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/Version.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/Version.java @@ -15,9 +15,9 @@ public final class Version { public final Type release; public static final int MAJOR = 5; public static final int MINOR = 1; - public static final int PATCH = 2; + public static final int PATCH = 3; public static final int BUILD = 1; - public static final Version.Type RELEASE = Type.BETA; + public static final Version.Type RELEASE = Type.STABLE; public Version(int major, int minor, int patch) { diff --git a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java index 59a37e42..bbac33a4 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java @@ -259,7 +259,7 @@ public static final class Config { public String login; public String[] args; public String password; - public final String auth_id = ""; + public String auth_id = ""; public LauncherConfig.LauncherEnvironment env; } diff --git a/build.gradle b/build.gradle index b97a4969..bf75dddc 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ id 'org.openjfx.javafxplugin' version '0.0.7' apply false } group = 'pro.gravit.launcher' -version = '5.1.2' +version = '5.1.3' apply from: 'props.gradle' diff --git a/modules b/modules index 2edb2c72..07e4380a 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 2edb2c7259d5a7dba3fa82c503f88a8a0e171840 +Subproject commit 07e4380ad52c4ef08378b8eb2202d8a1bd3639a2 diff --git a/props.gradle b/props.gradle index 2140b970..188d9517 100644 --- a/props.gradle +++ b/props.gradle @@ -1,18 +1,18 @@ project.ext { - verAsm = '7.2' - verNetty = '4.1.43.Final' - verOshiCore = '3.13.0' - verJunit = '5.6.0' - verGuavaC = '26.0-jre' + verAsm = '7.3.1' + verNetty = '4.1.48.Final' + verOshiCore = '4.5.2' + verJunit = '5.6.1' + verGuavaC = '28.2-jre' verJansi = '1.18' - verJline = '3.11.0' + verJline = '3.14.0' verBcprov = '1.46' - verGson = '2.8.5' + verGson = '2.8.6' verBcpkix = '1.61' verSlf4j = '1.7.25' - verMySQLConn = '8.0.16' - verPostgreSQLConn = '42.2.6' - verProguard = '6.2.0' + verMySQLConn = '8.0.19' + verPostgreSQLConn = '42.2.11' + verProguard = '6.2.2' verLaunch4j = '3.12' - verHibernate = '5.4.9.Final' + verHibernate = '5.4.12.Final' }