mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 03:31:15 +03:00
Merge branch 'release/5.1.3'
This commit is contained in:
commit
45e3d0b18e
62 changed files with 602 additions and 1250 deletions
82
.github/workflows/push.yml
vendored
Normal file
82
.github/workflows/push.yml
vendored
Normal file
|
@ -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
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -109,3 +109,4 @@ cmd.bat
|
||||||
cmd.sh
|
cmd.sh
|
||||||
## PVS Studio
|
## PVS Studio
|
||||||
.PVS-Studio/
|
.PVS-Studio/
|
||||||
|
project/target
|
||||||
|
|
|
@ -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
|
|
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -1,3 +1,3 @@
|
||||||
[submodule "modules"]
|
[submodule "modules"]
|
||||||
path = modules
|
path = modules
|
||||||
url = git@github.com:GravitLauncher/LauncherModules.git
|
url = https://github.com/GravitLauncher/LauncherModules.git
|
||||||
|
|
22
.travis.yml
22
.travis.yml
|
@ -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
|
|
|
@ -100,7 +100,7 @@ pack project(':LauncherAPI')
|
||||||
exclude group: 'org.slf4j'
|
exclude group: 'org.slf4j'
|
||||||
}
|
}
|
||||||
launch4j('net.sf.launch4j:launch4j:' + rootProject['verLaunch4j'] + ':workdir-win32') { transitive = false }
|
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']
|
compileOnlyA group: 'com.google.guava', name: 'guava', version: rootProject['verGuavaC']
|
||||||
// Do not update (laggy deps).
|
// Do not update (laggy deps).
|
||||||
|
|
|
@ -98,7 +98,6 @@ public void reload(ReloadType type) throws Exception {
|
||||||
LogHelper.debug("Init components");
|
LogHelper.debug("Init components");
|
||||||
config.components.forEach((k, v) -> {
|
config.components.forEach((k, v) -> {
|
||||||
LogHelper.subDebug("Init component %s", k);
|
LogHelper.subDebug("Init component %s", k);
|
||||||
registerObject("component.".concat(k), v);
|
|
||||||
v.init(this);
|
v.init(this);
|
||||||
});
|
});
|
||||||
LogHelper.debug("Init components successful");
|
LogHelper.debug("Init components successful");
|
||||||
|
|
|
@ -43,8 +43,8 @@ public synchronized Connection getConnection() throws SQLException {
|
||||||
PGSimpleDataSource postgresqlSource = new PGSimpleDataSource();
|
PGSimpleDataSource postgresqlSource = new PGSimpleDataSource();
|
||||||
|
|
||||||
// Set credentials
|
// Set credentials
|
||||||
postgresqlSource.setServerName(address);
|
postgresqlSource.setServerNames(new String[] {address}); //TODO support multinode PostgreSQL DB
|
||||||
postgresqlSource.setPortNumber(port);
|
postgresqlSource.setPortNumbers(new int[] {port});
|
||||||
postgresqlSource.setUser(username);
|
postgresqlSource.setUser(username);
|
||||||
postgresqlSource.setPassword(password);
|
postgresqlSource.setPassword(password);
|
||||||
postgresqlSource.setDatabaseName(database);
|
postgresqlSource.setDatabaseName(database);
|
||||||
|
|
|
@ -21,6 +21,7 @@ public static class authResult {
|
||||||
String username;
|
String username;
|
||||||
String error;
|
String error;
|
||||||
long permissions;
|
long permissions;
|
||||||
|
long flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class authRequest {
|
public static class authRequest {
|
||||||
|
@ -54,7 +55,7 @@ public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface p
|
||||||
|
|
||||||
authResult result = gson.fromJson(content, authResult.class);
|
authResult result = gson.fromJson(content, authResult.class);
|
||||||
if (result.username != null)
|
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)
|
else if (result.error != null)
|
||||||
return authError(result.error);
|
return authError(result.error);
|
||||||
else
|
else
|
||||||
|
|
|
@ -20,6 +20,7 @@ public final class MySQLAuthProvider extends AuthProvider {
|
||||||
private String query;
|
private String query;
|
||||||
private String message;
|
private String message;
|
||||||
private String[] queryParams;
|
private String[] queryParams;
|
||||||
|
private boolean flagsEnabled;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(LaunchServer srv) {
|
public void init(LaunchServer srv) {
|
||||||
|
@ -41,7 +42,8 @@ public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface p
|
||||||
// Execute SQL query
|
// Execute SQL query
|
||||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||||
try (ResultSet set = s.executeQuery()) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ public final class PostgreSQLAuthProvider extends AuthProvider {
|
||||||
private String query;
|
private String query;
|
||||||
private String message;
|
private String message;
|
||||||
private String[] queryParams;
|
private String[] queryParams;
|
||||||
|
private boolean flagsEnabled;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws SQLException, AuthException {
|
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
|
// Execute SQL query
|
||||||
s.setQueryTimeout(PostgreSQLSourceConfig.TIMEOUT);
|
s.setQueryTimeout(PostgreSQLSourceConfig.TIMEOUT);
|
||||||
try (ResultSet set = s.executeQuery()) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ public RejectAuthProvider(String message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String message;
|
private String message;
|
||||||
private ArrayList<String> whitelist;
|
private ArrayList<String> whitelist = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws AuthException {
|
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws AuthException {
|
||||||
|
@ -46,11 +46,20 @@ public Map<String, Command> getCommands() {
|
||||||
Map<String, Command> commands = new HashMap<>();
|
Map<String, Command> commands = new HashMap<>();
|
||||||
commands.put("message", new SubCommand() {
|
commands.put("message", new SubCommand() {
|
||||||
@Override
|
@Override
|
||||||
public void invoke(String... args) {
|
public void invoke(String... args) throws Exception {
|
||||||
|
verifyArgs(args, 1);
|
||||||
message = args[0];
|
message = args[0];
|
||||||
LogHelper.info("New reject message: %s", message);
|
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;
|
return commands;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ public final class RequestAuthProvider extends AuthProvider {
|
||||||
private String url;
|
private String url;
|
||||||
private transient Pattern pattern;
|
private transient Pattern pattern;
|
||||||
private String response;
|
private String response;
|
||||||
|
private boolean flagsEnabled;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(LaunchServer srv) {
|
public void init(LaunchServer srv) {
|
||||||
|
@ -36,7 +37,8 @@ public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface p
|
||||||
// Match username
|
// Match username
|
||||||
Matcher matcher = pattern.matcher(currentResponse);
|
Matcher matcher = pattern.matcher(currentResponse);
|
||||||
return matcher.matches() && matcher.groupCount() >= 1 ?
|
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);
|
authError(currentResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
|
||||||
updates.registerCommand("syncBinaries", new SyncBinariesCommand(server));
|
updates.registerCommand("syncBinaries", new SyncBinariesCommand(server));
|
||||||
updates.registerCommand("syncUpdates", new SyncUpdatesCommand(server));
|
updates.registerCommand("syncUpdates", new SyncUpdatesCommand(server));
|
||||||
updates.registerCommand("syncProfiles", new SyncProfilesCommand(server));
|
updates.registerCommand("syncProfiles", new SyncProfilesCommand(server));
|
||||||
|
updates.registerCommand("saveProfiles", new SaveProfilesCommand(server));
|
||||||
Category updatesCategory = new Category(updates, "updates", "Update and Sync Management");
|
Category updatesCategory = new Category(updates, "updates", "Update and Sync Management");
|
||||||
handler.registerCategory(updatesCategory);
|
handler.registerCategory(updatesCategory);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,8 +16,6 @@
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public final class UnindexAssetCommand extends Command {
|
public final class UnindexAssetCommand extends Command {
|
||||||
private static final JsonParser parser = new JsonParser();
|
|
||||||
|
|
||||||
public UnindexAssetCommand(LaunchServer server) {
|
public UnindexAssetCommand(LaunchServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +49,7 @@ public void invoke(String... args) throws Exception {
|
||||||
JsonObject objects;
|
JsonObject objects;
|
||||||
LogHelper.subInfo("Reading asset index file: '%s'", indexFileName);
|
LogHelper.subInfo("Reading asset index file: '%s'", indexFileName);
|
||||||
try (BufferedReader reader = IOHelper.newReader(IndexAssetCommand.resolveIndexFile(inputAssetDir, 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
|
// Restore objects
|
||||||
|
|
|
@ -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.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",
|
LogHelper.subInfo("Data: checkSign %s | auth_id %s", client.checkSign ? "true" : "false",
|
||||||
client.auth_id);
|
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);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import pro.gravit.launcher.Launcher;
|
import pro.gravit.launcher.Launcher;
|
||||||
import pro.gravit.launcher.LauncherConfig;
|
import pro.gravit.launcher.LauncherConfig;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
|
import pro.gravit.launchserver.Reconfigurable;
|
||||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||||
import pro.gravit.launchserver.auth.handler.MemoryAuthHandler;
|
import pro.gravit.launchserver.auth.handler.MemoryAuthHandler;
|
||||||
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
||||||
|
@ -124,8 +125,10 @@ public void init(LaunchServer.ReloadType type) {
|
||||||
for (Map.Entry<String,AuthProviderPair> provider : auth.entrySet()) {
|
for (Map.Entry<String,AuthProviderPair> provider : auth.entrySet()) {
|
||||||
provider.getValue().init(server, provider.getKey());
|
provider.getValue().init(server, provider.getKey());
|
||||||
}
|
}
|
||||||
if (dao != null)
|
if (dao != null) {
|
||||||
|
server.registerObject("dao", dao);
|
||||||
dao.init(server);
|
dao.init(server);
|
||||||
|
}
|
||||||
if (protectHandler != null) {
|
if (protectHandler != null) {
|
||||||
protectHandler.checkLaunchServerLicense();
|
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(".provider"), pair.provider);
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
|
server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
|
server.unregisterObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
|
||||||
|
pair.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type.equals(LaunchServer.ReloadType.FULL)) {
|
if (type.equals(LaunchServer.ReloadType.FULL)) {
|
||||||
|
@ -166,10 +170,16 @@ public void close(LaunchServer.ReloadType type) {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
try {
|
if(dao != null) {
|
||||||
for (AuthProviderPair p : auth.values()) p.close();
|
server.unregisterObject("dao", dao);
|
||||||
} catch (IOException e) {
|
if(dao instanceof AutoCloseable)
|
||||||
LogHelper.error(e);
|
{
|
||||||
|
try {
|
||||||
|
((AutoCloseable) dao).close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Entity
|
@Entity(name = "User")
|
||||||
@Table(name = "users")
|
@Table(name = "users")
|
||||||
public class UserHibernateImpl implements User {
|
public class UserHibernateImpl implements User {
|
||||||
@Id
|
@Id
|
||||||
|
@ -29,6 +29,7 @@ public class UserHibernateImpl implements User {
|
||||||
public String serverID;
|
public String serverID;
|
||||||
private String password_salt;
|
private String password_salt;
|
||||||
public long permissions;
|
public long permissions;
|
||||||
|
public long flags;
|
||||||
|
|
||||||
public void setPassword(String password) {
|
public void setPassword(String password) {
|
||||||
password_salt = SecurityHelper.randomStringAESKey();
|
password_salt = SecurityHelper.randomStringAESKey();
|
||||||
|
@ -55,11 +56,12 @@ public boolean verifyPassword(String password) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientPermissions getPermissions() {
|
public ClientPermissions getPermissions() {
|
||||||
return new ClientPermissions(permissions);
|
return new ClientPermissions(permissions, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPermissions(ClientPermissions permissions) {
|
public void setPermissions(ClientPermissions permissions) {
|
||||||
this.permissions = permissions.toLong();
|
this.permissions = permissions.permissions;
|
||||||
|
this.flags = permissions.flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAccessToken() {
|
public String getAccessToken() {
|
||||||
|
|
|
@ -2,14 +2,22 @@
|
||||||
|
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import pro.gravit.launcher.ClientPermissions;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
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.UserHibernateImpl;
|
||||||
import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl;
|
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.CommonHelper;
|
||||||
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
import java.nio.file.Paths;
|
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 driver;
|
||||||
public String url;
|
public String url;
|
||||||
public String username;
|
public String username;
|
||||||
|
@ -42,4 +50,72 @@ public void init(LaunchServer server) {
|
||||||
else
|
else
|
||||||
init.run();
|
init.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Command> getCommands() {
|
||||||
|
Map<String, Command> 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package pro.gravit.launchserver.socket.response.admin;
|
package pro.gravit.launchserver.socket.response.admin;
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import pro.gravit.launcher.ClientPermissions;
|
||||||
import pro.gravit.launcher.events.request.LogEvent;
|
import pro.gravit.launcher.events.request.LogEvent;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||||
|
@ -20,7 +21,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
sendError("Access denied");
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!client.permissions.canAdmin) {
|
if (!client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) {
|
||||||
sendError("Access denied");
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package pro.gravit.launchserver.socket.response.admin;
|
package pro.gravit.launchserver.socket.response.admin;
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import pro.gravit.launcher.ClientPermissions;
|
||||||
import pro.gravit.launcher.events.request.ExecCommandRequestEvent;
|
import pro.gravit.launcher.events.request.ExecCommandRequestEvent;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||||
|
@ -15,7 +16,7 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
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");
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package pro.gravit.launchserver.socket.response.auth;
|
package pro.gravit.launchserver.socket.response.auth;
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import pro.gravit.launcher.ClientPermissions;
|
||||||
import pro.gravit.launcher.events.RequestEvent;
|
import pro.gravit.launcher.events.RequestEvent;
|
||||||
import pro.gravit.launcher.events.request.ExitRequestEvent;
|
import pro.gravit.launcher.events.request.ExitRequestEvent;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
@ -17,7 +18,7 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
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");
|
sendError("Permissions denied");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package pro.gravit.launchserver.socket.response.auth;
|
package pro.gravit.launchserver.socket.response.auth;
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import pro.gravit.launcher.ClientPermissions;
|
||||||
import pro.gravit.launchserver.dao.User;
|
import pro.gravit.launchserver.dao.User;
|
||||||
import pro.gravit.launchserver.dao.impl.UserHibernateImpl;
|
import pro.gravit.launchserver.dao.impl.UserHibernateImpl;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
@ -21,7 +22,7 @@ public class RegisterResponse extends SimpleResponse {
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
byte[] normalHash = registerHash(login, server.runtime.registerApiKey);
|
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");
|
sendError("Hash invalid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package pro.gravit.launchserver.socket.response.auth;
|
package pro.gravit.launchserver.socket.response.auth;
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import pro.gravit.launcher.ClientPermissions;
|
||||||
import pro.gravit.launcher.events.request.SetPasswordRequestEvent;
|
import pro.gravit.launcher.events.request.SetPasswordRequestEvent;
|
||||||
import pro.gravit.launchserver.dao.User;
|
import pro.gravit.launchserver.dao.User;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
@ -26,7 +27,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
sendError("You not authorized");
|
sendError("You not authorized");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (username != null && !client.permissions.canAdmin) {
|
if (username != null && !client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) {
|
||||||
sendError("You not admin");
|
sendError("You not admin");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package pro.gravit.launcher;
|
package pro.gravit.launcher;
|
||||||
|
|
||||||
import pro.gravit.launcher.client.ClientLauncher;
|
|
||||||
import pro.gravit.launcher.client.ClientModuleManager;
|
import pro.gravit.launcher.client.ClientModuleManager;
|
||||||
import pro.gravit.launcher.client.DirBridge;
|
import pro.gravit.launcher.client.DirBridge;
|
||||||
import pro.gravit.launcher.utils.DirWatcher;
|
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.graphics", builder);
|
||||||
tryAddModule(findPath, "javafx.fxml", builder);
|
tryAddModule(findPath, "javafx.fxml", builder);
|
||||||
tryAddModule(findPath, "javafx.controls", builder);
|
tryAddModule(findPath, "javafx.controls", builder);
|
||||||
|
boolean useSwing = tryAddModule(findPath, "javafx.swing", builder);
|
||||||
String modulePath = builder.toString();
|
String modulePath = builder.toString();
|
||||||
if (!modulePath.isEmpty()) {
|
if (!modulePath.isEmpty()) {
|
||||||
args.add("--add-modules");
|
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("--module-path");
|
||||||
args.add(modulePath);
|
args.add(modulePath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
import pro.gravit.launcher.client.events.ClientEngineInitPhase;
|
import pro.gravit.launcher.client.events.ClientEngineInitPhase;
|
||||||
import pro.gravit.launcher.client.events.ClientExitPhase;
|
import pro.gravit.launcher.client.events.ClientExitPhase;
|
||||||
import pro.gravit.launcher.client.events.ClientPreGuiPhase;
|
import pro.gravit.launcher.client.events.ClientPreGuiPhase;
|
||||||
|
import pro.gravit.launcher.guard.LauncherGuardInterface;
|
||||||
import pro.gravit.launcher.guard.LauncherGuardManager;
|
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.NoRuntimeProvider;
|
||||||
import pro.gravit.launcher.gui.RuntimeProvider;
|
import pro.gravit.launcher.gui.RuntimeProvider;
|
||||||
import pro.gravit.launcher.managers.ClientGsonManager;
|
import pro.gravit.launcher.managers.ClientGsonManager;
|
||||||
import pro.gravit.launcher.managers.ClientHookManager;
|
|
||||||
import pro.gravit.launcher.managers.ConsoleManager;
|
import pro.gravit.launcher.managers.ConsoleManager;
|
||||||
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
||||||
import pro.gravit.launcher.request.Request;
|
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 final AtomicBoolean IS_CLIENT = new AtomicBoolean(false);
|
||||||
public static ClientLauncherProcess.ClientParams clientParams;
|
public static ClientLauncherProcess.ClientParams clientParams;
|
||||||
|
public static LauncherGuardInterface guard;
|
||||||
|
|
||||||
public static void checkClass(Class<?> clazz) throws SecurityException {
|
public static void checkClass(Class<?> clazz) throws SecurityException {
|
||||||
LauncherTrustManager trustManager = Launcher.getConfig().trustManager;
|
LauncherTrustManager trustManager = Launcher.getConfig().trustManager;
|
||||||
|
@ -146,11 +149,11 @@ private LauncherEngine() {
|
||||||
|
|
||||||
public void start(String... args) throws Throwable {
|
public void start(String... args) throws Throwable {
|
||||||
//Launcher.modulesManager = new ClientModuleManager(this);
|
//Launcher.modulesManager = new ClientModuleManager(this);
|
||||||
|
LauncherEngine.guard = tryGetStdGuard();
|
||||||
ClientPreGuiPhase event = new ClientPreGuiPhase(null);
|
ClientPreGuiPhase event = new ClientPreGuiPhase(null);
|
||||||
LauncherEngine.modulesManager.invokeEvent(event);
|
LauncherEngine.modulesManager.invokeEvent(event);
|
||||||
runtimeProvider = event.runtimeProvider;
|
runtimeProvider = event.runtimeProvider;
|
||||||
if (runtimeProvider == null) runtimeProvider = new NoRuntimeProvider();
|
if (runtimeProvider == null) runtimeProvider = new NoRuntimeProvider();
|
||||||
ClientHookManager.initGuiHook.hook(runtimeProvider);
|
|
||||||
runtimeProvider.init(false);
|
runtimeProvider.init(false);
|
||||||
//runtimeProvider.preLoad();
|
//runtimeProvider.preLoad();
|
||||||
if (Request.service == null) {
|
if (Request.service == null) {
|
||||||
|
@ -186,6 +189,18 @@ public void start(String... args) throws Throwable {
|
||||||
runtimeProvider.run(args);
|
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() {
|
public static LauncherEngine clientInstance() {
|
||||||
return new LauncherEngine();
|
return new LauncherEngine();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,6 @@ public class AuthService {
|
||||||
public static ClientProfile profile;
|
public static ClientProfile profile;
|
||||||
|
|
||||||
public static boolean isAdmin() {
|
public static boolean isAdmin() {
|
||||||
return permissions.canAdmin;
|
return permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN);
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isServer() {
|
|
||||||
return permissions.canServer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<Path> {
|
|
||||||
private final Stream.Builder<Path> result;
|
|
||||||
|
|
||||||
private ClassPathFileVisitor(Stream.Builder<Path> 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<PosixFilePermission> 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<String> 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<String> 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<String> 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<String> 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<String> 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<Path> 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<Path> resolveClassPathList(Path clientDir, String... classPath) throws IOException {
|
|
||||||
return resolveClassPathStream(clientDir, classPath).collect(Collectors.toCollection(LinkedList::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Stream<Path> resolveClassPathStream(Path clientDir, String... classPath) throws IOException {
|
|
||||||
Stream.Builder<Path> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<String> args = new LinkedList<>();
|
|
||||||
public String pathLauncher;
|
|
||||||
public ProcessBuilder builder;
|
|
||||||
public Process process;
|
|
||||||
public ClientProfile clientProfile;
|
|
||||||
public PlayerProfile playerProfile;
|
|
||||||
public ClientLauncher.Params params;
|
|
||||||
}
|
|
|
@ -6,9 +6,7 @@
|
||||||
import pro.gravit.launcher.LauncherEngine;
|
import pro.gravit.launcher.LauncherEngine;
|
||||||
import pro.gravit.launcher.api.AuthService;
|
import pro.gravit.launcher.api.AuthService;
|
||||||
import pro.gravit.launcher.api.ClientService;
|
import pro.gravit.launcher.api.ClientService;
|
||||||
import pro.gravit.launcher.client.events.ClientLaunchPhase;
|
import pro.gravit.launcher.client.events.client.*;
|
||||||
import pro.gravit.launcher.client.events.ClientLauncherInitPhase;
|
|
||||||
import pro.gravit.launcher.client.events.ClientLauncherPostInitPhase;
|
|
||||||
import pro.gravit.launcher.guard.LauncherGuardManager;
|
import pro.gravit.launcher.guard.LauncherGuardManager;
|
||||||
import pro.gravit.launcher.hasher.FileNameMatcher;
|
import pro.gravit.launcher.hasher.FileNameMatcher;
|
||||||
import pro.gravit.launcher.hasher.HashedDir;
|
import pro.gravit.launcher.hasher.HashedDir;
|
||||||
|
@ -34,7 +32,6 @@
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.SimpleFileVisitor;
|
import java.nio.file.SimpleFileVisitor;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -59,6 +56,10 @@ private static ClientLauncherProcess.ClientParams readParams(SocketAddress addre
|
||||||
public static void main(String[] args) throws Throwable {
|
public static void main(String[] args) throws Throwable {
|
||||||
LauncherEngine.IS_CLIENT.set(true);
|
LauncherEngine.IS_CLIENT.set(true);
|
||||||
LauncherEngine engine = LauncherEngine.clientInstance();
|
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(LauncherEngine.class);
|
||||||
LauncherEngine.checkClass(LauncherAgent.class);
|
LauncherEngine.checkClass(LauncherAgent.class);
|
||||||
LauncherEngine.checkClass(ClientLauncherEntryPoint.class);
|
LauncherEngine.checkClass(ClientLauncherEntryPoint.class);
|
||||||
|
@ -68,10 +69,6 @@ public static void main(String[] args) throws Throwable {
|
||||||
initGson(LauncherEngine.modulesManager);
|
initGson(LauncherEngine.modulesManager);
|
||||||
LauncherEngine.verifyNoAgent();
|
LauncherEngine.verifyNoAgent();
|
||||||
LauncherEngine.modulesManager.invokeEvent(new PreConfigPhase());
|
LauncherEngine.modulesManager.invokeEvent(new PreConfigPhase());
|
||||||
JVMHelper.verifySystemProperties(ClientLauncherEntryPoint.class, true);
|
|
||||||
EnvHelper.checkDangerousParams();
|
|
||||||
JVMHelper.checkStackTrace(ClientLauncherEntryPoint.class);
|
|
||||||
LogHelper.printVersion("Client Launcher");
|
|
||||||
engine.readKeys();
|
engine.readKeys();
|
||||||
LauncherGuardManager.initGuard(true);
|
LauncherGuardManager.initGuard(true);
|
||||||
LogHelper.debug("Reading ClientLauncher params");
|
LogHelper.debug("Reading ClientLauncher params");
|
||||||
|
@ -82,7 +79,7 @@ public static void main(String[] args) throws Throwable {
|
||||||
LauncherEngine.clientParams = params;
|
LauncherEngine.clientParams = params;
|
||||||
Request.setSession(params.session);
|
Request.setSession(params.session);
|
||||||
checkJVMBitsAndVersion();
|
checkJVMBitsAndVersion();
|
||||||
LauncherEngine.modulesManager.invokeEvent(new ClientLauncherInitPhase(null));
|
LauncherEngine.modulesManager.invokeEvent(new ClientProcessInitPhase(engine, params));
|
||||||
|
|
||||||
Path clientDir = Paths.get(params.clientDir);
|
Path clientDir = Paths.get(params.clientDir);
|
||||||
Path assetDir = Paths.get(params.assetDir);
|
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());
|
classLoader = new ClientClassLoader(classpath.toArray(new URL[0]), ClassLoader.getSystemClassLoader());
|
||||||
Thread.currentThread().setContextClassLoader(classLoader);
|
Thread.currentThread().setContextClassLoader(classLoader);
|
||||||
classLoader.nativePath = clientDir.resolve("natives").toString();
|
classLoader.nativePath = clientDir.resolve("natives").toString();
|
||||||
|
LauncherEngine.modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(engine, classLoader, profile));
|
||||||
// Start client with WatchService monitoring
|
// Start client with WatchService monitoring
|
||||||
boolean digest = !profile.isUpdateFastCheck();
|
boolean digest = !profile.isUpdateFastCheck();
|
||||||
LogHelper.debug("Restore sessions");
|
LogHelper.debug("Restore sessions");
|
||||||
|
@ -127,6 +125,7 @@ public static void main(String[] args) throws Throwable {
|
||||||
classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL());
|
classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL());
|
||||||
//classForName(classLoader, "com.google.common.collect.ForwardingMultimap");
|
//classForName(classLoader, "com.google.common.collect.ForwardingMultimap");
|
||||||
ClientService.baseURLs = classLoader.getURLs();
|
ClientService.baseURLs = classLoader.getURLs();
|
||||||
|
LauncherEngine.modulesManager.invokeEvent(new ClientProcessReadyEvent(engine, params));
|
||||||
LogHelper.debug("Starting JVM and client WatchService");
|
LogHelper.debug("Starting JVM and client WatchService");
|
||||||
FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher();
|
FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher();
|
||||||
FileNameMatcher clientMatcher = profile.getClientUpdateMatcher();
|
FileNameMatcher clientMatcher = profile.getClientUpdateMatcher();
|
||||||
|
@ -144,6 +143,7 @@ public static void main(String[] args) throws Throwable {
|
||||||
CommonHelper.newThread("Client Directory Watcher", true, clientWatcher).start();
|
CommonHelper.newThread("Client Directory Watcher", true, clientWatcher).start();
|
||||||
verifyHDir(assetDir, params.assetHDir, assetMatcher, digest);
|
verifyHDir(assetDir, params.assetHDir, assetMatcher, digest);
|
||||||
verifyHDir(clientDir, params.clientHDir, clientMatcher, digest);
|
verifyHDir(clientDir, params.clientHDir, clientMatcher, digest);
|
||||||
|
LauncherEngine.modulesManager.invokeEvent(new ClientProcessLaunchEvent(engine, params));
|
||||||
launch(profile, params);
|
launch(profile, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,6 +244,7 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa
|
||||||
LogHelper.info("ClassLoader URL: %s", u.toString());
|
LogHelper.info("ClassLoader URL: %s", u.toString());
|
||||||
}
|
}
|
||||||
FMLPatcher.apply();
|
FMLPatcher.apply();
|
||||||
|
LauncherEngine.modulesManager.invokeEvent(new ClientProcessPreInvokeMainClassEvent(params, profile, args));
|
||||||
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)).asFixedArity();
|
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)).asFixedArity();
|
||||||
Launcher.LAUNCHED.set(true);
|
Launcher.LAUNCHED.set(true);
|
||||||
JVMHelper.fullGC();
|
JVMHelper.fullGC();
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
package pro.gravit.launcher.client;
|
package pro.gravit.launcher.client;
|
||||||
|
|
||||||
import pro.gravit.launcher.Launcher;
|
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.hasher.HashedDir;
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
import pro.gravit.launcher.profiles.PlayerProfile;
|
import pro.gravit.launcher.profiles.PlayerProfile;
|
||||||
|
@ -10,10 +15,7 @@
|
||||||
import pro.gravit.utils.Version;
|
import pro.gravit.utils.Version;
|
||||||
import pro.gravit.utils.helper.*;
|
import pro.gravit.utils.helper.*;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
@ -24,9 +26,9 @@
|
||||||
public class ClientLauncherProcess {
|
public class ClientLauncherProcess {
|
||||||
private transient Process process;
|
private transient Process process;
|
||||||
private final transient Boolean[] waitWriteParams = new Boolean[] {false};
|
private final transient Boolean[] waitWriteParams = new Boolean[] {false};
|
||||||
public final Path executeFile;
|
public Path executeFile;
|
||||||
public final Path workDir;
|
public Path workDir;
|
||||||
public final Path javaDir;
|
public Path javaDir;
|
||||||
public final ClientParams params = new ClientParams();
|
public final ClientParams params = new ClientParams();
|
||||||
public final List<String> jvmArgs = new LinkedList<>();
|
public final List<String> jvmArgs = new LinkedList<>();
|
||||||
public final List<String> systemClientArgs = new LinkedList<>();
|
public final List<String> systemClientArgs = new LinkedList<>();
|
||||||
|
@ -42,18 +44,24 @@ public ClientLauncherProcess(Path executeFile, Path workDir, Path javaDir, Strin
|
||||||
this.mainClass = mainClass;
|
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,
|
public ClientLauncherProcess(Path clientDir, Path assetDir,
|
||||||
ClientProfile profile, PlayerProfile playerProfile, String accessToken,
|
ClientProfile profile, PlayerProfile playerProfile, String accessToken,
|
||||||
HashedDir clientHDir, HashedDir assetHDir, HashedDir jvmHDir) {
|
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,
|
ClientProfile profile, PlayerProfile playerProfile, String accessToken,
|
||||||
HashedDir clientHDir, HashedDir assetHDir, HashedDir jvmHDir) {
|
HashedDir clientHDir, HashedDir assetHDir, HashedDir jvmHDir) {
|
||||||
this.executeFile = LauncherGuardManager.getGuardJavaBinPath();
|
|
||||||
this.workDir = clientDir.toAbsolutePath();
|
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.mainClass = ClientLauncherEntryPoint.class.getName();
|
||||||
this.params.clientDir = this.workDir.toString();
|
this.params.clientDir = this.workDir.toString();
|
||||||
this.params.resourcePackDir = resourcePackDir.toAbsolutePath().toString();
|
this.params.resourcePackDir = resourcePackDir.toAbsolutePath().toString();
|
||||||
|
@ -78,6 +86,7 @@ private void applyClientProfile()
|
||||||
this.jvmArgs.add("-Xmx" + params.ram + 'M');
|
this.jvmArgs.add("-Xmx" + params.ram + 'M');
|
||||||
}
|
}
|
||||||
this.params.session = Request.getSession();
|
this.params.session = Request.getSession();
|
||||||
|
LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderCreateEvent(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,6 +137,18 @@ public void addClientArgs(Collection<String> 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<String> args) {
|
public void addClientLegacyArgs(Collection<String> args) {
|
||||||
args.add(playerProfile.username);
|
args.add(playerProfile.username);
|
||||||
args.add(accessToken);
|
args.add(accessToken);
|
||||||
|
@ -151,7 +172,7 @@ private void addModernClientArgs(Collection<String> args) {
|
||||||
if (version.compareTo(ClientProfile.Version.MC1710) >= 0) {
|
if (version.compareTo(ClientProfile.Version.MC1710) >= 0) {
|
||||||
// Add user properties
|
// Add user properties
|
||||||
Collections.addAll(args, "--userType", "mojang");
|
Collections.addAll(args, "--userType", "mojang");
|
||||||
ClientLauncher.ClientUserProperties properties = new ClientLauncher.ClientUserProperties();
|
ClientUserProperties properties = new ClientUserProperties();
|
||||||
if (playerProfile.skin != null) {
|
if (playerProfile.skin != null) {
|
||||||
properties.skinURL = new String[]{playerProfile.skin.url};
|
properties.skinURL = new String[]{playerProfile.skin.url};
|
||||||
properties.skinDigest = new String[]{SecurityHelper.toHex(playerProfile.skin.digest)};
|
properties.skinDigest = new String[]{SecurityHelper.toHex(playerProfile.skin.digest)};
|
||||||
|
@ -193,6 +214,8 @@ private void addModernClientArgs(Collection<String> args) {
|
||||||
}
|
}
|
||||||
public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
||||||
if(isStarted) throw new IllegalStateException("Process already started");
|
if(isStarted) throw new IllegalStateException("Process already started");
|
||||||
|
if(LauncherEngine.guard != null) LauncherEngine.guard.applyGuardParams(this);
|
||||||
|
LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderPreLaunchEvent(this));
|
||||||
List<String> processArgs = new LinkedList<>();
|
List<String> processArgs = new LinkedList<>();
|
||||||
processArgs.add(executeFile.toString());
|
processArgs.add(executeFile.toString());
|
||||||
processArgs.addAll(jvmArgs);
|
processArgs.addAll(jvmArgs);
|
||||||
|
@ -212,6 +235,7 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
||||||
LogHelper.debug("Commandline: %s", Arrays.toString(processArgs.toArray()));
|
LogHelper.debug("Commandline: %s", Arrays.toString(processArgs.toArray()));
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(processArgs);
|
ProcessBuilder processBuilder = new ProcessBuilder(processArgs);
|
||||||
EnvHelper.addEnv(processBuilder);
|
EnvHelper.addEnv(processBuilder);
|
||||||
|
processBuilder.environment().put("JAVA_HOME", javaDir.toAbsolutePath().toString());
|
||||||
processBuilder.environment().putAll(systemEnv);
|
processBuilder.environment().putAll(systemEnv);
|
||||||
processBuilder.directory(workDir.toFile());
|
processBuilder.directory(workDir.toFile());
|
||||||
processBuilder.inheritIO();
|
processBuilder.inheritIO();
|
||||||
|
@ -220,6 +244,7 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
||||||
processBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE);
|
processBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE);
|
||||||
}
|
}
|
||||||
process = processBuilder.start();
|
process = processBuilder.start();
|
||||||
|
LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderLaunchedEvent(this));
|
||||||
isStarted = true;
|
isStarted = true;
|
||||||
}
|
}
|
||||||
public void runWriteParams(SocketAddress address) throws IOException
|
public void runWriteParams(SocketAddress address) throws IOException
|
||||||
|
@ -242,6 +267,7 @@ public void runWriteParams(SocketAddress address) throws IOException
|
||||||
params.javaHDir.write(output);
|
params.javaHDir.write(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderParamsWrittedEvent(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Process getProcess() {
|
public Process getProcess() {
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public final class ServerPinger {
|
public final class ServerPinger {
|
||||||
private final JsonParser parser = new JsonParser();
|
|
||||||
|
|
||||||
public static final class Result {
|
public static final class Result {
|
||||||
|
|
||||||
|
@ -184,7 +183,7 @@ private Result modernPing(HInput input, HOutput output) throws IOException {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse JSON response
|
// Parse JSON response
|
||||||
JsonObject object = parser.parse(response).getAsJsonObject();
|
JsonObject object = JsonParser.parseString(response).getAsJsonObject();
|
||||||
JsonObject playersObject = object.get("players").getAsJsonObject();
|
JsonObject playersObject = object.get("players").getAsJsonObject();
|
||||||
int online = playersObject.get("online").getAsInt();
|
int online = playersObject.get("online").getAsInt();
|
||||||
int max = playersObject.get("max").getAsInt();
|
int max = playersObject.get("max").getAsInt();
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<String> args;
|
||||||
|
|
||||||
|
public ClientProcessPreInvokeMainClassEvent(ClientLauncherProcess.ClientParams params, ClientProfile profile, Collection<String> args) {
|
||||||
|
this.params = params;
|
||||||
|
this.profile = profile;
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +1,9 @@
|
||||||
package pro.gravit.launcher.guard;
|
package pro.gravit.launcher.guard;
|
||||||
|
|
||||||
import pro.gravit.launcher.client.ClientLauncherContext;
|
import pro.gravit.launcher.client.ClientLauncherProcess;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
public interface LauncherGuardInterface {
|
public interface LauncherGuardInterface {
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
Path getJavaBinPath();
|
void applyGuardParams(ClientLauncherProcess process);
|
||||||
|
|
||||||
int getClientJVMBits();
|
|
||||||
|
|
||||||
void init(boolean clientInstance);
|
|
||||||
|
|
||||||
void addCustomParams(ClientLauncherContext context);
|
|
||||||
|
|
||||||
void addCustomEnv(ClientLauncherContext context);
|
|
||||||
|
|
||||||
void setProtectToken(String token);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,31 +9,5 @@ public class LauncherGuardManager {
|
||||||
public static LauncherGuardInterface guard;
|
public static LauncherGuardInterface guard;
|
||||||
|
|
||||||
public static void initGuard(boolean clientInstance) {
|
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +1,6 @@
|
||||||
package pro.gravit.launcher.guard;
|
package pro.gravit.launcher.guard;
|
||||||
|
|
||||||
import pro.gravit.launcher.client.ClientLauncherContext;
|
import pro.gravit.launcher.client.ClientLauncherProcess;
|
||||||
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;
|
|
||||||
|
|
||||||
public class LauncherNoGuard implements LauncherGuardInterface {
|
public class LauncherNoGuard implements LauncherGuardInterface {
|
||||||
@Override
|
@Override
|
||||||
|
@ -16,33 +9,7 @@ public String getName() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getJavaBinPath() {
|
public void applyGuardParams(ClientLauncherProcess process) {
|
||||||
return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
//IGNORED
|
||||||
}
|
|
||||||
|
|
||||||
@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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<String, String> 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +1,30 @@
|
||||||
package pro.gravit.launcher.guard;
|
package pro.gravit.launcher.guard;
|
||||||
|
|
||||||
import pro.gravit.launcher.Launcher;
|
import pro.gravit.launcher.Launcher;
|
||||||
import pro.gravit.launcher.LauncherConfig;
|
import pro.gravit.launcher.client.ClientLauncherProcess;
|
||||||
import pro.gravit.launcher.client.ClientLauncherContext;
|
|
||||||
import pro.gravit.launcher.client.DirBridge;
|
import pro.gravit.launcher.client.DirBridge;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
|
||||||
import pro.gravit.utils.helper.JVMHelper;
|
import pro.gravit.utils.helper.JVMHelper;
|
||||||
import pro.gravit.utils.helper.UnpackHelper;
|
import pro.gravit.utils.helper.UnpackHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
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 class LauncherWrapperGuard implements LauncherGuardInterface {
|
||||||
|
|
||||||
public String protectToken;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "wrapper";
|
return "wrapper";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getJavaBinPath() {
|
public void applyGuardParams(ClientLauncherProcess process) {
|
||||||
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) {
|
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) {
|
||||||
String projectName = Launcher.getConfig().projectName;
|
String projectName = Launcher.getConfig().projectName;
|
||||||
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
|
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
|
||||||
return DirBridge.getGuardDir().resolve(wrapperUnpackName);
|
process.executeFile = DirBridge.getGuardDir().resolve(wrapperUnpackName);
|
||||||
} else
|
}
|
||||||
return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public LauncherWrapperGuard() {
|
||||||
public int getClientJVMBits() {
|
|
||||||
return JVMHelper.JVM_BITS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(boolean clientInstance) {
|
|
||||||
try {
|
try {
|
||||||
String wrapperName = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe";
|
String wrapperName = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe";
|
||||||
String projectName = Launcher.getConfig().projectName;
|
String projectName = Launcher.getConfig().projectName;
|
||||||
|
@ -51,25 +36,4 @@ public void init(boolean clientInstance) {
|
||||||
throw new SecurityException(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<String, String> 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<RuntimeProvider> initGuiHook = new HookSet<>();
|
|
||||||
public static final HookSet<HInput> paramsInputHook = new HookSet<>();
|
|
||||||
public static final HookSet<HOutput> paramsOutputHook = new HookSet<>();
|
|
||||||
|
|
||||||
public static final HookSet<ClientLauncherContext> clientLaunchHook = new HookSet<>();
|
|
||||||
public static final HookSet<ClientLauncherContext> clientLaunchFinallyHook = new HookSet<>();
|
|
||||||
|
|
||||||
public static final BiHookSet<ClientLauncherContext, ProcessBuilder> preStartHook = new BiHookSet<>();
|
|
||||||
public static final BiHookSet<ClientLauncherContext, ProcessBuilder> postStartHook = new BiHookSet<>();
|
|
||||||
}
|
|
|
@ -8,73 +8,104 @@
|
||||||
|
|
||||||
public class ClientPermissions {
|
public class ClientPermissions {
|
||||||
public static final ClientPermissions DEFAULT = new ClientPermissions();
|
public static final ClientPermissions DEFAULT = new ClientPermissions();
|
||||||
@LauncherNetworkAPI
|
public long permissions;
|
||||||
public boolean canAdmin;
|
public long flags;
|
||||||
@LauncherNetworkAPI
|
public enum PermissionConsts
|
||||||
public boolean canServer;
|
{
|
||||||
@LauncherNetworkAPI
|
ADMIN(0x01),
|
||||||
public final boolean canUSR1;
|
MANAGEMENT(0x02);
|
||||||
@LauncherNetworkAPI
|
public final long mask;
|
||||||
public final boolean canUSR2;
|
|
||||||
@LauncherNetworkAPI
|
PermissionConsts(long mask) {
|
||||||
public final boolean canUSR3;
|
this.mask = mask;
|
||||||
@LauncherNetworkAPI
|
}
|
||||||
public boolean canBot;
|
}
|
||||||
|
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 {
|
public ClientPermissions(HInput input) throws IOException {
|
||||||
this(input.readLong());
|
this(input.readLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientPermissions() {
|
public ClientPermissions() {
|
||||||
canAdmin = false;
|
|
||||||
canServer = false;
|
|
||||||
canUSR1 = false;
|
|
||||||
canUSR2 = false;
|
|
||||||
canUSR3 = false;
|
|
||||||
canBot = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientPermissions(long data) {
|
public ClientPermissions(long permissions) {
|
||||||
canAdmin = (data & (1)) != 0;
|
this.permissions = permissions;
|
||||||
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, long flags) {
|
||||||
|
this.permissions = permissions;
|
||||||
|
this.flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
public long toLong() {
|
public long toLong() {
|
||||||
long result = 0;
|
return permissions;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClientPermissions getSuperuserAccount() {
|
public static ClientPermissions getSuperuserAccount() {
|
||||||
ClientPermissions perm = new ClientPermissions();
|
ClientPermissions perm = new ClientPermissions();
|
||||||
perm.canServer = true;
|
|
||||||
perm.canAdmin = true;
|
|
||||||
return perm;
|
return perm;
|
||||||
}
|
}
|
||||||
|
@Deprecated
|
||||||
public void write(HOutput output) throws IOException {
|
public void write(HOutput output) throws IOException {
|
||||||
output.writeLong(toLong());
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new StringJoiner(", ", ClientPermissions.class.getSimpleName() + "[", "]")
|
return String.format("permissions %d | flags %d", permissions, flags);
|
||||||
.add("canAdmin=" + canAdmin)
|
|
||||||
.add("canServer=" + canServer)
|
|
||||||
.add("canUSR1=" + canUSR1)
|
|
||||||
.add("canUSR2=" + canUSR2)
|
|
||||||
.add("canUSR3=" + canUSR3)
|
|
||||||
.add("canBot=" + canBot)
|
|
||||||
.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import pro.gravit.launcher.hasher.HashedDir;
|
import pro.gravit.launcher.hasher.HashedDir;
|
||||||
import pro.gravit.launcher.profiles.optional.OptionalDepend;
|
import pro.gravit.launcher.profiles.optional.OptionalDepend;
|
||||||
import pro.gravit.launcher.profiles.optional.OptionalFile;
|
import pro.gravit.launcher.profiles.optional.OptionalFile;
|
||||||
|
import pro.gravit.launcher.profiles.optional.OptionalTrigger;
|
||||||
import pro.gravit.launcher.profiles.optional.OptionalType;
|
import pro.gravit.launcher.profiles.optional.OptionalType;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
import pro.gravit.utils.helper.VerifyHelper;
|
import pro.gravit.utils.helper.VerifyHelper;
|
||||||
|
@ -444,6 +445,16 @@ public void verify() {
|
||||||
if (s == null)
|
if (s == null)
|
||||||
throw new IllegalArgumentException(String.format("Found null entry in updateOptional.%s.dependenciesFile", f.name));
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,10 @@ public void registerEventHandler(EventHandler handler)
|
||||||
{
|
{
|
||||||
eventHandlers.add(handler);
|
eventHandlers.add(handler);
|
||||||
}
|
}
|
||||||
|
public void unregisterEventHandler(EventHandler handler)
|
||||||
|
{
|
||||||
|
eventHandlers.remove(handler);
|
||||||
|
}
|
||||||
public<T extends WebSocketEvent> void processEventHandlers(T event)
|
public<T extends WebSocketEvent> void processEventHandlers(T event)
|
||||||
{
|
{
|
||||||
for(EventHandler handler : eventHandlers)
|
for(EventHandler handler : eventHandlers)
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class YggdrasilMinecraftSessionService extends BaseMinecraftSessionService {
|
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 final boolean NO_TEXTURES = Boolean.parseBoolean("launcher.com.mojang.authlib.noTextures");
|
||||||
|
|
||||||
public static void fillTextureProperties(GameProfile profile, PlayerProfile pp) {
|
public static void fillTextureProperties(GameProfile profile, PlayerProfile pp) {
|
||||||
|
@ -62,7 +61,7 @@ private static void getTexturesMojang(Map<MinecraftProfileTexture.Type, Minecraf
|
||||||
JsonObject texturesJSON;
|
JsonObject texturesJSON;
|
||||||
try {
|
try {
|
||||||
byte[] decoded = Base64.getDecoder().decode(texturesBase64);
|
byte[] decoded = Base64.getDecoder().decode(texturesBase64);
|
||||||
texturesJSON = JSON_PARSER.parse(new String(decoded, IOHelper.UNICODE_CHARSET)).getAsJsonObject().getAsJsonObject("textures");
|
texturesJSON = JsonParser.parseString(new String(decoded, IOHelper.UNICODE_CHARSET)).getAsJsonObject().getAsJsonObject("textures");
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
LogHelper.error("Could not decode textures payload, Username: '%s', UUID: '%s'", profile.getName(), profile.getUUID());
|
LogHelper.error("Could not decode textures payload, Username: '%s', UUID: '%s'", profile.getName(), profile.getUUID());
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
public final class HTTPRequest {
|
public final class HTTPRequest {
|
||||||
private static final int TIMEOUT = 10000;
|
private static final int TIMEOUT = 10000;
|
||||||
private static final JsonParser parser = new JsonParser();
|
|
||||||
|
|
||||||
public static JsonElement jsonRequest(JsonElement request, URL url) throws IOException {
|
public static JsonElement jsonRequest(JsonElement request, URL url) throws IOException {
|
||||||
return jsonRequest(request, "POST", url);
|
return jsonRequest(request, "POST", url);
|
||||||
|
@ -42,7 +41,7 @@ public static JsonElement jsonRequest(JsonElement request, String method, URL ur
|
||||||
else
|
else
|
||||||
reader = new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8);
|
reader = new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8);
|
||||||
try {
|
try {
|
||||||
return parser.parse(reader);
|
return JsonParser.parseReader(reader);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (200 > statusCode || statusCode > 300) {
|
if (200 > statusCode || statusCode > 300) {
|
||||||
LogHelper.error("JsonRequest failed. Server response code %d", statusCode);
|
LogHelper.error("JsonRequest failed. Server response code %d", statusCode);
|
||||||
|
|
|
@ -15,9 +15,9 @@ public final class Version {
|
||||||
public final Type release;
|
public final Type release;
|
||||||
public static final int MAJOR = 5;
|
public static final int MAJOR = 5;
|
||||||
public static final int MINOR = 1;
|
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 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) {
|
public Version(int major, int minor, int patch) {
|
||||||
|
|
|
@ -259,7 +259,7 @@ public static final class Config {
|
||||||
public String login;
|
public String login;
|
||||||
public String[] args;
|
public String[] args;
|
||||||
public String password;
|
public String password;
|
||||||
public final String auth_id = "";
|
public String auth_id = "";
|
||||||
public LauncherConfig.LauncherEnvironment env;
|
public LauncherConfig.LauncherEnvironment env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
id 'org.openjfx.javafxplugin' version '0.0.7' apply false
|
id 'org.openjfx.javafxplugin' version '0.0.7' apply false
|
||||||
}
|
}
|
||||||
group = 'pro.gravit.launcher'
|
group = 'pro.gravit.launcher'
|
||||||
version = '5.1.2'
|
version = '5.1.3'
|
||||||
|
|
||||||
apply from: 'props.gradle'
|
apply from: 'props.gradle'
|
||||||
|
|
||||||
|
|
2
modules
2
modules
|
@ -1 +1 @@
|
||||||
Subproject commit 2edb2c7259d5a7dba3fa82c503f88a8a0e171840
|
Subproject commit 07e4380ad52c4ef08378b8eb2202d8a1bd3639a2
|
22
props.gradle
22
props.gradle
|
@ -1,18 +1,18 @@
|
||||||
project.ext {
|
project.ext {
|
||||||
verAsm = '7.2'
|
verAsm = '7.3.1'
|
||||||
verNetty = '4.1.43.Final'
|
verNetty = '4.1.48.Final'
|
||||||
verOshiCore = '3.13.0'
|
verOshiCore = '4.5.2'
|
||||||
verJunit = '5.6.0'
|
verJunit = '5.6.1'
|
||||||
verGuavaC = '26.0-jre'
|
verGuavaC = '28.2-jre'
|
||||||
verJansi = '1.18'
|
verJansi = '1.18'
|
||||||
verJline = '3.11.0'
|
verJline = '3.14.0'
|
||||||
verBcprov = '1.46'
|
verBcprov = '1.46'
|
||||||
verGson = '2.8.5'
|
verGson = '2.8.6'
|
||||||
verBcpkix = '1.61'
|
verBcpkix = '1.61'
|
||||||
verSlf4j = '1.7.25'
|
verSlf4j = '1.7.25'
|
||||||
verMySQLConn = '8.0.16'
|
verMySQLConn = '8.0.19'
|
||||||
verPostgreSQLConn = '42.2.6'
|
verPostgreSQLConn = '42.2.11'
|
||||||
verProguard = '6.2.0'
|
verProguard = '6.2.2'
|
||||||
verLaunch4j = '3.12'
|
verLaunch4j = '3.12'
|
||||||
verHibernate = '5.4.9.Final'
|
verHibernate = '5.4.12.Final'
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue