mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-23 00:51:01 +03:00
Merge branch 'release/5.1.2'
This commit is contained in:
commit
39e3dd77de
80 changed files with 1215 additions and 1650 deletions
|
@ -1,51 +1,90 @@
|
||||||
image: docker:latest
|
image: gradle:jdk11
|
||||||
services:
|
|
||||||
- docker:dind
|
|
||||||
|
|
||||||
variables:
|
|
||||||
DOCKER_DRIVER: overlay2
|
|
||||||
CI_VERSION: '6.6.$CI_PIPELINE_IID'
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- test
|
- 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:
|
build:
|
||||||
image: gradle:jdk11
|
|
||||||
stage: build
|
stage: build
|
||||||
before_script:
|
|
||||||
- apt-get -y update
|
|
||||||
- apt-get -y install zip git
|
|
||||||
- export GRADLE_USER_HOME=`pwd`/.gradle
|
|
||||||
- chmod +x gradlew
|
|
||||||
- sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules
|
|
||||||
- git submodule sync
|
|
||||||
- git submodule update --init --recursive
|
|
||||||
script:
|
script:
|
||||||
- ./gradlew assemble
|
- gradle assemble
|
||||||
after_script:
|
after_script:
|
||||||
- mkdir -p artifacts/modules
|
- mkdir -p artifacts/modules
|
||||||
- cd LaunchServer/build/libs/
|
- cd LaunchServer/build/libs/
|
||||||
- zip -r -9 ../../../artifacts/libraries.zip * -x "LaunchServer.jar" -x "LaunchServer-clean.jar"
|
- zip -r -9 ../../../artifacts/libraries.zip * -x "LaunchServer.jar" -x "LaunchServer-clean.jar"
|
||||||
- mv LaunchServer.jar ../../../artifacts/LaunchServer.jar
|
- cp LaunchServer.jar ../../../artifacts/LaunchServer.jar
|
||||||
- cd ../../../ServerWrapper/build/libs
|
- cd ../../../ServerWrapper/build/libs
|
||||||
- mv ServerWrapper.jar ../../../artifacts/ServerWrapper.jar
|
- cp ServerWrapper.jar ../../../artifacts/ServerWrapper.jar
|
||||||
- cd ../../../LauncherAuthlib/build/libs
|
- cd ../../../LauncherAuthlib/build/libs
|
||||||
- mv LauncherAuthlib.jar ../../../artifacts/LauncherAuthlib.jar
|
- cp LauncherAuthlib.jar ../../../artifacts/LauncherAuthlib.jar
|
||||||
- cd ../../../
|
- cd ../../../
|
||||||
- mv modules/*_module/build/libs/*.jar artifacts/modules
|
- cp modules/*_module/build/libs/*.jar artifacts/modules
|
||||||
- mv modules/*_swmodule/build/libs/*.jar artifacts/modules
|
- cp modules/*_swmodule/build/libs/*.jar artifacts/modules
|
||||||
- mv modules/*_lmodule/build/libs/*.jar artifacts/modules
|
- cp modules/*_lmodule/build/libs/*.jar artifacts/modules
|
||||||
cache:
|
cache:
|
||||||
|
key: "$CI_COMMIT_REF_NAME"
|
||||||
paths:
|
paths:
|
||||||
- .gradle
|
- .gradle
|
||||||
|
- LaunchServer/build
|
||||||
|
- Launcher/build
|
||||||
|
- LauncherCore/build
|
||||||
|
- LauncherAPI/build
|
||||||
|
- LauncherAuthlib/build
|
||||||
|
- modules/*_*module/build
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 6 week
|
expire_in: 6 week
|
||||||
paths:
|
paths:
|
||||||
- artifacts
|
- artifacts
|
||||||
|
|
||||||
test:
|
test:
|
||||||
image: gradle:jdk11
|
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- ./gradlew check
|
- 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
|
|
@ -22,16 +22,15 @@
|
||||||
hikari
|
hikari
|
||||||
pack
|
pack
|
||||||
launch4j
|
launch4j
|
||||||
launch4jCJ
|
|
||||||
bundleOnly.extendsFrom bundle
|
bundleOnly.extendsFrom bundle
|
||||||
api.extendsFrom bundle, hikari, pack, launch4jCJ, launch4j
|
api.extendsFrom bundle, hikari, pack, launch4j
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
dependsOn parent.childProjects.Launcher.tasks.build
|
dependsOn parent.childProjects.Launcher.tasks.assemble
|
||||||
from { configurations.pack.collect { it.isDirectory() ? it : zipTree(it) } }
|
from { configurations.pack.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||||
from(parent.childProjects.Launcher.tasks.shadowJar.archivePath)
|
from(parent.childProjects.Launcher.tasks.shadowJar)
|
||||||
from(parent.childProjects.Launcher.tasks.genRuntimeJS.archivePath)
|
from(parent.childProjects.Launcher.tasks.genRuntimeJS)
|
||||||
manifest.attributes("Main-Class": mainClassName,
|
manifest.attributes("Main-Class": mainClassName,
|
||||||
"Premain-Class": mainAgentName,
|
"Premain-Class": mainAgentName,
|
||||||
"Can-Redefine-Classes": "true",
|
"Can-Redefine-Classes": "true",
|
||||||
|
@ -71,23 +70,20 @@ task cleanjar(type: Jar, dependsOn: jar) {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
pack project(':LauncherAPI')
|
pack project(':LauncherAPI')
|
||||||
bundle 'org.ow2.asm:asm-commons:7.3.1'
|
bundle group: 'org.fusesource.jansi', name:'jansi', version: rootProject['verJansi']
|
||||||
bundle 'mysql:mysql-connector-java:8.0.16'
|
bundle group: 'org.jline', name: 'jline', version: rootProject['verJline']
|
||||||
bundle 'org.postgresql:postgresql:42.2.6'
|
bundle group: 'org.jline', name: 'jline-reader', version: rootProject['verJline']
|
||||||
bundle 'org.jline:jline:3.13.1'
|
bundle group: 'org.jline', name: 'jline-terminal', version: rootProject['verJline']
|
||||||
bundle 'org.jline:jline-reader:3.13.1'
|
bundle group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: rootProject['verBcpkix']
|
||||||
bundle 'org.jline:jline-terminal:3.13.1'
|
bundle group: 'org.ow2.asm', name: 'asm-commons', version: rootProject['verAsm']
|
||||||
bundle 'net.sf.proguard:proguard-base:6.2.0'
|
bundle group: 'io.netty', name: 'netty-all', version: rootProject['verNetty']
|
||||||
bundle 'org.fusesource.jansi:jansi:1.18'
|
bundle group: 'org.slf4j', name: 'slf4j-simple', version: rootProject['verSlf4j']
|
||||||
bundle 'commons-io:commons-io:2.6'
|
bundle group: 'org.slf4j', name: 'slf4j-api', version: rootProject['verSlf4j']
|
||||||
bundle 'commons-codec:commons-codec:1.12'
|
bundle group: 'org.hibernate', name: 'hibernate-core', version: rootProject['verHibernate']
|
||||||
bundle 'org.apache.httpcomponents:httpclient:4.5.10'
|
bundle group: 'mysql', name: 'mysql-connector-java', version: rootProject['verMySQLConn']
|
||||||
bundle 'io.netty:netty-all:4.1.43.Final'
|
bundle group: 'org.postgresql', name: 'postgresql', version: rootProject['verPostgreSQLConn']
|
||||||
bundle 'org.hibernate:hibernate-core:5.4.9.Final'
|
bundle group: 'net.sf.proguard', name: 'proguard-base', version: rootProject['verProguard']
|
||||||
bundle 'org.bouncycastle:bcpkix-jdk15on:1.61'
|
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: rootProject['verJunit']
|
||||||
|
|
||||||
bundle 'org.slf4j:slf4j-simple:1.7.25'
|
|
||||||
bundle 'org.slf4j:slf4j-api:1.7.25'
|
|
||||||
|
|
||||||
hikari 'io.micrometer:micrometer-core:1.0.6'
|
hikari 'io.micrometer:micrometer-core:1.0.6'
|
||||||
hikari('com.zaxxer:HikariCP:3.4.1') {
|
hikari('com.zaxxer:HikariCP:3.4.1') {
|
||||||
|
@ -96,25 +92,20 @@ pack project(':LauncherAPI')
|
||||||
exclude group: 'org.slf4j'
|
exclude group: 'org.slf4j'
|
||||||
}
|
}
|
||||||
|
|
||||||
launch4j('net.sf.launch4j:launch4j:3.12') {
|
launch4j('net.sf.launch4j:launch4j:' + rootProject['verLaunch4j']) {
|
||||||
exclude group: 'org.apache.ant'
|
exclude group: 'org.apache.ant'
|
||||||
exclude group: 'net.java.abeille'
|
exclude group: 'net.java.abeille'
|
||||||
exclude group: 'foxtrot'
|
exclude group: 'foxtrot'
|
||||||
exclude group: 'com.jgoodies'
|
exclude group: 'com.jgoodies'
|
||||||
|
exclude group: 'org.slf4j'
|
||||||
}
|
}
|
||||||
|
launch4j('net.sf.launch4j:launch4j:' + rootProject['verLaunch4j'] + ':workdir-win32') { transitive = false }
|
||||||
|
launch4j('net.sf.launch4j:launch4j:' + rootProject['verLaunch4j'] + 'workdir-linux') { transitive = false }
|
||||||
|
|
||||||
launch4jCJ('net.sf.launch4j:launch4j:3.12:workdir-win32') {
|
compileOnlyA group: 'com.google.guava', name: 'guava', version: rootProject['verGuavaC']
|
||||||
exclude group: '*'
|
// Do not update (laggy deps).
|
||||||
}
|
compileOnlyA 'log4j:log4j:1.2.17'
|
||||||
|
|
||||||
launch4jCJ('net.sf.launch4j:launch4j:3.12:workdir-linux') {
|
|
||||||
exclude group: '*'
|
|
||||||
}
|
|
||||||
|
|
||||||
compileOnlyA 'com.google.guava:guava:26.0-jre'
|
|
||||||
compileOnlyA 'log4j:log4j:1.2.17' // Do not update (laggy dep).
|
|
||||||
compileOnlyA 'org.apache.logging.log4j:log4j-core:2.11.2'
|
compileOnlyA 'org.apache.logging.log4j:log4j-core:2.11.2'
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.4.1'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
task hikari(type: Copy) {
|
task hikari(type: Copy) {
|
||||||
|
@ -123,39 +114,25 @@ task hikari(type: Copy) {
|
||||||
from configurations.hikari
|
from configurations.hikari
|
||||||
}
|
}
|
||||||
|
|
||||||
task launch4jM(type: Copy) {
|
task launch4j(type: Copy) {
|
||||||
duplicatesStrategy = 'EXCLUDE'
|
duplicatesStrategy = 'EXCLUDE'
|
||||||
into "$buildDir/libs/libraries/launch4j"
|
into "$buildDir/libs/libraries/launch4j"
|
||||||
from(configurations.launch4jCJ.collect { it.isDirectory() ? it : zipTree(it) })
|
from(configurations.launch4j.collect { it.isDirectory() ? it : ((it.getName().startsWith("launch4j") && it.getName().contains("workdir")) ? zipTree(it) : it) })
|
||||||
includeEmptyDirs false
|
includeEmptyDirs false
|
||||||
eachFile { FileCopyDetails fcp ->
|
eachFile { FileCopyDetails fcp ->
|
||||||
if (fcp.relativePath.pathString.startsWith("launch4j-")) {
|
if (fcp.relativePath.pathString.startsWith("launch4j-") &&
|
||||||
def segments = fcp.relativePath.segments
|
fcp.relativePath.pathString.contains("workdir")) {
|
||||||
def pathSegments = segments[1..-1] as String[]
|
def segments = fcp.relativePath.segments
|
||||||
fcp.relativePath = new RelativePath(!fcp.file.isDirectory(), pathSegments)
|
def pathSegments = segments[1..-1] as String[]
|
||||||
|
fcp.relativePath = new RelativePath(!fcp.file.isDirectory(), pathSegments)
|
||||||
|
} else if (fcp.relativePath.pathString.contains("META-INF")) fcp.exclude()
|
||||||
fcp.mode = 0755
|
fcp.mode = 0755
|
||||||
} else {
|
|
||||||
fcp.exclude()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task launch4jA(type: Copy) {
|
|
||||||
duplicatesStrategy = 'EXCLUDE'
|
|
||||||
into "$buildDir/libs/libraries/launch4j"
|
|
||||||
from(configurations.launch4j)
|
|
||||||
includeEmptyDirs false
|
|
||||||
eachFile { FileCopyDetails fcp ->
|
|
||||||
if (fcp.name.startsWith("launch4j")) {
|
|
||||||
fcp.name = "launch4j.jar"
|
|
||||||
}
|
|
||||||
fcp.mode = 0755
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task dumpLibs(type: Copy) {
|
task dumpLibs(type: Copy) {
|
||||||
duplicatesStrategy = 'EXCLUDE'
|
duplicatesStrategy = 'EXCLUDE'
|
||||||
dependsOn tasks.hikari, tasks.launch4jM, tasks.launch4jA
|
dependsOn tasks.hikari, tasks.launch4j
|
||||||
into "$buildDir/libs/libraries"
|
into "$buildDir/libs/libraries"
|
||||||
from configurations.bundleOnly
|
from configurations.bundleOnly
|
||||||
}
|
}
|
||||||
|
@ -173,14 +150,14 @@ task bundle(type: Zip) {
|
||||||
destinationDirectory = file("$buildDir")
|
destinationDirectory = file("$buildDir")
|
||||||
from(tasks.dumpLibs.destinationDir) { into 'libraries' }
|
from(tasks.dumpLibs.destinationDir) { into 'libraries' }
|
||||||
from(tasks.dumpCompileOnlyLibs.destinationDir) { into 'launcher-libraries-compile' }
|
from(tasks.dumpCompileOnlyLibs.destinationDir) { into 'launcher-libraries-compile' }
|
||||||
from tasks.jar.archivePath
|
from(tasks.jar)
|
||||||
from(parent.childProjects.Launcher.tasks.dumpLibs) { into 'launcher-libraries' }
|
from(parent.childProjects.Launcher.tasks.dumpLibs) { into 'launcher-libraries' }
|
||||||
}
|
}
|
||||||
|
|
||||||
task dumpClientLibs(type: Copy) {
|
task dumpClientLibs(type: Copy) {
|
||||||
dependsOn parent.childProjects.Launcher.tasks.build
|
dependsOn parent.childProjects.Launcher.tasks.build
|
||||||
into "$buildDir/libs/launcher-libraries"
|
into "$buildDir/libs/launcher-libraries"
|
||||||
from parent.childProjects.Launcher.tasks.dumpLibs.destinationDir
|
from parent.childProjects.Launcher.tasks.dumpLibs
|
||||||
}
|
}
|
||||||
|
|
||||||
assemble.dependsOn tasks.dumpLibs, tasks.dumpCompileOnlyLibs, tasks.dumpClientLibs, tasks.bundle, tasks.cleanjar
|
assemble.dependsOn tasks.dumpLibs, tasks.dumpCompileOnlyLibs, tasks.dumpClientLibs, tasks.bundle, tasks.cleanjar
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
|
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
import pro.gravit.launcher.Launcher;
|
import pro.gravit.launcher.Launcher;
|
||||||
import pro.gravit.launcher.hwid.HWIDProvider;
|
|
||||||
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
import pro.gravit.launcher.request.auth.AuthRequest;
|
||||||
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
||||||
import pro.gravit.launchserver.auth.hwid.HWIDHandler;
|
|
||||||
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||||
|
@ -208,11 +206,9 @@ public static void registerAll() {
|
||||||
AuthHandler.registerHandlers();
|
AuthHandler.registerHandlers();
|
||||||
AuthProvider.registerProviders();
|
AuthProvider.registerProviders();
|
||||||
TextureProvider.registerProviders();
|
TextureProvider.registerProviders();
|
||||||
HWIDHandler.registerHandlers();
|
|
||||||
Component.registerComponents();
|
Component.registerComponents();
|
||||||
ProtectHandler.registerHandlers();
|
ProtectHandler.registerHandlers();
|
||||||
WebSocketService.registerResponses();
|
WebSocketService.registerResponses();
|
||||||
HWIDProvider.registerHWIDs();
|
|
||||||
DaoProvider.registerProviders();
|
DaoProvider.registerProviders();
|
||||||
AuthRequest.registerProviders();
|
AuthRequest.registerProviders();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
||||||
import pro.gravit.launchserver.auth.hwid.HWIDHandler;
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||||
|
|
||||||
|
@ -13,17 +12,15 @@ public class AuthProviderPair {
|
||||||
public AuthProvider provider;
|
public AuthProvider provider;
|
||||||
public AuthHandler handler;
|
public AuthHandler handler;
|
||||||
public TextureProvider textureProvider;
|
public TextureProvider textureProvider;
|
||||||
public HWIDHandler hwid;
|
|
||||||
public Map<String, String> links;
|
public Map<String, String> links;
|
||||||
public transient String name;
|
public transient String name;
|
||||||
public String displayName;
|
public String displayName;
|
||||||
public final boolean isDefault = true;
|
public final boolean isDefault = true;
|
||||||
|
|
||||||
public AuthProviderPair(AuthProvider provider, AuthHandler handler, TextureProvider textureProvider, HWIDHandler hwid) {
|
public AuthProviderPair(AuthProvider provider, AuthHandler handler, TextureProvider textureProvider) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.textureProvider = textureProvider;
|
this.textureProvider = textureProvider;
|
||||||
this.hwid = hwid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(LaunchServer srv, String name) {
|
public void init(LaunchServer srv, String name) {
|
||||||
|
@ -32,10 +29,8 @@ public void init(LaunchServer srv, String name) {
|
||||||
if(provider == null) throw new NullPointerException(String.format("Auth %s provider null", name));
|
if(provider == null) throw new NullPointerException(String.format("Auth %s provider null", name));
|
||||||
if(handler == null) throw new NullPointerException(String.format("Auth %s handler null", name));
|
if(handler == null) throw new NullPointerException(String.format("Auth %s handler null", name));
|
||||||
if(textureProvider == null) throw new NullPointerException(String.format("Auth %s textureProvider null", name));
|
if(textureProvider == null) throw new NullPointerException(String.format("Auth %s textureProvider null", name));
|
||||||
if(hwid == null) throw new NullPointerException(String.format("Auth %s hwid null", name));
|
|
||||||
provider.init(srv);
|
provider.init(srv);
|
||||||
handler.init(srv);
|
handler.init(srv);
|
||||||
hwid.init();
|
|
||||||
}
|
}
|
||||||
public void link(LaunchServer srv)
|
public void link(LaunchServer srv)
|
||||||
{
|
{
|
||||||
|
@ -60,11 +55,6 @@ else if("textureProvider".equals(k))
|
||||||
if(pair.textureProvider == null) throw new NullPointerException(String.format("Auth %s link failed. %s.textureProvider is null", name, v));
|
if(pair.textureProvider == null) throw new NullPointerException(String.format("Auth %s link failed. %s.textureProvider is null", name, v));
|
||||||
textureProvider = pair.textureProvider;
|
textureProvider = pair.textureProvider;
|
||||||
}
|
}
|
||||||
else if("hwid".equals(k))
|
|
||||||
{
|
|
||||||
if(pair.hwid == null) throw new NullPointerException(String.format("Auth %s link failed. %s.hwid is null", name, v));
|
|
||||||
hwid = pair.hwid;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.hwid;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AcceptHWIDHandler extends HWIDHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ban(List<HWID> hwid) {
|
|
||||||
//SKIP
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void check0(HWID hwid, String username) {
|
|
||||||
//SKIP
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
//SKIP
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<HWID> getHwid(String username) {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unban(List<HWID> hwid) {
|
|
||||||
//SKIP
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.hwid;
|
|
||||||
|
|
||||||
public class HWIDException extends Exception {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = -5307315891121889972L;
|
|
||||||
|
|
||||||
public HWIDException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public HWIDException(String s) {
|
|
||||||
super(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HWIDException(String s, Throwable throwable) {
|
|
||||||
super(s, throwable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HWIDException(Throwable throwable) {
|
|
||||||
super(throwable);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.hwid;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
import pro.gravit.launchserver.Reconfigurable;
|
|
||||||
import pro.gravit.utils.ProviderMap;
|
|
||||||
import pro.gravit.utils.command.Command;
|
|
||||||
import pro.gravit.utils.command.SubCommand;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public abstract class HWIDHandler implements AutoCloseable, Reconfigurable {
|
|
||||||
public static final ProviderMap<HWIDHandler> providers = new ProviderMap<>("HWIDHandler");
|
|
||||||
private static boolean registredHandl = false;
|
|
||||||
|
|
||||||
|
|
||||||
public static void registerHandlers() {
|
|
||||||
if (!registredHandl) {
|
|
||||||
providers.register("accept", AcceptHWIDHandler.class);
|
|
||||||
providers.register("mysql", MysqlHWIDHandler.class);
|
|
||||||
providers.register("json", JsonHWIDHandler.class);
|
|
||||||
providers.register("jsonfile", JsonFileHWIDHandler.class);
|
|
||||||
providers.register("memory", MemoryHWIDHandler.class);
|
|
||||||
registredHandl = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Command> getCommands() {
|
|
||||||
Map<String, Command> commands = new HashMap<>();
|
|
||||||
commands.put("ban", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
List<HWID> target = getHwid(args[0]);
|
|
||||||
ban(target);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
commands.put("unban", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
List<HWID> target = getHwid(args[0]);
|
|
||||||
unban(target);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
commands.put("gethwid", new SubCommand() {
|
|
||||||
@Override
|
|
||||||
public void invoke(String... args) throws Exception {
|
|
||||||
List<HWID> target = getHwid(args[0]);
|
|
||||||
for (HWID hwid : target) {
|
|
||||||
if (hwid == null) {
|
|
||||||
LogHelper.error("[%s] HWID: null", args[0]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
LogHelper.info("[%s] HWID: %s", args[0], hwid.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void ban(List<HWID> hwid) throws HWIDException;
|
|
||||||
|
|
||||||
public void check(HWID hwid, String username) throws HWIDException {
|
|
||||||
if (hwid == null || hwid.isNull()) return;
|
|
||||||
check0(hwid, username);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void check0(HWID hwid, String username) throws HWIDException;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract void close() throws Exception;
|
|
||||||
|
|
||||||
public abstract void init();
|
|
||||||
|
|
||||||
public abstract List<HWID> getHwid(String username) throws HWIDException;
|
|
||||||
|
|
||||||
public abstract void unban(List<HWID> hwid) throws HWIDException;
|
|
||||||
}
|
|
|
@ -1,113 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.hwid;
|
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import pro.gravit.launcher.Launcher;
|
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
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.lang.reflect.Type;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class JsonFileHWIDHandler extends HWIDHandler {
|
|
||||||
public static class Entry {
|
|
||||||
public final HWID hwid;
|
|
||||||
public String username;
|
|
||||||
public boolean isBanned = false;
|
|
||||||
|
|
||||||
public Entry(HWID hwid) {
|
|
||||||
this.hwid = hwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Entry entry = (Entry) o;
|
|
||||||
return Objects.equals(hwid, entry.hwid);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(hwid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final String filename = "hwids.json";
|
|
||||||
public transient LinkedList<Entry> list = new LinkedList<>();
|
|
||||||
public final String banMessage = "You banned";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ban(List<HWID> hwid) {
|
|
||||||
for (Entry e : list) {
|
|
||||||
for (HWID banHWID : hwid) {
|
|
||||||
if (e.hwid.equals(banHWID)) {
|
|
||||||
e.isBanned = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init() {
|
|
||||||
Path path = Paths.get(filename);
|
|
||||||
Type type = new TypeToken<LinkedList<Entry>>() {
|
|
||||||
}.getType();
|
|
||||||
try (Reader reader = IOHelper.newReader(path)) {
|
|
||||||
list = Launcher.gsonManager.gson.fromJson(reader, type);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void check0(HWID hwid, String username) throws HWIDException {
|
|
||||||
boolean isOne = false;
|
|
||||||
for (Entry e : list) {
|
|
||||||
if (e.hwid.equals(hwid)) {
|
|
||||||
isOne = true;
|
|
||||||
if (e.isBanned) throw new HWIDException(banMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isOne) {
|
|
||||||
list.add(new Entry(hwid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws Exception {
|
|
||||||
Path path = Paths.get(filename);
|
|
||||||
try (Writer writer = IOHelper.newWriter(path)) {
|
|
||||||
Launcher.gsonManager.configGson.toJson(list, writer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<HWID> getHwid(String username) {
|
|
||||||
LinkedList<HWID> hwids = new LinkedList<>();
|
|
||||||
for (Entry e : list) {
|
|
||||||
if (e.username.equals(username)) hwids.add(e.hwid);
|
|
||||||
}
|
|
||||||
return hwids;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unban(List<HWID> hwid) {
|
|
||||||
for (Entry e : list) {
|
|
||||||
for (HWID banHWID : hwid) {
|
|
||||||
if (e.hwid.equals(banHWID)) {
|
|
||||||
e.isBanned = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,148 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.hwid;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
import pro.gravit.launcher.hwid.OshiHWID;
|
|
||||||
import pro.gravit.launcher.HTTPRequest;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public final class JsonHWIDHandler extends HWIDHandler {
|
|
||||||
private static final Gson gson = new Gson();
|
|
||||||
|
|
||||||
private URL url;
|
|
||||||
private URL urlBan;
|
|
||||||
private URL urlUnBan;
|
|
||||||
private URL urlGet;
|
|
||||||
private String apiKey;
|
|
||||||
|
|
||||||
public static class banRequest {
|
|
||||||
public banRequest(OshiHWID hwid) {
|
|
||||||
this.hwid = hwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
final OshiHWID hwid;
|
|
||||||
String apiKey;
|
|
||||||
|
|
||||||
public banRequest(OshiHWID hwid, String apiKey) {
|
|
||||||
this.hwid = hwid;
|
|
||||||
this.apiKey = apiKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class checkRequest {
|
|
||||||
public checkRequest(String username, OshiHWID hwid) {
|
|
||||||
this.username = username;
|
|
||||||
this.hwid = hwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String username;
|
|
||||||
final OshiHWID hwid;
|
|
||||||
String apiKey;
|
|
||||||
|
|
||||||
public checkRequest(String username, OshiHWID hwid, String apiKey) {
|
|
||||||
this.username = username;
|
|
||||||
this.hwid = hwid;
|
|
||||||
this.apiKey = apiKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Result {
|
|
||||||
String error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class BannedResult {
|
|
||||||
boolean isBanned;
|
|
||||||
String error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HWIDRequest {
|
|
||||||
public HWIDRequest(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String username;
|
|
||||||
String apiKey;
|
|
||||||
|
|
||||||
public HWIDRequest(String username, String apiKey) {
|
|
||||||
this.username = username;
|
|
||||||
this.apiKey = apiKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ban(List<HWID> l_hwid) throws HWIDException {
|
|
||||||
for (HWID hwid : l_hwid) {
|
|
||||||
banRequest request = new banRequest((OshiHWID) hwid, apiKey);
|
|
||||||
try {
|
|
||||||
JsonElement result = HTTPRequest.jsonRequest(gson.toJsonTree(request), urlBan);
|
|
||||||
Result r = gson.fromJson(result, Result.class);
|
|
||||||
if (r.error != null) throw new HWIDException(r.error);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
throw new HWIDException("HWID service error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void check0(HWID hwid, String username) throws HWIDException {
|
|
||||||
checkRequest request = new checkRequest(username, (OshiHWID) hwid, apiKey);
|
|
||||||
try {
|
|
||||||
JsonElement result = HTTPRequest.jsonRequest(gson.toJsonTree(request), url);
|
|
||||||
BannedResult r = gson.fromJson(result, BannedResult.class);
|
|
||||||
if (r.error != null) throw new HWIDException(r.error);
|
|
||||||
boolean isBanned = r.isBanned;
|
|
||||||
if (isBanned) throw new HWIDException("You will BANNED!");
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
throw new HWIDException("HWID service error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
// pass
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<HWID> getHwid(String username) throws HWIDException {
|
|
||||||
ArrayList<HWID> hwids = new ArrayList<>();
|
|
||||||
HWIDRequest request = new HWIDRequest(username, apiKey);
|
|
||||||
try {
|
|
||||||
JsonElement result = HTTPRequest.jsonRequest(gson.toJsonTree(request), urlGet);
|
|
||||||
OshiHWID[] r = gson.fromJson(result, OshiHWID[].class);
|
|
||||||
hwids.addAll(Arrays.asList(r));
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
throw new HWIDException("HWID service error");
|
|
||||||
}
|
|
||||||
return hwids;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unban(List<HWID> l_hwid) throws HWIDException {
|
|
||||||
for (HWID hwid : l_hwid) {
|
|
||||||
banRequest request = new banRequest((OshiHWID) hwid, apiKey);
|
|
||||||
try {
|
|
||||||
JsonElement result = HTTPRequest.jsonRequest(gson.toJsonTree(request), urlUnBan);
|
|
||||||
Result r = gson.fromJson(result, Result.class);
|
|
||||||
if (r.error != null) throw new HWIDException(r.error);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
throw new HWIDException("HWID service error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.hwid;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class MemoryHWIDHandler extends HWIDHandler {
|
|
||||||
public static class Entry {
|
|
||||||
public final HWID hwid;
|
|
||||||
public String username;
|
|
||||||
public boolean isBanned = false;
|
|
||||||
|
|
||||||
public Entry(HWID hwid) {
|
|
||||||
this.hwid = hwid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Entry entry = (Entry) o;
|
|
||||||
return Objects.equals(hwid, entry.hwid);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(hwid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final transient LinkedList<Entry> list = new LinkedList<>();
|
|
||||||
public final String banMessage = "You banned";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ban(List<HWID> hwid) {
|
|
||||||
for (Entry e : list) {
|
|
||||||
for (HWID banHWID : hwid) {
|
|
||||||
if (e.hwid.equals(banHWID)) {
|
|
||||||
e.isBanned = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void check0(HWID hwid, String username) throws HWIDException {
|
|
||||||
boolean isOne = false;
|
|
||||||
for (Entry e : list) {
|
|
||||||
if (e.hwid.equals(hwid)) {
|
|
||||||
isOne = true;
|
|
||||||
if (e.isBanned) throw new HWIDException(banMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isOne) {
|
|
||||||
list.add(new Entry(hwid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<HWID> getHwid(String username) {
|
|
||||||
LinkedList<HWID> hwids = new LinkedList<>();
|
|
||||||
for (Entry e : list) {
|
|
||||||
if (e.username.equals(username)) hwids.add(e.hwid);
|
|
||||||
}
|
|
||||||
return hwids;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unban(List<HWID> hwid) {
|
|
||||||
for (Entry e : list) {
|
|
||||||
for (HWID banHWID : hwid) {
|
|
||||||
if (e.hwid.equals(banHWID)) {
|
|
||||||
e.isBanned = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,268 +0,0 @@
|
||||||
package pro.gravit.launchserver.auth.hwid;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
import pro.gravit.launcher.hwid.OshiHWID;
|
|
||||||
import pro.gravit.launchserver.auth.MySQLSourceConfig;
|
|
||||||
import pro.gravit.utils.helper.CommonHelper;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MysqlHWIDHandler extends HWIDHandler {
|
|
||||||
private MySQLSourceConfig mySQLHolder;
|
|
||||||
|
|
||||||
private String tableUsers;
|
|
||||||
private String tableHwids;
|
|
||||||
|
|
||||||
private String userFieldHwid;
|
|
||||||
private String userFieldLogin;
|
|
||||||
|
|
||||||
private String hwidFieldTotalMemory;
|
|
||||||
private String hwidFieldSerialNumber;
|
|
||||||
private String hwidFieldHWDiskSerial;
|
|
||||||
private String hwidFieldProcessorID;
|
|
||||||
private String hwidFieldBanned;
|
|
||||||
private String hwidFieldMAC;
|
|
||||||
|
|
||||||
private String queryHwids;
|
|
||||||
private String[] paramsHwids;
|
|
||||||
|
|
||||||
private String queryBan;
|
|
||||||
private String[] paramsBan;
|
|
||||||
|
|
||||||
private String banMessage;
|
|
||||||
|
|
||||||
private boolean compareMode = false;
|
|
||||||
//Using queryHWID "queryHwids": "SELECT * FROM `users_hwids` WHERE `totalMemory` = ? or `serialNumber` = ? or `HWDiskSerial` = ? or `processorID` = ? or `MACAddr` = ?"
|
|
||||||
private int compare = 50; //При наборе схожести в 50 очков
|
|
||||||
private boolean oneCompareMode = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
//Добавить поля hwid в базу с пользователями
|
|
||||||
|
|
||||||
//Создание таблицы для хранения HWID
|
|
||||||
CREATE TABLE `fc_user_hwids` (
|
|
||||||
`id` int(16) NOT NULL,
|
|
||||||
`totalMemory` varchar(32) NOT NULL,
|
|
||||||
`serialNumber` varchar(64) NOT NULL,
|
|
||||||
`HWDiskSerial` varchar(64) NOT NULL,
|
|
||||||
`processorID` varchar(64) NOT NULL,
|
|
||||||
`MACAddr` varchar(64) NOT NULL,
|
|
||||||
`isBanned` tinyint(1) NOT NULL DEFAULT '0'
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
||||||
|
|
||||||
ALTER TABLE `fc_user_hwids` ADD UNIQUE KEY `id` (`id`);
|
|
||||||
|
|
||||||
ALTER TABLE `fc_user_hwids` MODIFY `id` int(16) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void check0(HWID hwid, String username) throws HWIDException {
|
|
||||||
if (hwid instanceof OshiHWID) {
|
|
||||||
OshiHWID oshiHWID = (OshiHWID) hwid;
|
|
||||||
try (Connection c = mySQLHolder.getConnection()) {
|
|
||||||
|
|
||||||
PreparedStatement s = c.prepareStatement(String.format("SELECT %s, %s FROM `%s` WHERE `%s` = ? LIMIT 1",
|
|
||||||
userFieldHwid, userFieldLogin, tableUsers, userFieldLogin));
|
|
||||||
s.setString(1, username);
|
|
||||||
|
|
||||||
// Execute SQL query
|
|
||||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
|
||||||
try (ResultSet set = s.executeQuery()) {
|
|
||||||
if (set.next()) {
|
|
||||||
int hwid_id = set.getInt(userFieldHwid);
|
|
||||||
if (hwid_id == 0) {
|
|
||||||
onUpdateInfo(oshiHWID, username, c);
|
|
||||||
} else {
|
|
||||||
onCheckInfo(oshiHWID, username, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onUpdateInfo(OshiHWID hwid, String username, Connection c) throws HWIDException {
|
|
||||||
try (PreparedStatement a = c.prepareStatement(queryHwids)) {
|
|
||||||
|
|
||||||
String[] replaceParams = {"totalMemory", String.valueOf(hwid.totalMemory), "serialNumber", hwid.serialNumber, "HWDiskSerial", hwid.HWDiskSerial, "processorID", hwid.processorID, "MAC", hwid.macAddr};
|
|
||||||
for (int i = 0; i < paramsHwids.length; i++) {
|
|
||||||
a.setString(i + 1, CommonHelper.replace(paramsHwids[i], replaceParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultSet set = a.executeQuery();
|
|
||||||
PreparedStatement ps;
|
|
||||||
if (set.next()) {
|
|
||||||
int id = set.getInt("id");
|
|
||||||
boolean isBanned = set.getBoolean(hwidFieldBanned);
|
|
||||||
|
|
||||||
ps = c.prepareStatement(String.format("UPDATE `%s` SET `%s` = ? WHERE `%s` = ?",
|
|
||||||
tableUsers, userFieldHwid, userFieldLogin));
|
|
||||||
ps.setInt(1, id);
|
|
||||||
ps.setString(2, username);
|
|
||||||
|
|
||||||
ps.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
|
||||||
ps.executeUpdate();
|
|
||||||
|
|
||||||
if (isBanned) {
|
|
||||||
throw new HWIDException(banMessage);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ps = c.prepareStatement(String.format("INSERT INTO `%s` (`%s`, `%s`, `%s`, `%s`, `%s`) VALUES (?, ?, ?, ?, ?);",
|
|
||||||
tableHwids, hwidFieldTotalMemory, hwidFieldSerialNumber, hwidFieldHWDiskSerial, hwidFieldProcessorID, hwidFieldMAC));
|
|
||||||
ps.setString(1, String.valueOf(hwid.totalMemory));
|
|
||||||
ps.setString(2, hwid.serialNumber);
|
|
||||||
ps.setString(3, hwid.HWDiskSerial);
|
|
||||||
ps.setString(4, hwid.processorID);
|
|
||||||
ps.setString(5, hwid.macAddr);
|
|
||||||
ps.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
|
||||||
ps.executeUpdate();
|
|
||||||
|
|
||||||
ps = c.prepareStatement(String.format("UPDATE `%s` SET `%s` = LAST_INSERT_ID() WHERE `%s` = ?;",
|
|
||||||
tableUsers, userFieldHwid, userFieldLogin));
|
|
||||||
ps.setString(1, username);
|
|
||||||
ps.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
|
||||||
ps.executeUpdate();
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onCheckInfo(OshiHWID hwid, String username, Connection c) throws HWIDException {
|
|
||||||
try (PreparedStatement a = c.prepareStatement(queryHwids)) {
|
|
||||||
String[] replaceParams = {"totalMemory", String.valueOf(hwid.totalMemory), "serialNumber", hwid.serialNumber, "HWDiskSerial", hwid.HWDiskSerial, "processorID", hwid.processorID, "MAC", hwid.macAddr};
|
|
||||||
for (int i = 0; i < paramsHwids.length; i++) {
|
|
||||||
a.setString(i + 1, CommonHelper.replace(paramsHwids[i], replaceParams));
|
|
||||||
}
|
|
||||||
ResultSet set = a.executeQuery();
|
|
||||||
boolean isOne = false;
|
|
||||||
while (set.next()) {
|
|
||||||
if (!oneCompareMode) isOne = true;
|
|
||||||
if (compareMode) {
|
|
||||||
OshiHWID db_hwid = new OshiHWID();
|
|
||||||
db_hwid.serialNumber = set.getString(hwidFieldSerialNumber);
|
|
||||||
db_hwid.processorID = set.getString(hwidFieldProcessorID);
|
|
||||||
db_hwid.HWDiskSerial = set.getString(hwidFieldHWDiskSerial);
|
|
||||||
db_hwid.totalMemory = Long.parseLong(set.getString(hwidFieldTotalMemory));
|
|
||||||
db_hwid.macAddr = set.getString(hwidFieldMAC);
|
|
||||||
if (LogHelper.isDevEnabled()) {
|
|
||||||
LogHelper.dev("Compare HWID: %s vs %s", hwid.toString(), db_hwid.toString());
|
|
||||||
}
|
|
||||||
int compare_point = hwid.compare(db_hwid);
|
|
||||||
if (compare_point < compare) continue;
|
|
||||||
else {
|
|
||||||
if (LogHelper.isDevEnabled()) {
|
|
||||||
LogHelper.debug("User %s hwid check: found compare %d in %d", username, compare_point, set.getInt("id"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (oneCompareMode) isOne = true;
|
|
||||||
boolean isBanned = set.getBoolean(hwidFieldBanned);
|
|
||||||
if (isBanned) {
|
|
||||||
throw new HWIDException(banMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isOne) {
|
|
||||||
onUpdateInfo(hwid, username, c);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsBanned(HWID hwid, boolean isBanned) {
|
|
||||||
if (LogHelper.isDebugEnabled()) {
|
|
||||||
LogHelper.debug("%s Request HWID: %s", isBanned ? "Ban" : "UnBan", hwid.toString());
|
|
||||||
}
|
|
||||||
if (hwid instanceof OshiHWID) {
|
|
||||||
OshiHWID oshiHWID = (OshiHWID) hwid;
|
|
||||||
try (Connection c = mySQLHolder.getConnection()) {
|
|
||||||
try (PreparedStatement a = c.prepareStatement(queryBan)) {
|
|
||||||
String[] replaceParamsUpd = {"totalMemory", String.valueOf(oshiHWID.totalMemory), "serialNumber", oshiHWID.serialNumber, "HWDiskSerial", oshiHWID.HWDiskSerial, "processorID", oshiHWID.processorID, "MAC", oshiHWID.macAddr, "isBanned", isBanned ? "1" : "0"};
|
|
||||||
for (int i = 0; i < paramsBan.length; i++) {
|
|
||||||
a.setString(i + 1, CommonHelper.replace(paramsBan[i], replaceParamsUpd));
|
|
||||||
}
|
|
||||||
a.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
|
||||||
a.executeUpdate();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ban(List<HWID> list) {
|
|
||||||
for (HWID hwid : list) {
|
|
||||||
setIsBanned(hwid, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unban(List<HWID> list) {
|
|
||||||
for (HWID hwid : list) {
|
|
||||||
setIsBanned(hwid, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<HWID> getHwid(String username) {
|
|
||||||
ArrayList<HWID> list = new ArrayList<>();
|
|
||||||
try (Connection c = mySQLHolder.getConnection()) {
|
|
||||||
if (LogHelper.isDebugEnabled()) {
|
|
||||||
LogHelper.debug("Try find HWID from username %s", username);
|
|
||||||
}
|
|
||||||
PreparedStatement s = c.prepareStatement(String.format("SELECT %s, %s FROM `%s` WHERE `%s` = ? LIMIT 1", userFieldHwid, userFieldLogin, tableUsers, userFieldLogin));
|
|
||||||
s.setString(1, username);
|
|
||||||
|
|
||||||
// Execute SQL query
|
|
||||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
|
||||||
|
|
||||||
try (ResultSet set = s.executeQuery()) {
|
|
||||||
if (set.next()) {
|
|
||||||
int hwid_id = set.getInt(userFieldHwid);
|
|
||||||
if (hwid_id != 0) {
|
|
||||||
s = c.prepareStatement(String.format("SELECT * FROM `%s` WHERE `id` = ? LIMIT 1", tableHwids));
|
|
||||||
s.setInt(1, hwid_id);
|
|
||||||
ResultSet rs = s.executeQuery();
|
|
||||||
if (rs.next()) {
|
|
||||||
OshiHWID oshiHWID = new OshiHWID();
|
|
||||||
oshiHWID.totalMemory = Long.parseLong(rs.getString(hwidFieldTotalMemory));
|
|
||||||
oshiHWID.serialNumber = rs.getString(hwidFieldSerialNumber);
|
|
||||||
oshiHWID.HWDiskSerial = rs.getString(hwidFieldHWDiskSerial);
|
|
||||||
oshiHWID.processorID = rs.getString(hwidFieldProcessorID);
|
|
||||||
oshiHWID.macAddr = rs.getString(hwidFieldMAC);
|
|
||||||
list.add(oshiHWID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LogHelper.error(new HWIDException("HWID not found"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
mySQLHolder.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package pro.gravit.launchserver.auth.protect;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.events.request.GetSecureLevelInfoRequestEvent;
|
||||||
|
import pro.gravit.launchserver.auth.protect.interfaces.SecureProtectHandler;
|
||||||
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||||
|
import pro.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
|
public class AdvancedProtectHandler extends ProtectHandler implements SecureProtectHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
|
||||||
|
return (context.authType == AuthResponse.ConnectTypes.CLIENT) && context.client.checkSign;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkLaunchServerLicense() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GetSecureLevelInfoRequestEvent onGetSecureLevelInfo(GetSecureLevelInfoRequestEvent event) {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean allowGetSecureLevelInfo(Client client) {
|
||||||
|
return client.checkSign;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,20 +4,6 @@
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
import pro.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
public class NoProtectHandler extends ProtectHandler {
|
public class NoProtectHandler extends ProtectHandler {
|
||||||
@Override
|
|
||||||
public String generateSecureToken(AuthResponse.AuthContext context) {
|
|
||||||
return SecurityHelper.randomStringToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String generateClientSecureToken() {
|
|
||||||
return SecurityHelper.randomStringToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean verifyClientSecureToken(String token, String secureKey) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
|
public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
|
||||||
|
|
|
@ -12,16 +12,11 @@ public static void registerHandlers() {
|
||||||
if (!registredHandl) {
|
if (!registredHandl) {
|
||||||
providers.register("none", NoProtectHandler.class);
|
providers.register("none", NoProtectHandler.class);
|
||||||
providers.register("std", StdProtectHandler.class);
|
providers.register("std", StdProtectHandler.class);
|
||||||
|
providers.register("advanced", AdvancedProtectHandler.class);
|
||||||
registredHandl = true;
|
registredHandl = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract String generateSecureToken(AuthResponse.AuthContext context); //Генерация токена для передачи его в LauncherGuardInterface
|
|
||||||
|
|
||||||
public abstract String generateClientSecureToken();
|
|
||||||
|
|
||||||
public abstract boolean verifyClientSecureToken(String token, String secureKey);
|
|
||||||
|
|
||||||
public abstract boolean allowGetAccessToken(AuthResponse.AuthContext context);
|
public abstract boolean allowGetAccessToken(AuthResponse.AuthContext context);
|
||||||
|
|
||||||
public abstract void checkLaunchServerLicense(); //Выдает SecurityException при ошибке проверки лицензии
|
public abstract void checkLaunchServerLicense(); //Выдает SecurityException при ошибке проверки лицензии
|
||||||
|
|
|
@ -1,33 +1,48 @@
|
||||||
package pro.gravit.launchserver.auth.protect;
|
package pro.gravit.launchserver.auth.protect;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
|
import pro.gravit.launchserver.auth.protect.interfaces.ProfilesProtectHandler;
|
||||||
|
import pro.gravit.launchserver.socket.Client;
|
||||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
import pro.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
public class StdProtectHandler extends ProtectHandler {
|
import java.util.ArrayList;
|
||||||
public final boolean checkSecure = true;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
@Override
|
import java.util.Map;
|
||||||
public String generateSecureToken(AuthResponse.AuthContext context) {
|
|
||||||
return SecurityHelper.randomStringToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String generateClientSecureToken() {
|
|
||||||
return SecurityHelper.randomStringToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean verifyClientSecureToken(String token, String secureKey) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public class StdProtectHandler extends ProtectHandler implements ProfilesProtectHandler {
|
||||||
|
public Map<String, List<String>> profileWhitelist = new HashMap<>();
|
||||||
|
public List<String> allowUpdates = new ArrayList<>();
|
||||||
@Override
|
@Override
|
||||||
public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
|
public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
|
||||||
return (context.authType == AuthResponse.ConnectTypes.CLIENT) && (!checkSecure || context.client.isSecure);
|
return (context.authType == AuthResponse.ConnectTypes.CLIENT) && context.client.checkSign;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkLaunchServerLicense() {
|
public void checkLaunchServerLicense() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canGetProfile(ClientProfile profile, Client client) {
|
||||||
|
return canChangeProfile(profile, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canChangeProfile(ClientProfile profile, Client client) {
|
||||||
|
return client.isAuth && client.username != null && isWhitelisted(profile.getTitle(), client.username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canGetUpdates(String updatesDirName, Client client) {
|
||||||
|
return client.profile != null && ( client.profile.getDir().equals(updatesDirName) || client.profile.getAssetDir().equals(updatesDirName) || allowUpdates.contains(updatesDirName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWhitelisted(String profileTitle, String username)
|
||||||
|
{
|
||||||
|
List<String> allowedUsername = profileWhitelist.get(profileTitle);
|
||||||
|
if(allowedUsername == null) return true;
|
||||||
|
return allowedUsername.contains(username);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package pro.gravit.launchserver.auth.protect.interfaces;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
|
||||||
|
public interface ProfilesProtectHandler {
|
||||||
|
default boolean canGetProfiles(Client client)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default boolean canGetProfile(ClientProfile profile, Client client)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default boolean canChangeProfile(ClientProfile profile, Client client)
|
||||||
|
{
|
||||||
|
return client.isAuth;
|
||||||
|
}
|
||||||
|
default boolean canGetUpdates(String updatesDirName, Client client)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package pro.gravit.launchserver.auth.protect.interfaces;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.events.request.GetSecureLevelInfoRequestEvent;
|
||||||
|
import pro.gravit.launcher.events.request.SecurityReportRequestEvent;
|
||||||
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
import pro.gravit.launchserver.socket.response.secure.SecurityReportResponse;
|
||||||
|
import pro.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
|
import java.security.Signature;
|
||||||
|
import java.security.SignatureException;
|
||||||
|
import java.security.interfaces.ECPublicKey;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
|
||||||
|
public interface SecureProtectHandler {
|
||||||
|
default byte[] generateSecureLevelKey()
|
||||||
|
{
|
||||||
|
return SecurityHelper.randomBytes(128);
|
||||||
|
}
|
||||||
|
default void verifySecureLevelKey(byte[] publicKey, byte[] data, byte[] signature) throws InvalidKeySpecException, SignatureException {
|
||||||
|
if(publicKey == null || signature == null) throw new InvalidKeySpecException();
|
||||||
|
ECPublicKey pubKey = SecurityHelper.toPublicECKey(publicKey);
|
||||||
|
Signature sign = SecurityHelper.newECVerifySignature(pubKey);
|
||||||
|
sign.update(data);
|
||||||
|
sign.verify(signature);
|
||||||
|
}
|
||||||
|
GetSecureLevelInfoRequestEvent onGetSecureLevelInfo(GetSecureLevelInfoRequestEvent event);
|
||||||
|
boolean allowGetSecureLevelInfo(Client client);
|
||||||
|
default SecurityReportRequestEvent onSecurityReport(SecurityReportResponse report, Client client)
|
||||||
|
{
|
||||||
|
return new SecurityReportRequestEvent();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,10 @@
|
||||||
package pro.gravit.launchserver.command.basic;
|
package pro.gravit.launchserver.command.basic;
|
||||||
|
|
||||||
import org.bouncycastle.cert.X509CertificateHolder;
|
import org.bouncycastle.cert.X509CertificateHolder;
|
||||||
import pro.gravit.launcher.hwid.HWIDCheckHelper;
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.command.Command;
|
import pro.gravit.launchserver.command.Command;
|
||||||
import pro.gravit.launchserver.socket.handlers.NettyServerSocketHandler;
|
import pro.gravit.launchserver.socket.handlers.NettyServerSocketHandler;
|
||||||
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.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
@ -56,8 +54,5 @@ public void invoke(String... args) throws Exception {
|
||||||
server.certificateManager.writePrivateKey(Paths.get(name.concat(".key")), pair.getPrivate());
|
server.certificateManager.writePrivateKey(Paths.get(name.concat(".key")), pair.getPrivate());
|
||||||
server.certificateManager.writeCertificate(Paths.get(name.concat(".crt")), cert);
|
server.certificateManager.writeCertificate(Paths.get(name.concat(".crt")), cert);
|
||||||
}
|
}
|
||||||
if (args[0].equals("hwidcheck")) {
|
|
||||||
LogHelper.info("HWID String %s bad rating %d", args[1], HWIDCheckHelper.checkString(args[1]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ public void invoke(String... args) {
|
||||||
LogHelper.info("Channel %s | connectUUID %s | checkSign %s", ip, frameHandler.getConnectUUID(), client.checkSign ? "true" : "false");
|
LogHelper.info("Channel %s | connectUUID %s | checkSign %s", ip, frameHandler.getConnectUUID(), client.checkSign ? "true" : "false");
|
||||||
else {
|
else {
|
||||||
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 | isSecure %s | auth_id %s", client.checkSign ? "true" : "false", client.isSecure ? "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 (long %d)", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.toLong());
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
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.hwid.AcceptHWIDHandler;
|
|
||||||
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
||||||
import pro.gravit.launchserver.auth.protect.StdProtectHandler;
|
import pro.gravit.launchserver.auth.protect.StdProtectHandler;
|
||||||
import pro.gravit.launchserver.auth.provider.RejectAuthProvider;
|
import pro.gravit.launchserver.auth.provider.RejectAuthProvider;
|
||||||
|
@ -75,7 +74,6 @@ public AuthProviderPair getAuthProviderPair() {
|
||||||
public ExeConf launch4j;
|
public ExeConf launch4j;
|
||||||
public NettyConfig netty;
|
public NettyConfig netty;
|
||||||
|
|
||||||
public String whitelistRejectString;
|
|
||||||
public LauncherConf launcher;
|
public LauncherConf launcher;
|
||||||
public CertificateConf certificate;
|
public CertificateConf certificate;
|
||||||
public JarSignerConf sign;
|
public JarSignerConf sign;
|
||||||
|
@ -139,7 +137,6 @@ public void init(LaunchServer.ReloadType type) {
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
|
server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
|
server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
|
server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".hwid"), pair.hwid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Arrays.stream(mirrors).forEach(server.mirrorManager::addMirror);
|
Arrays.stream(mirrors).forEach(server.mirrorManager::addMirror);
|
||||||
|
@ -152,7 +149,6 @@ 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);
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".hwid"), pair.hwid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type.equals(LaunchServer.ReloadType.FULL)) {
|
if (type.equals(LaunchServer.ReloadType.FULL)) {
|
||||||
|
@ -280,12 +276,11 @@ public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) {
|
||||||
AuthProviderPair a = new AuthProviderPair(new RejectAuthProvider("Настройте authProvider"),
|
AuthProviderPair a = new AuthProviderPair(new RejectAuthProvider("Настройте authProvider"),
|
||||||
new MemoryAuthHandler(),
|
new MemoryAuthHandler(),
|
||||||
new RequestTextureProvider("http://example.com/skins/%username%.png", "http://example.com/cloaks/%username%.png")
|
new RequestTextureProvider("http://example.com/skins/%username%.png", "http://example.com/cloaks/%username%.png")
|
||||||
, new AcceptHWIDHandler());
|
);
|
||||||
a.displayName = "Default";
|
a.displayName = "Default";
|
||||||
newConfig.auth.put("std", a);
|
newConfig.auth.put("std", a);
|
||||||
newConfig.protectHandler = new StdProtectHandler();
|
newConfig.protectHandler = new StdProtectHandler();
|
||||||
newConfig.binaryName = "Launcher";
|
newConfig.binaryName = "Launcher";
|
||||||
newConfig.whitelistRejectString = "Вас нет в белом списке";
|
|
||||||
|
|
||||||
newConfig.netty = new NettyConfig();
|
newConfig.netty = new NettyConfig();
|
||||||
newConfig.netty.fileServerEnabled = true;
|
newConfig.netty.fileServerEnabled = true;
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
package pro.gravit.launchserver.dao;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface HwidDAO {
|
|
||||||
UserHWID findById(long id);
|
|
||||||
|
|
||||||
List<? extends UserHWID> findHWIDs(HWID hwid);
|
|
||||||
|
|
||||||
void save(UserHWID user);
|
|
||||||
|
|
||||||
void update(UserHWID user);
|
|
||||||
|
|
||||||
void delete(UserHWID user);
|
|
||||||
|
|
||||||
List<UserHWID> findAll();
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package pro.gravit.launchserver.dao;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
|
|
||||||
public interface UserHWID {
|
|
||||||
boolean isBanned();
|
|
||||||
HWID toHWID();
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
package pro.gravit.launchserver.dao.impl;
|
|
||||||
|
|
||||||
import org.hibernate.Session;
|
|
||||||
import org.hibernate.SessionFactory;
|
|
||||||
import org.hibernate.Transaction;
|
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
import pro.gravit.launcher.hwid.OshiHWID;
|
|
||||||
import pro.gravit.launchserver.dao.HwidDAO;
|
|
||||||
import pro.gravit.launchserver.dao.UserHWID;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
|
||||||
import javax.persistence.criteria.Root;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class HibernateHwidDAOImpl implements HwidDAO {
|
|
||||||
private final SessionFactory factory;
|
|
||||||
|
|
||||||
public HibernateHwidDAOImpl(SessionFactory factory) {
|
|
||||||
this.factory = factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserHWIDImpl> findHWIDs(HWID hwid) {
|
|
||||||
if(!(hwid instanceof OshiHWID)) throw new UnsupportedOperationException();
|
|
||||||
OshiHWID oshiHWID = (OshiHWID) hwid;
|
|
||||||
EntityManager em = factory.createEntityManager();
|
|
||||||
em.getTransaction().begin();
|
|
||||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
|
||||||
CriteriaQuery<UserHWIDImpl> personCriteria = cb.createQuery(UserHWIDImpl.class);
|
|
||||||
Root<UserHWIDImpl> rootUser = personCriteria.from(UserHWIDImpl.class);
|
|
||||||
personCriteria.select(rootUser).where(
|
|
||||||
cb.or(
|
|
||||||
cb.equal(rootUser.get("totalMemory"), oshiHWID.totalMemory),
|
|
||||||
cb.equal(rootUser.get("HWDiskSerial"), oshiHWID.HWDiskSerial),
|
|
||||||
cb.equal(rootUser.get("serialNumber"), oshiHWID.serialNumber),
|
|
||||||
cb.equal(rootUser.get("processorID"), oshiHWID.processorID),
|
|
||||||
cb.equal(rootUser.get("macAddr"), oshiHWID.macAddr)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
List<UserHWIDImpl> list = em.createQuery(personCriteria).getResultList();
|
|
||||||
em.close();
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserHWIDImpl findById(long id) {
|
|
||||||
try (Session s = factory.openSession()) {
|
|
||||||
return s.get(UserHWIDImpl.class, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void save(UserHWID user) {
|
|
||||||
try (Session session = factory.openSession()) {
|
|
||||||
Transaction tx1 = session.beginTransaction();
|
|
||||||
session.save(user);
|
|
||||||
tx1.commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(UserHWID user) {
|
|
||||||
try (Session session = factory.openSession()) {
|
|
||||||
Transaction tx1 = session.beginTransaction();
|
|
||||||
session.update(user);
|
|
||||||
tx1.commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete(UserHWID user) {
|
|
||||||
try (Session session = factory.openSession()) {
|
|
||||||
Transaction tx1 = session.beginTransaction();
|
|
||||||
session.delete(user);
|
|
||||||
tx1.commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public List<UserHWID> findAll() {
|
|
||||||
try (Session s = factory.openSession()) {
|
|
||||||
return (List<UserHWID>) s.createQuery("From user_hwids").list();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package pro.gravit.launchserver.dao.impl;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.hwid.OshiHWID;
|
|
||||||
import pro.gravit.launchserver.dao.UserHWID;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "users_hwids")
|
|
||||||
public class UserHWIDImpl implements UserHWID {
|
|
||||||
private final transient Supplier<OshiHWID> oshiSupp = () -> {
|
|
||||||
OshiHWID hwid = new OshiHWID();
|
|
||||||
hwid.HWDiskSerial = this.HWDiskSerial;
|
|
||||||
hwid.macAddr = this.macAddr;
|
|
||||||
hwid.processorID = this.processorID;
|
|
||||||
hwid.serialNumber = this.serialNumber;
|
|
||||||
hwid.totalMemory = this.totalMemory;
|
|
||||||
return hwid;
|
|
||||||
};
|
|
||||||
private transient OshiHWID oshi = null;
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
||||||
private long id;
|
|
||||||
|
|
||||||
public final long totalMemory = 0;
|
|
||||||
public String serialNumber;
|
|
||||||
public String HWDiskSerial;
|
|
||||||
public String processorID;
|
|
||||||
public String macAddr;
|
|
||||||
|
|
||||||
public boolean banned;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBanned() {
|
|
||||||
return banned;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OshiHWID toHWID() {
|
|
||||||
if (oshi == null) oshi = oshiSupp.get();
|
|
||||||
return oshi;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +1,12 @@
|
||||||
package pro.gravit.launchserver.dao.provider;
|
package pro.gravit.launchserver.dao.provider;
|
||||||
|
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.dao.HwidDAO;
|
|
||||||
import pro.gravit.launchserver.dao.UserDAO;
|
import pro.gravit.launchserver.dao.UserDAO;
|
||||||
import pro.gravit.utils.ProviderMap;
|
import pro.gravit.utils.ProviderMap;
|
||||||
|
|
||||||
public abstract class DaoProvider {
|
public abstract class DaoProvider {
|
||||||
public static final ProviderMap<DaoProvider> providers = new ProviderMap<>("DaoProvider");
|
public static final ProviderMap<DaoProvider> providers = new ProviderMap<>("DaoProvider");
|
||||||
public UserDAO userDAO;
|
public UserDAO userDAO;
|
||||||
public HwidDAO hwidDao;
|
|
||||||
|
|
||||||
public static void registerProviders() {
|
public static void registerProviders() {
|
||||||
providers.register("hibernate", HibernateDaoProvider.class);
|
providers.register("hibernate", HibernateDaoProvider.class);
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.dao.impl.HibernateHwidDAOImpl;
|
|
||||||
import pro.gravit.launchserver.dao.impl.UserHibernateImpl;
|
import pro.gravit.launchserver.dao.impl.UserHibernateImpl;
|
||||||
import pro.gravit.launchserver.dao.impl.UserHWIDImpl;
|
|
||||||
import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl;
|
import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl;
|
||||||
import pro.gravit.utils.helper.CommonHelper;
|
import pro.gravit.utils.helper.CommonHelper;
|
||||||
|
|
||||||
|
@ -27,7 +25,6 @@ public void init(LaunchServer server) {
|
||||||
Runnable init = () -> {
|
Runnable init = () -> {
|
||||||
Configuration cfg = new Configuration()
|
Configuration cfg = new Configuration()
|
||||||
.addAnnotatedClass(UserHibernateImpl.class)
|
.addAnnotatedClass(UserHibernateImpl.class)
|
||||||
.addAnnotatedClass(UserHWIDImpl.class)
|
|
||||||
.setProperty("hibernate.connection.driver_class", driver)
|
.setProperty("hibernate.connection.driver_class", driver)
|
||||||
.setProperty("hibernate.connection.url", url)
|
.setProperty("hibernate.connection.url", url)
|
||||||
.setProperty("hibernate.connection.username", username)
|
.setProperty("hibernate.connection.username", username)
|
||||||
|
@ -39,7 +36,6 @@ public void init(LaunchServer server) {
|
||||||
cfg.configure(Paths.get(hibernateConfig).toFile());
|
cfg.configure(Paths.get(hibernateConfig).toFile());
|
||||||
sessionFactory = cfg.buildSessionFactory();
|
sessionFactory = cfg.buildSessionFactory();
|
||||||
userDAO = new HibernateUserDAOImpl(sessionFactory);
|
userDAO = new HibernateUserDAOImpl(sessionFactory);
|
||||||
hwidDao = new HibernateHwidDAOImpl(sessionFactory);
|
|
||||||
};
|
};
|
||||||
if (parallelHibernateInit)
|
if (parallelHibernateInit)
|
||||||
CommonHelper.newThread("Hibernate Thread", true, init);
|
CommonHelper.newThread("Hibernate Thread", true, init);
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
package pro.gravit.launchserver.manangers;
|
package pro.gravit.launchserver.manangers;
|
||||||
|
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
import pro.gravit.launcher.hwid.HWIDProvider;
|
|
||||||
import pro.gravit.launcher.managers.GsonManager;
|
import pro.gravit.launcher.managers.GsonManager;
|
||||||
import pro.gravit.launcher.modules.events.PreGsonPhase;
|
import pro.gravit.launcher.modules.events.PreGsonPhase;
|
||||||
import pro.gravit.launcher.request.JsonResultSerializeAdapter;
|
import pro.gravit.launcher.request.JsonResultSerializeAdapter;
|
||||||
import pro.gravit.launcher.request.WebSocketEvent;
|
import pro.gravit.launcher.request.WebSocketEvent;
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
import pro.gravit.launcher.request.auth.AuthRequest;
|
||||||
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
||||||
import pro.gravit.launchserver.auth.hwid.HWIDHandler;
|
|
||||||
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||||
|
@ -33,11 +30,9 @@ public void registerAdapters(GsonBuilder builder) {
|
||||||
builder.registerTypeAdapter(AuthProvider.class, new UniversalJsonAdapter<>(AuthProvider.providers));
|
builder.registerTypeAdapter(AuthProvider.class, new UniversalJsonAdapter<>(AuthProvider.providers));
|
||||||
builder.registerTypeAdapter(TextureProvider.class, new UniversalJsonAdapter<>(TextureProvider.providers));
|
builder.registerTypeAdapter(TextureProvider.class, new UniversalJsonAdapter<>(TextureProvider.providers));
|
||||||
builder.registerTypeAdapter(AuthHandler.class, new UniversalJsonAdapter<>(AuthHandler.providers));
|
builder.registerTypeAdapter(AuthHandler.class, new UniversalJsonAdapter<>(AuthHandler.providers));
|
||||||
builder.registerTypeAdapter(HWIDHandler.class, new UniversalJsonAdapter<>(HWIDHandler.providers));
|
|
||||||
builder.registerTypeAdapter(Component.class, new UniversalJsonAdapter<>(Component.providers));
|
builder.registerTypeAdapter(Component.class, new UniversalJsonAdapter<>(Component.providers));
|
||||||
builder.registerTypeAdapter(ProtectHandler.class, new UniversalJsonAdapter<>(ProtectHandler.providers));
|
builder.registerTypeAdapter(ProtectHandler.class, new UniversalJsonAdapter<>(ProtectHandler.providers));
|
||||||
builder.registerTypeAdapter(DaoProvider.class, new UniversalJsonAdapter<>(DaoProvider.providers));
|
builder.registerTypeAdapter(DaoProvider.class, new UniversalJsonAdapter<>(DaoProvider.providers));
|
||||||
builder.registerTypeAdapter(HWID.class, new UniversalJsonAdapter<>(HWIDProvider.hwids));
|
|
||||||
builder.registerTypeAdapter(WebSocketServerResponse.class, new UniversalJsonAdapter<>(WebSocketService.providers));
|
builder.registerTypeAdapter(WebSocketServerResponse.class, new UniversalJsonAdapter<>(WebSocketService.providers));
|
||||||
builder.registerTypeAdapter(WebSocketEvent.class, new JsonResultSerializeAdapter());
|
builder.registerTypeAdapter(WebSocketEvent.class, new JsonResultSerializeAdapter());
|
||||||
builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers));
|
builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers));
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package pro.gravit.launchserver.modules.events.security;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.events.request.SecurityReportRequestEvent;
|
||||||
|
import pro.gravit.launcher.modules.LauncherModule;
|
||||||
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
import pro.gravit.launchserver.socket.response.secure.SecurityReportResponse;
|
||||||
|
|
||||||
|
public class SecurityReportModuleEvent extends LauncherModule.Event {
|
||||||
|
public final SecurityReportRequestEvent event;
|
||||||
|
public final SecurityReportResponse response;
|
||||||
|
public final Client client;
|
||||||
|
|
||||||
|
public SecurityReportModuleEvent(SecurityReportRequestEvent event, SecurityReportResponse response, Client client) {
|
||||||
|
this.event = event;
|
||||||
|
this.response = response;
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,4 +19,9 @@ public void init(LauncherInitContext initContext) {
|
||||||
public void testEvent(InitPhase event) {
|
public void testEvent(InitPhase event) {
|
||||||
//LogHelper.debug("[LaunchServerCore] Event LaunchServerInitPhase passed");
|
//LogHelper.debug("[LaunchServerCore] Event LaunchServerInitPhase passed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Event> boolean registerEvent(EventHandler<T> handle, Class<T> tClass) {
|
||||||
|
return super.registerEvent(handle, tClass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,9 @@ public class Client {
|
||||||
public ClientProfile profile;
|
public ClientProfile profile;
|
||||||
public boolean isAuth;
|
public boolean isAuth;
|
||||||
public boolean checkSign;
|
public boolean checkSign;
|
||||||
public boolean isSecure;
|
|
||||||
public ClientPermissions permissions;
|
public ClientPermissions permissions;
|
||||||
public String username;
|
public String username;
|
||||||
public String verifyToken;
|
public TrustLevel trustLevel;
|
||||||
public transient LogHelper.OutputEnity logOutput;
|
public transient LogHelper.OutputEnity logOutput;
|
||||||
|
|
||||||
public transient AuthProviderPair auth;
|
public transient AuthProviderPair auth;
|
||||||
|
@ -48,4 +47,10 @@ public enum Type {
|
||||||
SERVER,
|
SERVER,
|
||||||
USER
|
USER
|
||||||
}
|
}
|
||||||
|
public static class TrustLevel
|
||||||
|
{
|
||||||
|
public byte[] verifySecureKey;
|
||||||
|
public boolean keyChecked;
|
||||||
|
public byte[] publicKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,9 @@
|
||||||
import pro.gravit.launchserver.socket.response.profile.BatchProfileByUsername;
|
import pro.gravit.launchserver.socket.response.profile.BatchProfileByUsername;
|
||||||
import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse;
|
import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse;
|
||||||
import pro.gravit.launchserver.socket.response.profile.ProfileByUsername;
|
import pro.gravit.launchserver.socket.response.profile.ProfileByUsername;
|
||||||
import pro.gravit.launchserver.socket.response.secure.GetSecureTokenResponse;
|
import pro.gravit.launchserver.socket.response.secure.GetSecureLevelInfoResponse;
|
||||||
import pro.gravit.launchserver.socket.response.secure.VerifySecureTokenResponse;
|
import pro.gravit.launchserver.socket.response.secure.SecurityReportResponse;
|
||||||
|
import pro.gravit.launchserver.socket.response.secure.VerifySecureLevelKeyResponse;
|
||||||
import pro.gravit.launchserver.socket.response.update.LauncherResponse;
|
import pro.gravit.launchserver.socket.response.update.LauncherResponse;
|
||||||
import pro.gravit.launchserver.socket.response.update.UpdateListResponse;
|
import pro.gravit.launchserver.socket.response.update.UpdateListResponse;
|
||||||
import pro.gravit.launchserver.socket.response.update.UpdateResponse;
|
import pro.gravit.launchserver.socket.response.update.UpdateResponse;
|
||||||
|
@ -123,12 +124,13 @@ public static void registerResponses() {
|
||||||
providers.register("batchProfileByUsername", BatchProfileByUsername.class);
|
providers.register("batchProfileByUsername", BatchProfileByUsername.class);
|
||||||
providers.register("profileByUsername", ProfileByUsername.class);
|
providers.register("profileByUsername", ProfileByUsername.class);
|
||||||
providers.register("profileByUUID", ProfileByUUIDResponse.class);
|
providers.register("profileByUUID", ProfileByUUIDResponse.class);
|
||||||
providers.register("getSecureToken", GetSecureTokenResponse.class);
|
|
||||||
providers.register("verifySecureToken", VerifySecureTokenResponse.class);
|
|
||||||
providers.register("getAvailabilityAuth", GetAvailabilityAuthResponse.class);
|
providers.register("getAvailabilityAuth", GetAvailabilityAuthResponse.class);
|
||||||
providers.register("register", RegisterResponse.class);
|
providers.register("register", RegisterResponse.class);
|
||||||
providers.register("setPassword", SetPasswordResponse.class);
|
providers.register("setPassword", SetPasswordResponse.class);
|
||||||
providers.register("exit", ExitResponse.class);
|
providers.register("exit", ExitResponse.class);
|
||||||
|
providers.register("getSecureLevelInfo", GetSecureLevelInfoResponse.class);
|
||||||
|
providers.register("verifySecureLevelKey", VerifySecureLevelKeyResponse.class);
|
||||||
|
providers.register("securityReport", SecurityReportResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendObject(ChannelHandlerContext ctx, Object obj) {
|
public void sendObject(ChannelHandlerContext ctx, Object obj) {
|
||||||
|
|
|
@ -2,15 +2,12 @@
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import pro.gravit.launcher.events.request.AuthRequestEvent;
|
import pro.gravit.launcher.events.request.AuthRequestEvent;
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
import pro.gravit.launcher.hwid.NoHWID;
|
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
import pro.gravit.launcher.request.auth.AuthRequest;
|
||||||
import pro.gravit.launcher.request.auth.password.AuthECPassword;
|
import pro.gravit.launcher.request.auth.password.AuthECPassword;
|
||||||
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
|
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
import pro.gravit.launchserver.auth.AuthException;
|
||||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||||
import pro.gravit.launchserver.auth.hwid.HWIDException;
|
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProviderResult;
|
import pro.gravit.launchserver.auth.provider.AuthProviderResult;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
@ -39,7 +36,6 @@ public class AuthResponse extends SimpleResponse {
|
||||||
|
|
||||||
public String auth_id;
|
public String auth_id;
|
||||||
public ConnectTypes authType;
|
public ConnectTypes authType;
|
||||||
public HWID hwid;
|
|
||||||
|
|
||||||
public enum ConnectTypes {
|
public enum ConnectTypes {
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@ -69,7 +65,6 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
||||||
throw new AuthException("Password decryption error");
|
throw new AuthException("Password decryption error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(hwid == null) hwid = new NoHWID();
|
|
||||||
AuthProviderPair pair;
|
AuthProviderPair pair;
|
||||||
if (auth_id.isEmpty()) pair = server.config.getAuthProviderPair();
|
if (auth_id.isEmpty()) pair = server.config.getAuthProviderPair();
|
||||||
else pair = server.config.getAuthProviderPair(auth_id);
|
else pair = server.config.getAuthProviderPair(auth_id);
|
||||||
|
@ -78,7 +73,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
||||||
sendError("auth_id incorrect");
|
sendError("auth_id incorrect");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AuthContext context = new AuthContext(clientData, login, client, hwid, ip, authType);
|
AuthContext context = new AuthContext(clientData, login, client, ip, authType);
|
||||||
AuthProvider provider = pair.provider;
|
AuthProvider provider = pair.provider;
|
||||||
server.authHookManager.preHook.hook(context, clientData);
|
server.authHookManager.preHook.hook(context, clientData);
|
||||||
provider.preAuth(login, password, ip);
|
provider.preAuth(login, password, ip);
|
||||||
|
@ -87,20 +82,9 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
||||||
AuthProvider.authError(String.format("Illegal result: '%s'", aresult.username));
|
AuthProvider.authError(String.format("Illegal result: '%s'", aresult.username));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Collection<ClientProfile> profiles = server.getProfiles();
|
|
||||||
for (ClientProfile p : profiles) {
|
|
||||||
if (p.getTitle().equals(client)) {
|
|
||||||
if (!p.isWhitelistContains(login)) {
|
|
||||||
throw new AuthException(server.config.whitelistRejectString);
|
|
||||||
}
|
|
||||||
clientData.profile = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//if (clientData.profile == null) {
|
//if (clientData.profile == null) {
|
||||||
// throw new AuthException("You profile not found");
|
// throw new AuthException("You profile not found");
|
||||||
//}
|
//}
|
||||||
if (authType == ConnectTypes.CLIENT)
|
|
||||||
pair.hwid.check(hwid, aresult.username);
|
|
||||||
server.authHookManager.postHook.hook(context, clientData);
|
server.authHookManager.postHook.hook(context, clientData);
|
||||||
clientData.isAuth = true;
|
clientData.isAuth = true;
|
||||||
clientData.permissions = aresult.permissions;
|
clientData.permissions = aresult.permissions;
|
||||||
|
@ -128,17 +112,16 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
||||||
}
|
}
|
||||||
clientData.type = authType;
|
clientData.type = authType;
|
||||||
sendResult(result);
|
sendResult(result);
|
||||||
} catch (AuthException | HWIDException | HookException e) {
|
} catch (AuthException | HookException e) {
|
||||||
sendError(e.getMessage());
|
sendError(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AuthContext {
|
public static class AuthContext {
|
||||||
public AuthContext(Client client, String login, String profileName, HWID hwid, String ip, ConnectTypes authType) {
|
public AuthContext(Client client, String login, String profileName, String ip, ConnectTypes authType) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.login = login;
|
this.login = login;
|
||||||
this.profileName = profileName;
|
this.profileName = profileName;
|
||||||
this.hwid = hwid;
|
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
this.authType = authType;
|
this.authType = authType;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +130,6 @@ public AuthContext(Client client, String login, String profileName, HWID hwid, S
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int password_length; //Use AuthProvider for get password
|
public int password_length; //Use AuthProvider for get password
|
||||||
public final String profileName;
|
public final String profileName;
|
||||||
public final HWID hwid;
|
|
||||||
public final String ip;
|
public final String ip;
|
||||||
public final ConnectTypes authType;
|
public final ConnectTypes authType;
|
||||||
public final Client client;
|
public final Client client;
|
||||||
|
|
|
@ -36,7 +36,6 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Client newClient = new Client(0);
|
Client newClient = new Client(0);
|
||||||
newClient.isSecure = client.isSecure;
|
|
||||||
newClient.checkSign = client.checkSign;
|
newClient.checkSign = client.checkSign;
|
||||||
handler.setClient(newClient);
|
handler.setClient(newClient);
|
||||||
if(client.session != 0) server.sessionManager.removeClient(client.session);
|
if(client.session != 0) server.sessionManager.removeClient(client.session);
|
||||||
|
@ -56,7 +55,6 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
if(chClient.session != client.session) return;
|
if(chClient.session != client.session) return;
|
||||||
}
|
}
|
||||||
Client newCusClient = new Client(0);
|
Client newCusClient = new Client(0);
|
||||||
newCusClient.isSecure = chClient.isSecure;
|
|
||||||
newCusClient.checkSign = chClient.checkSign;
|
newCusClient.checkSign = chClient.checkSign;
|
||||||
wsHandler.setClient(newCusClient);
|
wsHandler.setClient(newCusClient);
|
||||||
if(chClient.session != 0) server.sessionManager.removeClient(chClient.session);
|
if(chClient.session != 0) server.sessionManager.removeClient(chClient.session);
|
||||||
|
@ -76,7 +74,6 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
Client chClient = wsHandler.getClient();
|
Client chClient = wsHandler.getClient();
|
||||||
if(!chClient.isAuth || !username.equals(chClient.username)) return;
|
if(!chClient.isAuth || !username.equals(chClient.username)) return;
|
||||||
Client newCusClient = new Client(0);
|
Client newCusClient = new Client(0);
|
||||||
newCusClient.isSecure = chClient.isSecure;
|
|
||||||
newCusClient.checkSign = chClient.checkSign;
|
newCusClient.checkSign = chClient.checkSign;
|
||||||
wsHandler.setClient(newCusClient);
|
wsHandler.setClient(newCusClient);
|
||||||
if(chClient.session != 0) server.sessionManager.removeClient(chClient.session);
|
if(chClient.session != 0) server.sessionManager.removeClient(chClient.session);
|
||||||
|
|
|
@ -3,9 +3,14 @@
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import pro.gravit.launcher.events.request.ErrorRequestEvent;
|
import pro.gravit.launcher.events.request.ErrorRequestEvent;
|
||||||
import pro.gravit.launcher.events.request.ProfilesRequestEvent;
|
import pro.gravit.launcher.events.request.ProfilesRequestEvent;
|
||||||
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
|
import pro.gravit.launchserver.auth.protect.interfaces.ProfilesProtectHandler;
|
||||||
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;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ProfilesResponse extends SimpleResponse {
|
public class ProfilesResponse extends SimpleResponse {
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
|
@ -14,10 +19,29 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
if (!client.checkSign && !client.isAuth) {
|
if (server.config.protectHandler instanceof ProfilesProtectHandler && !((ProfilesProtectHandler) server.config.protectHandler).canGetProfiles(client)) {
|
||||||
service.sendObject(ctx, new ErrorRequestEvent("Access denied"));
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sendResult(new ProfilesRequestEvent(server.getProfiles()));
|
|
||||||
|
List<ClientProfile> profileList;
|
||||||
|
List<ClientProfile> serverProfiles = server.getProfiles();
|
||||||
|
if (server.config.protectHandler instanceof ProfilesProtectHandler)
|
||||||
|
{
|
||||||
|
ProfilesProtectHandler protectHandler = (ProfilesProtectHandler) server.config.protectHandler;
|
||||||
|
profileList = new ArrayList<>(4);
|
||||||
|
for(ClientProfile profile : serverProfiles)
|
||||||
|
{
|
||||||
|
if(protectHandler.canGetProfile(profile, client))
|
||||||
|
{
|
||||||
|
profileList.add(profile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
profileList = serverProfiles;
|
||||||
|
}
|
||||||
|
sendResult(new ProfilesRequestEvent(profileList));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import pro.gravit.launcher.events.request.SetProfileRequestEvent;
|
import pro.gravit.launcher.events.request.SetProfileRequestEvent;
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
|
import pro.gravit.launchserver.auth.protect.interfaces.ProfilesProtectHandler;
|
||||||
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;
|
||||||
import pro.gravit.utils.HookException;
|
import pro.gravit.utils.HookException;
|
||||||
|
@ -19,10 +20,6 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
if (!client.isAuth) {
|
|
||||||
sendError("Access denied");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
server.authHookManager.setProfileHook.hook(this, client);
|
server.authHookManager.setProfileHook.hook(this, client);
|
||||||
} catch (HookException e) {
|
} catch (HookException e) {
|
||||||
|
@ -31,8 +28,9 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
Collection<ClientProfile> profiles = server.getProfiles();
|
Collection<ClientProfile> profiles = server.getProfiles();
|
||||||
for (ClientProfile p : profiles) {
|
for (ClientProfile p : profiles) {
|
||||||
if (p.getTitle().equals(this.client)) {
|
if (p.getTitle().equals(this.client)) {
|
||||||
if (!p.isWhitelistContains(client.username)) {
|
if (server.config.protectHandler instanceof ProfilesProtectHandler &&
|
||||||
sendError(server.config.whitelistRejectString);
|
!((ProfilesProtectHandler) server.config.protectHandler).canChangeProfile(p, client)) {
|
||||||
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
client.profile = p;
|
client.profile = p;
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package pro.gravit.launchserver.socket.response.secure;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import pro.gravit.launcher.events.request.GetSecureLevelInfoRequestEvent;
|
||||||
|
import pro.gravit.launchserver.auth.protect.interfaces.SecureProtectHandler;
|
||||||
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||||
|
|
||||||
|
public class GetSecureLevelInfoResponse extends SimpleResponse {
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "getSecureLevelInfo";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
|
if(!(server.config.protectHandler instanceof SecureProtectHandler))
|
||||||
|
{
|
||||||
|
GetSecureLevelInfoRequestEvent response = new GetSecureLevelInfoRequestEvent(null);
|
||||||
|
response.enabled = false;
|
||||||
|
sendResult(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SecureProtectHandler secureProtectHandler = (SecureProtectHandler) server.config.protectHandler;
|
||||||
|
if(!secureProtectHandler.allowGetSecureLevelInfo(client))
|
||||||
|
{
|
||||||
|
sendError("Access denied");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(client.trustLevel == null) client.trustLevel = new Client.TrustLevel();
|
||||||
|
if(client.trustLevel.verifySecureKey == null) client.trustLevel.verifySecureKey = secureProtectHandler.generateSecureLevelKey();
|
||||||
|
GetSecureLevelInfoRequestEvent response = new GetSecureLevelInfoRequestEvent(client.trustLevel.verifySecureKey);
|
||||||
|
response.enabled = true;
|
||||||
|
sendResult(secureProtectHandler.onGetSecureLevelInfo(response));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +0,0 @@
|
||||||
package pro.gravit.launchserver.socket.response.secure;
|
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import pro.gravit.launcher.events.request.GetSecureTokenRequestEvent;
|
|
||||||
import pro.gravit.launchserver.socket.Client;
|
|
||||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
|
||||||
|
|
||||||
public class GetSecureTokenResponse extends SimpleResponse {
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return "getSecureToken";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
|
||||||
String secureToken = server.config.protectHandler.generateClientSecureToken();
|
|
||||||
client.verifyToken = secureToken;
|
|
||||||
sendResult(new GetSecureTokenRequestEvent(secureToken));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package pro.gravit.launchserver.socket.response.secure;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import pro.gravit.launcher.events.request.SecurityReportRequestEvent;
|
||||||
|
import pro.gravit.launchserver.auth.protect.interfaces.SecureProtectHandler;
|
||||||
|
import pro.gravit.launchserver.modules.events.security.SecurityReportModuleEvent;
|
||||||
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||||
|
|
||||||
|
public class SecurityReportResponse extends SimpleResponse {
|
||||||
|
public String reportType;
|
||||||
|
public String smallData;
|
||||||
|
public String largeData;
|
||||||
|
public byte[] smallBytes;
|
||||||
|
public byte[] largeBytes;
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "securityReport";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
|
if(!(server.config.protectHandler instanceof SecureProtectHandler))
|
||||||
|
{
|
||||||
|
sendError("Method not allowed");
|
||||||
|
}
|
||||||
|
SecureProtectHandler secureProtectHandler = (SecureProtectHandler) server.config.protectHandler;
|
||||||
|
SecurityReportRequestEvent event = secureProtectHandler.onSecurityReport(this, client);
|
||||||
|
server.modulesManager.invokeEvent(new SecurityReportModuleEvent(event, this, client));
|
||||||
|
sendResult(event);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package pro.gravit.launchserver.socket.response.secure;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import pro.gravit.launcher.events.request.VerifySecureLevelKeyRequestEvent;
|
||||||
|
import pro.gravit.launchserver.auth.protect.interfaces.SecureProtectHandler;
|
||||||
|
import pro.gravit.launchserver.socket.Client;
|
||||||
|
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||||
|
|
||||||
|
import java.security.SignatureException;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
|
||||||
|
public class VerifySecureLevelKeyResponse extends SimpleResponse {
|
||||||
|
public byte[] publicKey;
|
||||||
|
public byte[] signature;
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "verifySecureLevelKey";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
|
if(!(server.config.protectHandler instanceof SecureProtectHandler) || client.trustLevel == null || client.trustLevel.verifySecureKey == null)
|
||||||
|
{
|
||||||
|
sendError("This method not allowed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SecureProtectHandler secureProtectHandler = (SecureProtectHandler) server.config.protectHandler;
|
||||||
|
try {
|
||||||
|
secureProtectHandler.verifySecureLevelKey(publicKey, client.trustLevel.verifySecureKey, signature);
|
||||||
|
} catch (InvalidKeySpecException e)
|
||||||
|
{
|
||||||
|
sendError("Invalid public key");
|
||||||
|
return;
|
||||||
|
} catch (SignatureException e)
|
||||||
|
{
|
||||||
|
sendError("Invalid signature");
|
||||||
|
return;
|
||||||
|
} catch (SecurityException e)
|
||||||
|
{
|
||||||
|
sendError(e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client.trustLevel.keyChecked = true;
|
||||||
|
client.trustLevel.publicKey = publicKey;
|
||||||
|
sendResult(new VerifySecureLevelKeyRequestEvent());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +0,0 @@
|
||||||
package pro.gravit.launchserver.socket.response.secure;
|
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import pro.gravit.launcher.events.request.VerifySecureTokenRequestEvent;
|
|
||||||
import pro.gravit.launchserver.socket.Client;
|
|
||||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
|
||||||
|
|
||||||
public class VerifySecureTokenResponse extends SimpleResponse {
|
|
||||||
public String secureToken;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return "verifySecureToken";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
|
||||||
boolean success = server.config.protectHandler.verifyClientSecureToken(secureToken, client.verifyToken);
|
|
||||||
if (success) client.isSecure = true;
|
|
||||||
sendResult(new VerifySecureTokenRequestEvent(success));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -36,9 +36,8 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
byte[] hash = server.launcherBinary.getDigest();
|
byte[] hash = server.launcherBinary.getDigest();
|
||||||
if (hash == null)
|
if (hash == null)
|
||||||
service.sendObjectAndClose(ctx, new LauncherRequestEvent(true, server.config.netty.launcherURL));
|
service.sendObjectAndClose(ctx, new LauncherRequestEvent(true, server.config.netty.launcherURL));
|
||||||
if (Arrays.equals(bytes, hash)) {
|
if (Arrays.equals(bytes, hash) && checkSecure(secureHash, secureSalt)) {
|
||||||
client.checkSign = true;
|
client.checkSign = true;
|
||||||
client.isSecure = checkSecure(secureHash, secureSalt);
|
|
||||||
sendResult(new LauncherRequestEvent(false, server.config.netty.launcherURL));
|
sendResult(new LauncherRequestEvent(false, server.config.netty.launcherURL));
|
||||||
} else {
|
} else {
|
||||||
sendResultAndClose(new LauncherRequestEvent(true, server.config.netty.launcherURL));
|
sendResultAndClose(new LauncherRequestEvent(true, server.config.netty.launcherURL));
|
||||||
|
@ -47,9 +46,8 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
{
|
{
|
||||||
byte[] hash = server.launcherEXEBinary.getDigest();
|
byte[] hash = server.launcherEXEBinary.getDigest();
|
||||||
if (hash == null) sendResultAndClose(new LauncherRequestEvent(true, server.config.netty.launcherEXEURL));
|
if (hash == null) sendResultAndClose(new LauncherRequestEvent(true, server.config.netty.launcherEXEURL));
|
||||||
if (Arrays.equals(bytes, hash)) {
|
if (Arrays.equals(bytes, hash) && checkSecure(secureHash, secureSalt)) {
|
||||||
client.checkSign = true;
|
client.checkSign = true;
|
||||||
client.isSecure = checkSecure(secureHash, secureSalt);
|
|
||||||
sendResult(new LauncherRequestEvent(false, server.config.netty.launcherEXEURL));
|
sendResult(new LauncherRequestEvent(false, server.config.netty.launcherEXEURL));
|
||||||
} else {
|
} else {
|
||||||
sendResultAndClose(new LauncherRequestEvent(true, server.config.netty.launcherEXEURL));
|
sendResultAndClose(new LauncherRequestEvent(true, server.config.netty.launcherEXEURL));
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import pro.gravit.launcher.events.request.UpdateRequestEvent;
|
import pro.gravit.launcher.events.request.UpdateRequestEvent;
|
||||||
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.launchserver.auth.protect.interfaces.ProfilesProtectHandler;
|
||||||
import pro.gravit.launchserver.config.LaunchServerConfig;
|
import pro.gravit.launchserver.config.LaunchServerConfig;
|
||||||
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,19 +21,10 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
if (!client.isAuth || client.type != AuthResponse.ConnectTypes.CLIENT || client.profile == null) {
|
if (server.config.protectHandler instanceof ProfilesProtectHandler && !((ProfilesProtectHandler) server.config.protectHandler).canGetUpdates(dirName, client)) {
|
||||||
sendError("Access denied");
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!client.permissions.canAdmin) {
|
|
||||||
for (ClientProfile p : server.getProfiles()) {
|
|
||||||
if (!client.profile.getTitle().equals(p.getTitle())) continue;
|
|
||||||
if (!p.isWhitelistContains(client.username)) {
|
|
||||||
sendError("You don't download this folder");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HashedDir dir = server.updatesDirMap.get(dirName);
|
HashedDir dir = server.updatesDirMap.get(dirName);
|
||||||
if (dir == null) {
|
if (dir == null) {
|
||||||
sendError(String.format("Directory %s not found", dirName));
|
sendError(String.format("Directory %s not found", dirName));
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
-target 8
|
-target 8
|
||||||
-forceprocessing
|
-forceprocessing
|
||||||
|
|
||||||
-overloadaggressively
|
|
||||||
-repackageclasses 'pro.gravit.launcher'
|
-repackageclasses 'pro.gravit.launcher'
|
||||||
-keepattributes SourceFile,LineNumberTable,*Annotation*
|
-keepattributes SourceFile,LineNumberTable,*Annotation*
|
||||||
-renamesourcefileattribute SourceFile
|
-renamesourcefileattribute SourceFile
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
import pro.gravit.launchserver.asm.InjectClassAcceptor;
|
import pro.gravit.launchserver.asm.InjectClassAcceptor;
|
||||||
import pro.gravit.utils.helper.JarHelper;
|
import pro.gravit.utils.helper.JarHelper;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -38,11 +40,11 @@ public static class TestClass
|
||||||
public Map<String, String> map;
|
public Map<String, String> map;
|
||||||
}
|
}
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void prepare() throws Exception {
|
public static void prepare() throws Throwable {
|
||||||
classLoader = new ASMClassLoader(ASMTransformersTest.class.getClassLoader());
|
classLoader = new ASMClassLoader(ASMTransformersTest.class.getClassLoader());
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void testASM() throws Exception
|
void testASM() throws Throwable
|
||||||
{
|
{
|
||||||
ClassReader reader = new ClassReader(JarHelper.getClassBytes(TestClass.class));
|
ClassReader reader = new ClassReader(JarHelper.getClassBytes(TestClass.class));
|
||||||
ClassNode node = new ClassNode();
|
ClassNode node = new ClassNode();
|
||||||
|
@ -65,15 +67,13 @@ void testASM() throws Exception
|
||||||
byte[] bytes = writer.toByteArray();
|
byte[] bytes = writer.toByteArray();
|
||||||
classLoader.rawDefineClass("ASMTestClass", bytes, 0, bytes.length);
|
classLoader.rawDefineClass("ASMTestClass", bytes, 0, bytes.length);
|
||||||
Class<?> clazz = classLoader.loadClass("ASMTestClass");
|
Class<?> clazz = classLoader.loadClass("ASMTestClass");
|
||||||
Object instance = clazz.newInstance();
|
Object instance = MethodHandles.publicLookup().findConstructor(clazz, MethodType.methodType(void.class)).invoke();
|
||||||
Field field = clazz.getField("test");
|
Assertions.assertEquals(1234, (int)
|
||||||
Object result = field.get(instance);
|
MethodHandles.publicLookup().findGetter(clazz, "test", int.class).invoke(instance));
|
||||||
Assertions.assertEquals(1234, (int) (Integer) result);
|
Assertions.assertEquals(strings, (List<String>)
|
||||||
field = clazz.getField("s");
|
MethodHandles.publicLookup().findGetter(clazz, "s", List.class).invoke(instance));
|
||||||
result = field.get(instance);
|
|
||||||
Assertions.assertEquals(strings, result);
|
Assertions.assertEquals(byteMap, (Map<String, Object>)
|
||||||
field = clazz.getField("map");
|
MethodHandles.publicLookup().findGetter(clazz, "map", Map.class).invoke(instance));
|
||||||
result = field.get(instance);
|
|
||||||
Assertions.assertEquals(byteMap, result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,9 +53,9 @@ task javadocJar(type: Jar) {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
pack project(':LauncherAPI')
|
pack project(':LauncherAPI')
|
||||||
bundle 'com.github.oshi:oshi-core:3.13.0'
|
bundle group: 'com.github.oshi', name: 'oshi-core', version: rootProject['verOshiCore']
|
||||||
pack 'io.netty:netty-codec-http:4.1.43.Final'
|
pack group: 'io.netty', name: 'netty-codec-http', version: rootProject['verNetty']
|
||||||
pack 'org.ow2.asm:asm-tree:7.1'
|
pack group: 'org.ow2.asm', name: 'asm-tree', version: rootProject['verAsm']
|
||||||
}
|
}
|
||||||
|
|
||||||
task genRuntimeJS(type: Zip) {
|
task genRuntimeJS(type: Zip) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
||||||
Path javaBin = IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
Path javaBin = IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
||||||
List<String> args = new LinkedList<>();
|
List<String> args = new LinkedList<>();
|
||||||
args.add(javaBin.toString());
|
args.add(javaBin.toString());
|
||||||
String pathLauncher = IOHelper.getCodeSource(ClientLauncher.class).toString();
|
String pathLauncher = IOHelper.getCodeSource(LauncherEngine.class).toString();
|
||||||
args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
||||||
args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled())));
|
args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled())));
|
||||||
args.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, Boolean.toString(LogHelper.isDevEnabled())));
|
args.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, Boolean.toString(LogHelper.isDevEnabled())));
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
import pro.gravit.launcher.guard.LauncherGuardManager;
|
import pro.gravit.launcher.guard.LauncherGuardManager;
|
||||||
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.hwid.HWIDProvider;
|
|
||||||
import pro.gravit.launcher.managers.ClientGsonManager;
|
import pro.gravit.launcher.managers.ClientGsonManager;
|
||||||
import pro.gravit.launcher.managers.ClientHookManager;
|
import pro.gravit.launcher.managers.ClientHookManager;
|
||||||
import pro.gravit.launcher.managers.ConsoleManager;
|
import pro.gravit.launcher.managers.ConsoleManager;
|
||||||
|
@ -40,6 +39,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 void checkClass(Class<?> clazz) throws SecurityException {
|
public static void checkClass(Class<?> clazz) throws SecurityException {
|
||||||
LauncherTrustManager trustManager = Launcher.getConfig().trustManager;
|
LauncherTrustManager trustManager = Launcher.getConfig().trustManager;
|
||||||
|
@ -76,14 +76,13 @@ public static void main(String... args) throws Throwable {
|
||||||
LogHelper.printLicense("Launcher");
|
LogHelper.printLicense("Launcher");
|
||||||
LauncherEngine.checkClass(LauncherEngine.class);
|
LauncherEngine.checkClass(LauncherEngine.class);
|
||||||
LauncherEngine.checkClass(LauncherAgent.class);
|
LauncherEngine.checkClass(LauncherAgent.class);
|
||||||
LauncherEngine.checkClass(ClientLauncher.class);
|
LauncherEngine.checkClass(ClientLauncherEntryPoint.class);
|
||||||
LauncherEngine.modulesManager = new ClientModuleManager();
|
LauncherEngine.modulesManager = new ClientModuleManager();
|
||||||
LauncherConfig.initModules(LauncherEngine.modulesManager);
|
LauncherConfig.initModules(LauncherEngine.modulesManager);
|
||||||
LauncherEngine.modulesManager.initModules(null);
|
LauncherEngine.modulesManager.initModules(null);
|
||||||
// Start Launcher
|
// Start Launcher
|
||||||
initGson(LauncherEngine.modulesManager);
|
initGson(LauncherEngine.modulesManager);
|
||||||
ConsoleManager.initConsole();
|
ConsoleManager.initConsole();
|
||||||
HWIDProvider.registerHWIDs();
|
|
||||||
LauncherEngine.modulesManager.invokeEvent(new PreConfigPhase());
|
LauncherEngine.modulesManager.invokeEvent(new PreConfigPhase());
|
||||||
Launcher.getConfig(); // init config
|
Launcher.getConfig(); // init config
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
|
@ -3,14 +3,12 @@
|
||||||
import pro.gravit.launcher.*;
|
import pro.gravit.launcher.*;
|
||||||
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.api.SystemService;
|
|
||||||
import pro.gravit.launcher.client.events.ClientLaunchPhase;
|
import pro.gravit.launcher.client.events.ClientLaunchPhase;
|
||||||
import pro.gravit.launcher.client.events.ClientLauncherInitPhase;
|
import pro.gravit.launcher.client.events.ClientLauncherInitPhase;
|
||||||
import pro.gravit.launcher.client.events.ClientLauncherPostInitPhase;
|
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;
|
||||||
import pro.gravit.launcher.hwid.HWIDProvider;
|
|
||||||
import pro.gravit.launcher.managers.ClientGsonManager;
|
import pro.gravit.launcher.managers.ClientGsonManager;
|
||||||
import pro.gravit.launcher.managers.ClientHookManager;
|
import pro.gravit.launcher.managers.ClientHookManager;
|
||||||
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
||||||
|
@ -457,7 +455,6 @@ public static void main(String... args) throws Throwable {
|
||||||
JVMHelper.checkStackTrace(ClientLauncher.class);
|
JVMHelper.checkStackTrace(ClientLauncher.class);
|
||||||
LogHelper.printVersion("Client Launcher");
|
LogHelper.printVersion("Client Launcher");
|
||||||
engine.readKeys();
|
engine.readKeys();
|
||||||
HWIDProvider.registerHWIDs();
|
|
||||||
LauncherGuardManager.initGuard(true);
|
LauncherGuardManager.initGuard(true);
|
||||||
LogHelper.debug("Reading ClientLauncher params");
|
LogHelper.debug("Reading ClientLauncher params");
|
||||||
ParamContainer p = container.read();
|
ParamContainer p = container.read();
|
||||||
|
|
|
@ -0,0 +1,262 @@
|
||||||
|
package pro.gravit.launcher.client;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.Launcher;
|
||||||
|
import pro.gravit.launcher.LauncherAgent;
|
||||||
|
import pro.gravit.launcher.LauncherConfig;
|
||||||
|
import pro.gravit.launcher.LauncherEngine;
|
||||||
|
import pro.gravit.launcher.api.AuthService;
|
||||||
|
import pro.gravit.launcher.api.ClientService;
|
||||||
|
import pro.gravit.launcher.client.events.ClientLaunchPhase;
|
||||||
|
import pro.gravit.launcher.client.events.ClientLauncherInitPhase;
|
||||||
|
import pro.gravit.launcher.client.events.ClientLauncherPostInitPhase;
|
||||||
|
import pro.gravit.launcher.guard.LauncherGuardManager;
|
||||||
|
import pro.gravit.launcher.hasher.FileNameMatcher;
|
||||||
|
import pro.gravit.launcher.hasher.HashedDir;
|
||||||
|
import pro.gravit.launcher.managers.ClientGsonManager;
|
||||||
|
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
||||||
|
import pro.gravit.launcher.patches.FMLPatcher;
|
||||||
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
|
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.utils.DirWatcher;
|
||||||
|
import pro.gravit.utils.helper.*;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
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.Paths;
|
||||||
|
import java.nio.file.SimpleFileVisitor;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class ClientLauncherEntryPoint {
|
||||||
|
private static ClientLauncherProcess.ClientParams readParams(SocketAddress address) throws IOException {
|
||||||
|
try (Socket socket = IOHelper.newSocket())
|
||||||
|
{
|
||||||
|
socket.connect(address);
|
||||||
|
try(HInput input = new HInput(socket.getInputStream()))
|
||||||
|
{
|
||||||
|
byte[] serialized = input.readByteArray(0);
|
||||||
|
ClientLauncherProcess.ClientParams params = Launcher.gsonManager.gson.fromJson(new String(serialized, IOHelper.UNICODE_CHARSET), ClientLauncherProcess.ClientParams.class);
|
||||||
|
params.clientHDir = new HashedDir(input);
|
||||||
|
params.assetHDir = new HashedDir(input);
|
||||||
|
params.javaHDir = new HashedDir(input);
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static ClientClassLoader classLoader;
|
||||||
|
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(ClientLauncherEntryPoint.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(ClientLauncherEntryPoint.class, true);
|
||||||
|
EnvHelper.checkDangerousParams();
|
||||||
|
JVMHelper.checkStackTrace(ClientLauncherEntryPoint.class);
|
||||||
|
LogHelper.printVersion("Client Launcher");
|
||||||
|
engine.readKeys();
|
||||||
|
LauncherGuardManager.initGuard(true);
|
||||||
|
LogHelper.debug("Reading ClientLauncher params");
|
||||||
|
ClientLauncherProcess.ClientParams params = readParams(new InetSocketAddress("127.0.0.1", Launcher.getConfig().clientPort));
|
||||||
|
ClientProfile profile = params.profile;
|
||||||
|
Launcher.profile = profile;
|
||||||
|
AuthService.profile = profile;
|
||||||
|
LauncherEngine.clientParams = params;
|
||||||
|
Request.setSession(params.session);
|
||||||
|
checkJVMBitsAndVersion();
|
||||||
|
LauncherEngine.modulesManager.invokeEvent(new ClientLauncherInitPhase(null));
|
||||||
|
|
||||||
|
Path clientDir = Paths.get(params.clientDir);
|
||||||
|
Path assetDir = Paths.get(params.assetDir);
|
||||||
|
|
||||||
|
// Verify ClientLauncher sign and classpath
|
||||||
|
LogHelper.debug("Verifying ClientLauncher sign and classpath");
|
||||||
|
List<URL> classpath = new LinkedList<>();
|
||||||
|
resolveClassPathStream(clientDir, params.profile.getClassPath()).map(IOHelper::toURL).collect(Collectors.toCollection(() -> classpath));
|
||||||
|
|
||||||
|
params.profile.pushOptionalClassPath((opt) -> {
|
||||||
|
resolveClassPathStream(clientDir, opt).map(IOHelper::toURL).collect(Collectors.toCollection(() -> classpath));
|
||||||
|
});
|
||||||
|
classLoader = new ClientClassLoader(classpath.toArray(new URL[0]), ClassLoader.getSystemClassLoader());
|
||||||
|
Thread.currentThread().setContextClassLoader(classLoader);
|
||||||
|
classLoader.nativePath = clientDir.resolve("natives").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.playerProfile.username;
|
||||||
|
AuthService.uuid = params.playerProfile.uuid;
|
||||||
|
ClientService.classLoader = classLoader;
|
||||||
|
ClientService.nativePath = classLoader.nativePath;
|
||||||
|
classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.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(assetDir, params.assetHDir, assetMatcher, digest);
|
||||||
|
DirWatcher clientWatcher = new DirWatcher(clientDir, params.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);
|
||||||
|
//}
|
||||||
|
Launcher.profile.pushOptionalFile(params.clientHDir, false);
|
||||||
|
// Start WatchService, and only then client
|
||||||
|
CommonHelper.newThread("Asset Directory Watcher", true, assetWatcher).start();
|
||||||
|
CommonHelper.newThread("Client Directory Watcher", true, clientWatcher).start();
|
||||||
|
verifyHDir(assetDir, params.assetHDir, assetMatcher, digest);
|
||||||
|
verifyHDir(clientDir, params.clientHDir, clientMatcher, digest);
|
||||||
|
launch(profile, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void initGson(ClientModuleManager moduleManager) {
|
||||||
|
Launcher.gsonManager = new ClientGsonManager(moduleManager);
|
||||||
|
Launcher.gsonManager.initGson();
|
||||||
|
}
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void launch(ClientProfile profile, ClientLauncherProcess.ClientParams params) throws Throwable {
|
||||||
|
// Add client args
|
||||||
|
Collection<String> args = new LinkedList<>();
|
||||||
|
if (profile.getVersion().compareTo(ClientProfile.Version.MC164) >= 0)
|
||||||
|
params.addClientArgs(args);
|
||||||
|
else {
|
||||||
|
params.addClientLegacyArgs(args);
|
||||||
|
System.setProperty("minecraft.applet.TargetDirectory", params.clientDir);
|
||||||
|
}
|
||||||
|
Collections.addAll(args, profile.getClientArgs());
|
||||||
|
profile.pushOptionalClientArgs(args);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,258 @@
|
||||||
|
package pro.gravit.launcher.client;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.Launcher;
|
||||||
|
import pro.gravit.launcher.guard.LauncherGuardManager;
|
||||||
|
import pro.gravit.launcher.hasher.HashedDir;
|
||||||
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
|
import pro.gravit.launcher.profiles.PlayerProfile;
|
||||||
|
import pro.gravit.launcher.request.Request;
|
||||||
|
import pro.gravit.launcher.serialize.HOutput;
|
||||||
|
import pro.gravit.utils.Version;
|
||||||
|
import pro.gravit.utils.helper.*;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ClientLauncherProcess {
|
||||||
|
private transient Process process;
|
||||||
|
private final transient Boolean[] waitWriteParams = new Boolean[] {false};
|
||||||
|
public final Path executeFile;
|
||||||
|
public final Path workDir;
|
||||||
|
public final Path javaDir;
|
||||||
|
public final ClientParams params = new ClientParams();
|
||||||
|
public final List<String> jvmArgs = new LinkedList<>();
|
||||||
|
public final List<String> systemClientArgs = new LinkedList<>();
|
||||||
|
public final List<String> systemClassPath = new LinkedList<>();
|
||||||
|
public final Map<String, String> systemEnv = new HashMap<>();
|
||||||
|
public final String mainClass;
|
||||||
|
public boolean isStarted;
|
||||||
|
|
||||||
|
public ClientLauncherProcess(Path executeFile, Path workDir, Path javaDir, String mainClass) {
|
||||||
|
this.executeFile = executeFile;
|
||||||
|
this.workDir = workDir;
|
||||||
|
this.javaDir = javaDir;
|
||||||
|
this.mainClass = mainClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientLauncherProcess(Path clientDir, Path assetDir,
|
||||||
|
ClientProfile profile, PlayerProfile playerProfile, String accessToken,
|
||||||
|
HashedDir clientHDir, HashedDir assetHDir, HashedDir jvmHDir) {
|
||||||
|
this(clientDir, assetDir, clientDir.resolve("resourcepacks"), profile, playerProfile, accessToken, clientHDir, assetHDir, jvmHDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientLauncherProcess(Path clientDir, Path assetDir, Path resourcePackDir,
|
||||||
|
ClientProfile profile, PlayerProfile playerProfile, String accessToken,
|
||||||
|
HashedDir clientHDir, HashedDir assetHDir, HashedDir jvmHDir) {
|
||||||
|
this.executeFile = LauncherGuardManager.getGuardJavaBinPath();
|
||||||
|
this.workDir = clientDir.toAbsolutePath();
|
||||||
|
this.javaDir = Paths.get(System.getProperty("java.home"));
|
||||||
|
this.mainClass = ClientLauncherEntryPoint.class.getName();
|
||||||
|
this.params.clientDir = this.workDir.toString();
|
||||||
|
this.params.resourcePackDir = resourcePackDir.toAbsolutePath().toString();
|
||||||
|
this.params.assetDir = assetDir.toAbsolutePath().toString();
|
||||||
|
this.params.profile = profile;
|
||||||
|
this.params.playerProfile = playerProfile;
|
||||||
|
this.params.accessToken = accessToken;
|
||||||
|
this.params.assetHDir = assetHDir;
|
||||||
|
this.params.clientHDir = clientHDir;
|
||||||
|
this.params.javaHDir = jvmHDir;
|
||||||
|
applyClientProfile();
|
||||||
|
}
|
||||||
|
private void applyClientProfile()
|
||||||
|
{
|
||||||
|
this.systemClassPath.add(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toAbsolutePath().toString());
|
||||||
|
Collections.addAll(this.jvmArgs, this.params.profile.getJvmArgs());
|
||||||
|
this.params.profile.pushOptionalJvmArgs(this.jvmArgs);
|
||||||
|
this.systemEnv.put("JAVA_HOME", javaDir.toString());
|
||||||
|
Collections.addAll(this.systemClassPath, this.params.profile.getAlternativeClassPath());
|
||||||
|
if (params.ram > 0) {
|
||||||
|
this.jvmArgs.add("-Xms" + params.ram + 'M');
|
||||||
|
this.jvmArgs.add("-Xmx" + params.ram + 'M');
|
||||||
|
}
|
||||||
|
this.params.session = Request.getSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class ClientParams
|
||||||
|
{
|
||||||
|
public String assetDir;
|
||||||
|
|
||||||
|
public String clientDir;
|
||||||
|
|
||||||
|
public String resourcePackDir;
|
||||||
|
|
||||||
|
// Client params
|
||||||
|
|
||||||
|
public PlayerProfile playerProfile;
|
||||||
|
|
||||||
|
public ClientProfile profile;
|
||||||
|
|
||||||
|
public String accessToken;
|
||||||
|
|
||||||
|
//==Minecraft params==
|
||||||
|
|
||||||
|
public boolean autoEnter;
|
||||||
|
|
||||||
|
public boolean fullScreen;
|
||||||
|
|
||||||
|
public int ram;
|
||||||
|
|
||||||
|
public int width;
|
||||||
|
|
||||||
|
public int height;
|
||||||
|
|
||||||
|
//========
|
||||||
|
|
||||||
|
public long session;
|
||||||
|
|
||||||
|
public transient HashedDir assetHDir;
|
||||||
|
|
||||||
|
public transient HashedDir clientHDir;
|
||||||
|
|
||||||
|
public transient HashedDir javaHDir;
|
||||||
|
|
||||||
|
public void addClientArgs(Collection<String> args)
|
||||||
|
{
|
||||||
|
if (profile.getVersion().compareTo(ClientProfile.Version.MC164) >= 0)
|
||||||
|
addModernClientArgs(args);
|
||||||
|
else
|
||||||
|
addClientLegacyArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addClientLegacyArgs(Collection<String> args) {
|
||||||
|
args.add(playerProfile.username);
|
||||||
|
args.add(accessToken);
|
||||||
|
|
||||||
|
// Add args for tweaker
|
||||||
|
Collections.addAll(args, "--version", profile.getVersion().name);
|
||||||
|
Collections.addAll(args, "--gameDir", clientDir);
|
||||||
|
Collections.addAll(args, "--assetsDir", assetDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addModernClientArgs(Collection<String> args) {
|
||||||
|
|
||||||
|
// Add version-dependent args
|
||||||
|
ClientProfile.Version version = profile.getVersion();
|
||||||
|
Collections.addAll(args, "--username", playerProfile.username);
|
||||||
|
if (version.compareTo(ClientProfile.Version.MC172) >= 0) {
|
||||||
|
Collections.addAll(args, "--uuid", Launcher.toHash(playerProfile.uuid));
|
||||||
|
Collections.addAll(args, "--accessToken", 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");
|
||||||
|
ClientLauncher.ClientUserProperties properties = new ClientLauncher.ClientUserProperties();
|
||||||
|
if (playerProfile.skin != null) {
|
||||||
|
properties.skinURL = new String[]{playerProfile.skin.url};
|
||||||
|
properties.skinDigest = new String[]{SecurityHelper.toHex(playerProfile.skin.digest)};
|
||||||
|
}
|
||||||
|
if (playerProfile.cloak != null) {
|
||||||
|
properties.cloakURL = new String[]{playerProfile.cloak.url};
|
||||||
|
properties.cloakDigest = new String[]{SecurityHelper.toHex(playerProfile.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", accessToken);
|
||||||
|
|
||||||
|
// Add version and dirs args
|
||||||
|
Collections.addAll(args, "--version", profile.getVersion().name);
|
||||||
|
Collections.addAll(args, "--gameDir", clientDir);
|
||||||
|
Collections.addAll(args, "--assetsDir", assetDir);
|
||||||
|
Collections.addAll(args, "--resourcePackDir", resourcePackDir);
|
||||||
|
if (version.compareTo(ClientProfile.Version.MC194) >= 0)
|
||||||
|
Collections.addAll(args, "--versionType", "Launcher v" + Version.getVersion().getVersionString());
|
||||||
|
|
||||||
|
// Add server args
|
||||||
|
if (autoEnter) {
|
||||||
|
Collections.addAll(args, "--server", profile.getServerAddress());
|
||||||
|
Collections.addAll(args, "--port", Integer.toString(profile.getServerPort()));
|
||||||
|
}
|
||||||
|
profile.pushOptionalClientArgs(args);
|
||||||
|
// Add window size args
|
||||||
|
if (fullScreen)
|
||||||
|
Collections.addAll(args, "--fullscreen", Boolean.toString(true));
|
||||||
|
if (width > 0 && height > 0) {
|
||||||
|
Collections.addAll(args, "--width", Integer.toString(width));
|
||||||
|
Collections.addAll(args, "--height", Integer.toString(height));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
||||||
|
if(isStarted) throw new IllegalStateException("Process already started");
|
||||||
|
List<String> processArgs = new LinkedList<>();
|
||||||
|
processArgs.add(executeFile.toString());
|
||||||
|
processArgs.addAll(jvmArgs);
|
||||||
|
processArgs.add("-cp");
|
||||||
|
//ADD CLASSPATH
|
||||||
|
processArgs.add(String.join(getPathSeparator(), systemClassPath));
|
||||||
|
processArgs.add(mainClass);
|
||||||
|
processArgs.addAll(systemClientArgs);
|
||||||
|
synchronized (waitWriteParams)
|
||||||
|
{
|
||||||
|
if(!waitWriteParams[0])
|
||||||
|
{
|
||||||
|
waitWriteParams.wait(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(LogHelper.isDebugEnabled())
|
||||||
|
LogHelper.debug("Commandline: %s", Arrays.toString(processArgs.toArray()));
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder(processArgs);
|
||||||
|
EnvHelper.addEnv(processBuilder);
|
||||||
|
processBuilder.environment().putAll(systemEnv);
|
||||||
|
processBuilder.directory(workDir.toFile());
|
||||||
|
processBuilder.inheritIO();
|
||||||
|
if (pipeOutput) {
|
||||||
|
processBuilder.redirectErrorStream(true);
|
||||||
|
processBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE);
|
||||||
|
}
|
||||||
|
process = processBuilder.start();
|
||||||
|
isStarted = true;
|
||||||
|
}
|
||||||
|
public void runWriteParams(SocketAddress address) throws IOException
|
||||||
|
{
|
||||||
|
try(ServerSocket serverSocket = new ServerSocket())
|
||||||
|
{
|
||||||
|
serverSocket.bind(address);
|
||||||
|
synchronized (waitWriteParams)
|
||||||
|
{
|
||||||
|
waitWriteParams[0] = true;
|
||||||
|
waitWriteParams.notifyAll();
|
||||||
|
}
|
||||||
|
Socket socket = serverSocket.accept();
|
||||||
|
try(HOutput output = new HOutput(socket.getOutputStream()))
|
||||||
|
{
|
||||||
|
byte[] serializedMainParams = Launcher.gsonManager.gson.toJson(params).getBytes(IOHelper.UNICODE_CHARSET);
|
||||||
|
output.writeByteArray(serializedMainParams, 0);
|
||||||
|
params.clientHDir.write(output);
|
||||||
|
params.assetHDir.write(output);
|
||||||
|
params.javaHDir.write(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process getProcess() {
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getPathSeparator()
|
||||||
|
{
|
||||||
|
if(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
|
||||||
|
return ";";
|
||||||
|
else
|
||||||
|
return ":";
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,129 +0,0 @@
|
||||||
package pro.gravit.launcher.hwid;
|
|
||||||
|
|
||||||
import oshi.SystemInfo;
|
|
||||||
import oshi.hardware.*;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.net.NetworkInterface;
|
|
||||||
|
|
||||||
public class OshiHWIDProvider implements LauncherHWIDInterface {
|
|
||||||
public SystemInfo systemInfo;
|
|
||||||
public HardwareAbstractionLayer hardware;
|
|
||||||
public boolean noHWID;
|
|
||||||
|
|
||||||
public OshiHWIDProvider() {
|
|
||||||
try {
|
|
||||||
systemInfo = new SystemInfo();
|
|
||||||
noHWID = false;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
noHWID = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSerial() {
|
|
||||||
try {
|
|
||||||
if (hardware == null) hardware = systemInfo.getHardware();
|
|
||||||
return hardware.getComputerSystem().getSerialNumber();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProcessorID() {
|
|
||||||
try {
|
|
||||||
if (hardware == null) hardware = systemInfo.getHardware();
|
|
||||||
return hardware.getProcessor().getProcessorID();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHWDisk() {
|
|
||||||
try {
|
|
||||||
if (hardware == null) hardware = systemInfo.getHardware();
|
|
||||||
HWDiskStore store = null;
|
|
||||||
long size = 0;
|
|
||||||
for (HWDiskStore s : hardware.getDiskStores()) {
|
|
||||||
if (size < s.getSize()) {
|
|
||||||
store = s;
|
|
||||||
size = s.getSize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return store == null ? "" : store.getSerial();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMacAddr() {
|
|
||||||
for (NetworkIF networkIF : hardware.getNetworkIFs()) {
|
|
||||||
if (networkIF.getNetworkInterface().isVirtual()) continue;
|
|
||||||
for (String ipv4 : networkIF.getIPv4addr()) {
|
|
||||||
if (ipv4.startsWith("127.")) continue;
|
|
||||||
if (ipv4.startsWith("10.")) continue;
|
|
||||||
return networkIF.getMacaddr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTotalMemory() {
|
|
||||||
if (noHWID) return 1024 << 20;
|
|
||||||
if (hardware == null) hardware = systemInfo.getHardware();
|
|
||||||
return hardware.getMemory().getTotal();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getAvailableMemory() {
|
|
||||||
if (noHWID) return -1;
|
|
||||||
if (hardware == null) hardware = systemInfo.getHardware();
|
|
||||||
return hardware.getMemory().getAvailable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void printHardwareInformation() {
|
|
||||||
try {
|
|
||||||
if (hardware == null) hardware = systemInfo.getHardware();
|
|
||||||
ComputerSystem computerSystem = hardware.getComputerSystem();
|
|
||||||
LogHelper.debug("ComputerSystem Model: %s Serial: %s", computerSystem.getModel(), computerSystem.getSerialNumber());
|
|
||||||
for (HWDiskStore s : hardware.getDiskStores()) {
|
|
||||||
LogHelper.debug("HWDiskStore Serial: %s Model: %s Size: %d", s.getSerial(), s.getModel(), s.getSize());
|
|
||||||
}
|
|
||||||
for (UsbDevice s : hardware.getUsbDevices(true)) {
|
|
||||||
LogHelper.debug("USBDevice Serial: %s Name: %s", s.getSerialNumber(), s.getName());
|
|
||||||
}
|
|
||||||
for (NetworkIF networkIF : hardware.getNetworkIFs()) {
|
|
||||||
LogHelper.debug("Network Interface: %s mac: %s", networkIF.getName(), networkIF.getMacaddr());
|
|
||||||
NetworkInterface network = networkIF.getNetworkInterface();
|
|
||||||
if (network.isLoopback() || network.isVirtual()) continue;
|
|
||||||
LogHelper.debug("Network Interface display: %s name: %s", network.getDisplayName(), network.getName());
|
|
||||||
for (String ipv4 : networkIF.getIPv4addr()) {
|
|
||||||
if (ipv4.startsWith("127.")) continue;
|
|
||||||
if (ipv4.startsWith("10.")) continue;
|
|
||||||
LogHelper.subDebug("IPv4: %s", ipv4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CentralProcessor processor = hardware.getProcessor();
|
|
||||||
LogHelper.debug("Processor Model: %s ID: %s", processor.getModel(), processor.getProcessorID());
|
|
||||||
} catch (Throwable e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HWID getHWID() {
|
|
||||||
OshiHWID hwid = new OshiHWID();
|
|
||||||
hwid.serialNumber = getSerial();
|
|
||||||
hwid.totalMemory = getTotalMemory();
|
|
||||||
hwid.HWDiskSerial = getHWDisk();
|
|
||||||
hwid.processorID = getProcessorID();
|
|
||||||
hwid.macAddr = getMacAddr();
|
|
||||||
printHardwareInformation();
|
|
||||||
return hwid;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,8 +3,6 @@
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import pro.gravit.launcher.client.ClientModuleManager;
|
import pro.gravit.launcher.client.ClientModuleManager;
|
||||||
import pro.gravit.launcher.client.UserSettings;
|
import pro.gravit.launcher.client.UserSettings;
|
||||||
import pro.gravit.launcher.hwid.HWID;
|
|
||||||
import pro.gravit.launcher.hwid.HWIDProvider;
|
|
||||||
import pro.gravit.launcher.modules.events.PreGsonPhase;
|
import pro.gravit.launcher.modules.events.PreGsonPhase;
|
||||||
import pro.gravit.launcher.request.websockets.ClientWebSocketService;
|
import pro.gravit.launcher.request.websockets.ClientWebSocketService;
|
||||||
import pro.gravit.utils.UniversalJsonAdapter;
|
import pro.gravit.utils.UniversalJsonAdapter;
|
||||||
|
@ -20,7 +18,6 @@ public ClientGsonManager(ClientModuleManager moduleManager) {
|
||||||
public void registerAdapters(GsonBuilder builder) {
|
public void registerAdapters(GsonBuilder builder) {
|
||||||
super.registerAdapters(builder);
|
super.registerAdapters(builder);
|
||||||
builder.registerTypeAdapter(UserSettings.class, new UniversalJsonAdapter<>(UserSettings.providers));
|
builder.registerTypeAdapter(UserSettings.class, new UniversalJsonAdapter<>(UserSettings.providers));
|
||||||
builder.registerTypeAdapter(HWID.class, new UniversalJsonAdapter<>(HWIDProvider.hwids));
|
|
||||||
ClientWebSocketService.appendTypeAdapters(builder);
|
ClientWebSocketService.appendTypeAdapters(builder);
|
||||||
moduleManager.invokeEvent(new PreGsonPhase(builder));
|
moduleManager.invokeEvent(new PreGsonPhase(builder));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(':LauncherCore')
|
api project(':LauncherCore')
|
||||||
compileOnly 'io.netty:netty-codec-http:4.1.43.Final'
|
compileOnly group: 'io.netty', name: 'netty-codec-http', version: rootProject['verNetty']
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.4.1'
|
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: rootProject['verJunit']
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
|
|
@ -40,12 +40,29 @@ public enum AuthType
|
||||||
OTHER
|
OTHER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public enum ServerFeature
|
||||||
|
{
|
||||||
|
FEATURE_SUPPORT(1);
|
||||||
|
public final int val;
|
||||||
|
|
||||||
|
ServerFeature(int val) {
|
||||||
|
this.val = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public final List<AuthAvailability> list;
|
public final List<AuthAvailability> list;
|
||||||
|
@LauncherNetworkAPI
|
||||||
|
public final long features;
|
||||||
|
|
||||||
public GetAvailabilityAuthRequestEvent(List<AuthAvailability> list) {
|
public GetAvailabilityAuthRequestEvent(List<AuthAvailability> list) {
|
||||||
this.list = list;
|
this.list = list;
|
||||||
|
this.features = ServerFeature.FEATURE_SUPPORT.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GetAvailabilityAuthRequestEvent(List<AuthAvailability> list, long features) {
|
||||||
|
this.list = list;
|
||||||
|
this.features = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package pro.gravit.launcher.events.request;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.events.RequestEvent;
|
||||||
|
|
||||||
|
public class GetSecureLevelInfoRequestEvent extends RequestEvent {
|
||||||
|
public final byte[] verifySecureKey;
|
||||||
|
public boolean enabled;
|
||||||
|
|
||||||
|
public GetSecureLevelInfoRequestEvent(byte[] verifySecureKey) {
|
||||||
|
this.verifySecureKey = verifySecureKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "getSecureLevelInfo";
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
package pro.gravit.launcher.events.request;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.LauncherNetworkAPI;
|
|
||||||
import pro.gravit.launcher.events.RequestEvent;
|
|
||||||
|
|
||||||
public class GetSecureTokenRequestEvent extends RequestEvent {
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public final String secureToken;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return "GetSecureToken";
|
|
||||||
}
|
|
||||||
|
|
||||||
public GetSecureTokenRequestEvent(String secureToken) {
|
|
||||||
this.secureToken = secureToken;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package pro.gravit.launcher.events.request;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.events.RequestEvent;
|
||||||
|
|
||||||
|
public class SecurityReportRequestEvent extends RequestEvent {
|
||||||
|
public SecurityReportRequestEvent(ReportAction action) {
|
||||||
|
this.action = action;
|
||||||
|
this.otherAction = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SecurityReportRequestEvent(String otherAction) {
|
||||||
|
this.action = ReportAction.OTHER;
|
||||||
|
this.otherAction = otherAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SecurityReportRequestEvent() {
|
||||||
|
this.action = ReportAction.NONE;
|
||||||
|
this.otherAction = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ReportAction
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
LOGOUT,
|
||||||
|
EXIT,
|
||||||
|
CRASH,
|
||||||
|
OTHER
|
||||||
|
}
|
||||||
|
public final ReportAction action;
|
||||||
|
public final String otherAction;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "securityReport";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package pro.gravit.launcher.events.request;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.events.RequestEvent;
|
||||||
|
|
||||||
|
public class VerifySecureLevelKeyRequestEvent extends RequestEvent {
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "verifySecureLevelKey";
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
package pro.gravit.launcher.events.request;
|
|
||||||
|
|
||||||
import pro.gravit.launcher.LauncherNetworkAPI;
|
|
||||||
import pro.gravit.launcher.events.RequestEvent;
|
|
||||||
|
|
||||||
public class VerifySecureTokenRequestEvent extends RequestEvent {
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public final boolean success;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return "verifySecureToken";
|
|
||||||
}
|
|
||||||
|
|
||||||
public VerifySecureTokenRequestEvent(boolean success) {
|
|
||||||
this.success = success;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
package pro.gravit.launcher.hwid;
|
package pro.gravit.launcher.hwid;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public interface HWID {
|
public interface HWID {
|
||||||
|
|
||||||
int getLevel(); //Уровень доверия, насколько уникальные значения
|
int getLevel(); //Уровень доверия, насколько уникальные значения
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
package pro.gravit.launcher.hwid;
|
|
||||||
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
public class HWIDCheckHelper {
|
|
||||||
public static int checkString(String str) {
|
|
||||||
int result = 0;
|
|
||||||
//Считаем символы
|
|
||||||
char lastChar = '\0';
|
|
||||||
int combo = 0;
|
|
||||||
int maxCombo = 0;
|
|
||||||
//Считаем род символов
|
|
||||||
int lastCharType = -1;
|
|
||||||
int lastCharTypeCombo = 0;
|
|
||||||
int wtfCharTypeCombo = 0;
|
|
||||||
boolean skipLastCharType = true;
|
|
||||||
for (char c : str.toCharArray()) {
|
|
||||||
if (c == lastChar || Math.abs(c - lastChar) == 1 ||
|
|
||||||
((lastChar == '0' || lastChar == '9') && (c == 'A' || c == 'a'))) //Переход с 0 или 9 на A или a
|
|
||||||
{
|
|
||||||
combo++;
|
|
||||||
} else {
|
|
||||||
combo = 1;
|
|
||||||
}
|
|
||||||
lastChar = c;
|
|
||||||
if (maxCombo < combo)
|
|
||||||
maxCombo = combo;
|
|
||||||
int charType = getCharType(c);
|
|
||||||
if (lastCharType == charType) {
|
|
||||||
lastCharTypeCombo++;
|
|
||||||
//Нам подсунули серию из идущих подряд спец символов. Что за?
|
|
||||||
if ((charType == -1 || charType == 3) && lastCharTypeCombo > 2) {
|
|
||||||
wtfCharTypeCombo += 3;
|
|
||||||
}
|
|
||||||
//Нам подсунули серию из слишком большого числа идущих подряд чисел. Что за?
|
|
||||||
if ((charType == 0) && lastCharTypeCombo > 4) {
|
|
||||||
wtfCharTypeCombo++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (skipLastCharType && (charType == -1 || charType == 3)) {
|
|
||||||
skipLastCharType = false;
|
|
||||||
} else {
|
|
||||||
skipLastCharType = true;
|
|
||||||
lastCharType = charType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Считаем результат
|
|
||||||
LogHelper.debug("HWID Checker maxCombo %d", maxCombo);
|
|
||||||
LogHelper.debug("HWID Checker wtfCharTypeCombo %d", wtfCharTypeCombo);
|
|
||||||
if (maxCombo > 3) result += maxCombo * 3;
|
|
||||||
if (wtfCharTypeCombo > 1) result += wtfCharTypeCombo * 2;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getCharType(char c) {
|
|
||||||
if (c >= '0' && c <= '9') return 0;
|
|
||||||
if (c >= 'A' && c <= 'Z') return 1;
|
|
||||||
if (c >= 'a' && c <= 'z') return 2;
|
|
||||||
if (c == ' ' || c == '-' || c == '_') return 3;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package pro.gravit.launcher.hwid;
|
|
||||||
|
|
||||||
import pro.gravit.utils.ProviderMap;
|
|
||||||
|
|
||||||
public class HWIDProvider {
|
|
||||||
public static final ProviderMap<HWID> hwids = new ProviderMap<>();
|
|
||||||
|
|
||||||
public static void registerHWIDs() {
|
|
||||||
hwids.register("oshi", OshiHWID.class);
|
|
||||||
hwids.register("no", NoHWID.class);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
package pro.gravit.launcher.hwid;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface LauncherHWIDInterface {
|
|
||||||
HWID getHWID();
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package pro.gravit.launcher.hwid;
|
|
||||||
|
|
||||||
public class NoHWID implements HWID {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getLevel() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getAntiLevel() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(HWID hwid) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isNull() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void normalize() {
|
|
||||||
//Skip
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
package pro.gravit.launcher.hwid;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import pro.gravit.launcher.LauncherNetworkAPI;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.StringJoiner;
|
|
||||||
|
|
||||||
public class OshiHWID implements HWID {
|
|
||||||
public static Gson gson = new Gson();
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public long totalMemory = 0;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public String serialNumber;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public String HWDiskSerial;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public String processorID;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
public String macAddr;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getLevel() //Уровень доверия, насколько уникальные значения
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
if (totalMemory != 0) result += 32;
|
|
||||||
if (serialNumber != null) result += isRealSerialNumber() ? 20 : 3;
|
|
||||||
if (HWDiskSerial != null && !HWDiskSerial.isEmpty()) result += 38;
|
|
||||||
if (processorID != null && !processorID.isEmpty()) result += 15;
|
|
||||||
if (macAddr != null && !macAddr.isEmpty()) result += 25;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getAntiLevel() {
|
|
||||||
return HWIDCheckHelper.checkString(serialNumber) + HWIDCheckHelper.checkString(HWDiskSerial);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(HWID hwid) {
|
|
||||||
if (hwid instanceof OshiHWID) {
|
|
||||||
int rate = 0;
|
|
||||||
OshiHWID oshi = (OshiHWID) hwid;
|
|
||||||
if (Math.abs(oshi.totalMemory - totalMemory) < 1024 * 1024) rate += 5;
|
|
||||||
if (oshi.totalMemory == totalMemory) rate += 32;
|
|
||||||
if (oshi.HWDiskSerial.equals(HWDiskSerial) && !HWDiskSerial.isEmpty()) rate += 38;
|
|
||||||
if (oshi.processorID.equals(processorID) && !processorID.isEmpty()) rate += 15;
|
|
||||||
if (oshi.serialNumber.equals(serialNumber)) rate += isRealSerialNumber() ? 20 : 3;
|
|
||||||
if (!oshi.macAddr.isEmpty() && oshi.macAddr.equals(macAddr)) rate += 19;
|
|
||||||
return rate;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isNull() {
|
|
||||||
return getLevel() < 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void normalize() {
|
|
||||||
HWDiskSerial = HWDiskSerial.trim();
|
|
||||||
serialNumber = serialNumber.trim();
|
|
||||||
processorID = processorID.trim();
|
|
||||||
macAddr = macAddr.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRealSerialNumber() {
|
|
||||||
if (serialNumber.isEmpty()) return false;
|
|
||||||
if (serialNumber.equals("System Serial Number")) return false;
|
|
||||||
if (serialNumber.equals("To be filled by O.E.M.")) return false;
|
|
||||||
if (serialNumber.equals("unknown")) return false;
|
|
||||||
if (serialNumber.equals("None")) return false;
|
|
||||||
if (serialNumber.equals("Default string")) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
OshiHWID oshiHWID = (OshiHWID) o;
|
|
||||||
return totalMemory == oshiHWID.totalMemory &&
|
|
||||||
Objects.equals(serialNumber, oshiHWID.serialNumber) &&
|
|
||||||
Objects.equals(HWDiskSerial, oshiHWID.HWDiskSerial) &&
|
|
||||||
Objects.equals(processorID, oshiHWID.processorID) &&
|
|
||||||
Objects.equals(macAddr, oshiHWID.macAddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(totalMemory, serialNumber, HWDiskSerial, processorID, macAddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new StringJoiner(", ", OshiHWID.class.getSimpleName() + "[", "]")
|
|
||||||
.add("totalMemory=" + totalMemory)
|
|
||||||
.add("serialNumber='" + serialNumber + "'")
|
|
||||||
.add("HWDiskSerial='" + HWDiskSerial + "'")
|
|
||||||
.add("processorID='" + processorID + "'")
|
|
||||||
.add("macAddr='" + macAddr + "'")
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,7 +22,7 @@ public Path getModuleConfig(String moduleName) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getModuleConfig(String moduleName, String configName) {
|
public Path getModuleConfig(String moduleName, String configName) {
|
||||||
return getModuleConfigDir(moduleName).resolve(moduleName.concat(configName.concat(".json")));
|
return getModuleConfigDir(moduleName).resolve(configName.concat(".json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path getModuleConfigDir(String moduleName) {
|
public Path getModuleConfigDir(String moduleName) {
|
||||||
|
|
|
@ -120,8 +120,6 @@ public enum ClassLoaderConfig
|
||||||
private final Set<OptionalFile> updateOptional = new HashSet<>();
|
private final Set<OptionalFile> updateOptional = new HashSet<>();
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private boolean updateFastCheck;
|
private boolean updateFastCheck;
|
||||||
@LauncherNetworkAPI
|
|
||||||
private boolean useWhitelist;
|
|
||||||
// Client launcher
|
// Client launcher
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private String mainClass;
|
private String mainClass;
|
||||||
|
@ -130,9 +128,9 @@ public enum ClassLoaderConfig
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private final List<String> classPath = new ArrayList<>();
|
private final List<String> classPath = new ArrayList<>();
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private final List<String> clientArgs = new ArrayList<>();
|
private final List<String> altClassPath = new ArrayList<>();
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private final List<String> whitelist = new ArrayList<>();
|
private final List<String> clientArgs = new ArrayList<>();
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public SecurityManagerConfig securityManagerConfig = SecurityManagerConfig.CLIENT;
|
public SecurityManagerConfig securityManagerConfig = SecurityManagerConfig.CLIENT;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
|
@ -158,6 +156,10 @@ public String[] getClassPath() {
|
||||||
return classPath.toArray(new String[0]);
|
return classPath.toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String[] getAlternativeClassPath() {
|
||||||
|
return altClassPath.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public String[] getClientArgs() {
|
public String[] getClientArgs() {
|
||||||
return clientArgs.toArray(new String[0]);
|
return clientArgs.toArray(new String[0]);
|
||||||
|
@ -200,6 +202,7 @@ public String[] getJvmArgs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getMainClass() {
|
public String getMainClass() {
|
||||||
return mainClass;
|
return mainClass;
|
||||||
}
|
}
|
||||||
|
@ -245,20 +248,11 @@ public Collection<String> getShared() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void markOptional(String name, OptionalType type) {
|
|
||||||
OptionalFile file = getOptionalFile(name, type);
|
|
||||||
if (file == null) {
|
|
||||||
throw new SecurityException(String.format("Optional %s not found in optionalList", name));
|
|
||||||
}
|
|
||||||
markOptional(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void markOptional(OptionalFile file) {
|
public void markOptional(OptionalFile file) {
|
||||||
|
|
||||||
if (file.mark) return;
|
if (file.mark) return;
|
||||||
file.mark = true;
|
file.mark = true;
|
||||||
file.notifyObservers(true);
|
file.watchEvent(true);
|
||||||
if (file.dependencies != null) {
|
if (file.dependencies != null) {
|
||||||
for (OptionalFile dep : file.dependencies) {
|
for (OptionalFile dep : file.dependencies) {
|
||||||
if (dep.dependenciesCount == null) dep.dependenciesCount = new HashSet<>();
|
if (dep.dependenciesCount == null) dep.dependenciesCount = new HashSet<>();
|
||||||
|
@ -274,19 +268,10 @@ public void markOptional(OptionalFile file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void unmarkOptional(String name, OptionalType type) {
|
|
||||||
OptionalFile file = getOptionalFile(name, type);
|
|
||||||
if (file == null) {
|
|
||||||
throw new SecurityException(String.format("Optional %s not found in optionalList", name));
|
|
||||||
}
|
|
||||||
unmarkOptional(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void unmarkOptional(OptionalFile file) {
|
public void unmarkOptional(OptionalFile file) {
|
||||||
if (!file.mark) return;
|
if (!file.mark) return;
|
||||||
file.mark = false;
|
file.mark = false;
|
||||||
file.notifyObservers(false);
|
file.watchEvent(false);
|
||||||
if (file.dependenciesCount != null) {
|
if (file.dependenciesCount != null) {
|
||||||
for (OptionalFile f : file.dependenciesCount) {
|
for (OptionalFile f : file.dependenciesCount) {
|
||||||
if (f.isPreset) continue;
|
if (f.isPreset) continue;
|
||||||
|
@ -383,12 +368,6 @@ public boolean isUpdateFastCheck() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isWhitelistContains(String username) {
|
|
||||||
if (!useWhitelist) return true;
|
|
||||||
return whitelist.stream().anyMatch(profileCaseSensitive ? e -> e.equals(username) : e -> e.equalsIgnoreCase(username));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setTitle(String title) {
|
public void setTitle(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.*;
|
||||||
import java.util.Observable;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.Set;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
public class OptionalFile extends Observable {
|
public class OptionalFile {
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public String[] list;
|
public String[] list;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
|
@ -18,7 +18,7 @@ public class OptionalFile extends Observable {
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public boolean mark;
|
public boolean mark;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public final boolean visible = true;
|
public boolean visible = true;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public String name;
|
public String name;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
|
@ -125,4 +125,27 @@ public static OptionalType readType(HInput input) throws IOException {
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
private volatile transient Collection<BiConsumer<OptionalFile, Boolean>> watchList = null;
|
||||||
|
public void registerWatcher(BiConsumer<OptionalFile, Boolean> watcher)
|
||||||
|
{
|
||||||
|
if(watchList == null) watchList = ConcurrentHashMap.newKeySet();
|
||||||
|
watchList.add(watcher);
|
||||||
|
}
|
||||||
|
public void removeWatcher(BiConsumer<OptionalFile, Boolean> watcher)
|
||||||
|
{
|
||||||
|
if(watchList == null) return;
|
||||||
|
watchList.remove(watcher);
|
||||||
|
}
|
||||||
|
public void clearAllWatchers()
|
||||||
|
{
|
||||||
|
if(watchList == null) return;
|
||||||
|
watchList.clear();
|
||||||
|
}
|
||||||
|
public void watchEvent(boolean isMark)
|
||||||
|
{
|
||||||
|
if(watchList == null) return;
|
||||||
|
watchList.forEach((e) -> {
|
||||||
|
e.accept(this, isMark);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ public enum TriggerType
|
||||||
public boolean need = true;
|
public boolean need = true;
|
||||||
public long value;
|
public long value;
|
||||||
public long compareMode = 0;
|
public long compareMode = 0;
|
||||||
boolean isTriggered()
|
public boolean isTriggered()
|
||||||
{
|
{
|
||||||
long test;
|
long test;
|
||||||
switch (type)
|
switch (type)
|
||||||
|
|
|
@ -24,10 +24,6 @@ public interface AuthPasswordInterface {
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private final String auth_id;
|
private final String auth_id;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private final HWID hwid;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
private final String customText;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
private final boolean getSession;
|
private final boolean getSession;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private final ConnectTypes authType;
|
private final ConnectTypes authType;
|
||||||
|
@ -45,34 +41,26 @@ public enum ConnectTypes {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AuthRequest(String login, byte[] password, HWID hwid) {
|
public AuthRequest(String login, byte[] password) {
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
||||||
this.password = new AuthECPassword(password.clone());
|
this.password = new AuthECPassword(password.clone());
|
||||||
this.hwid = hwid;
|
|
||||||
customText = "";
|
|
||||||
auth_id = "";
|
auth_id = "";
|
||||||
getSession = true;
|
getSession = true;
|
||||||
authType = ConnectTypes.CLIENT;
|
authType = ConnectTypes.CLIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AuthRequest(String login, byte[] password, String auth_id) {
|
||||||
public AuthRequest(String login, byte[] password, HWID hwid, String auth_id) {
|
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
||||||
this.password = new AuthECPassword(password.clone());
|
this.password = new AuthECPassword(password.clone());
|
||||||
this.hwid = hwid;
|
|
||||||
this.auth_id = auth_id;
|
this.auth_id = auth_id;
|
||||||
customText = "";
|
|
||||||
getSession = true;
|
getSession = true;
|
||||||
authType = ConnectTypes.CLIENT;
|
authType = ConnectTypes.CLIENT;
|
||||||
}
|
}
|
||||||
|
@Deprecated
|
||||||
|
public AuthRequest(String login, byte[] password, HWID hwid, String auth_id) {
|
||||||
public AuthRequest(String login, byte[] password, HWID hwid, String customText, String auth_id) {
|
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
||||||
this.password = new AuthECPassword(password.clone());
|
this.password = new AuthECPassword(password.clone());
|
||||||
this.hwid = hwid;
|
|
||||||
this.auth_id = auth_id;
|
this.auth_id = auth_id;
|
||||||
this.customText = customText;
|
|
||||||
getSession = true;
|
getSession = true;
|
||||||
authType = ConnectTypes.CLIENT;
|
authType = ConnectTypes.CLIENT;
|
||||||
}
|
}
|
||||||
|
@ -82,8 +70,6 @@ public AuthRequest(String login, byte[] encryptedPassword, String auth_id, Conne
|
||||||
this.password = new AuthECPassword(encryptedPassword.clone());
|
this.password = new AuthECPassword(encryptedPassword.clone());
|
||||||
this.auth_id = auth_id;
|
this.auth_id = auth_id;
|
||||||
this.authType = authType;
|
this.authType = authType;
|
||||||
this.hwid = null;
|
|
||||||
this.customText = "";
|
|
||||||
this.getSession = false;
|
this.getSession = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +78,6 @@ public AuthRequest(String login, String password, String auth_id, ConnectTypes a
|
||||||
this.password = new AuthPlainPassword(password);
|
this.password = new AuthPlainPassword(password);
|
||||||
this.auth_id = auth_id;
|
this.auth_id = auth_id;
|
||||||
this.authType = authType;
|
this.authType = authType;
|
||||||
this.hwid = null;
|
|
||||||
this.customText = "";
|
|
||||||
this.getSession = false;
|
this.getSession = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package pro.gravit.launcher.request.secure;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.events.request.GetSecureLevelInfoRequestEvent;
|
||||||
|
import pro.gravit.launcher.request.Request;
|
||||||
|
|
||||||
|
public class GetSecureLevelInfoRequest extends Request<GetSecureLevelInfoRequestEvent> {
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "getSecureLevelInfo";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package pro.gravit.launcher.request.secure;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.events.request.SecurityReportRequestEvent;
|
||||||
|
import pro.gravit.launcher.request.Request;
|
||||||
|
|
||||||
|
public final class SecurityReportRequest extends Request<SecurityReportRequestEvent> {
|
||||||
|
public final String reportType;
|
||||||
|
public final String smallData;
|
||||||
|
public final String largeData;
|
||||||
|
public final byte[] smallBytes;
|
||||||
|
public final byte[] largeBytes;
|
||||||
|
|
||||||
|
public SecurityReportRequest(String reportType, String smallData, String largeData, byte[] smallBytes, byte[] largeBytes) {
|
||||||
|
this.reportType = reportType;
|
||||||
|
this.smallData = smallData;
|
||||||
|
this.largeData = largeData;
|
||||||
|
this.smallBytes = smallBytes;
|
||||||
|
this.largeBytes = largeBytes;
|
||||||
|
}
|
||||||
|
public SecurityReportRequest(String reportType, String smallData, String largeData, byte[] smallBytes) {
|
||||||
|
this.reportType = reportType;
|
||||||
|
this.smallData = smallData;
|
||||||
|
this.largeData = largeData;
|
||||||
|
this.smallBytes = smallBytes;
|
||||||
|
this.largeBytes = null;
|
||||||
|
}
|
||||||
|
public SecurityReportRequest(String reportType, String smallData, String largeData) {
|
||||||
|
this.reportType = reportType;
|
||||||
|
this.smallData = smallData;
|
||||||
|
this.largeData = largeData;
|
||||||
|
this.smallBytes = null;
|
||||||
|
this.largeBytes = null;
|
||||||
|
}
|
||||||
|
public SecurityReportRequest(String reportType, String smallData, byte[] smallBytes) {
|
||||||
|
this.reportType = reportType;
|
||||||
|
this.smallData = smallData;
|
||||||
|
this.largeData = null;
|
||||||
|
this.smallBytes = smallBytes;
|
||||||
|
this.largeBytes = null;
|
||||||
|
}
|
||||||
|
public SecurityReportRequest(String reportType, byte[] smallBytes, byte[] largeBytes) {
|
||||||
|
this.reportType = reportType;
|
||||||
|
this.smallData = null;
|
||||||
|
this.largeData = null;
|
||||||
|
this.smallBytes = smallBytes;
|
||||||
|
this.largeBytes = largeBytes;
|
||||||
|
}
|
||||||
|
public SecurityReportRequest(String reportType, byte[] smallBytes) {
|
||||||
|
this.reportType = reportType;
|
||||||
|
this.smallData = null;
|
||||||
|
this.largeData = null;
|
||||||
|
this.smallBytes = smallBytes;
|
||||||
|
this.largeBytes = null;
|
||||||
|
}
|
||||||
|
public SecurityReportRequest(String reportType, String smallData) {
|
||||||
|
this.reportType = reportType;
|
||||||
|
this.smallData = smallData;
|
||||||
|
this.largeData = null;
|
||||||
|
this.smallBytes = null;
|
||||||
|
this.largeBytes = null;
|
||||||
|
}
|
||||||
|
public SecurityReportRequest(String reportType) {
|
||||||
|
this.reportType = reportType;
|
||||||
|
this.smallData = null;
|
||||||
|
this.largeData = null;
|
||||||
|
this.smallBytes = null;
|
||||||
|
this.largeBytes = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "securityReport";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package pro.gravit.launcher.request.secure;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.events.request.VerifySecureLevelKeyRequestEvent;
|
||||||
|
import pro.gravit.launcher.request.Request;
|
||||||
|
|
||||||
|
public class VerifySecureLevelKeyRequest extends Request<VerifySecureLevelKeyRequestEvent> {
|
||||||
|
public final byte[] publicKey;
|
||||||
|
public final byte[] signature;
|
||||||
|
|
||||||
|
public VerifySecureLevelKeyRequest(byte[] publicKey, byte[] signature) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
this.signature = signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "verifySecureLevelKey";
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
import pro.gravit.launcher.hasher.HashedEntryAdapter;
|
import pro.gravit.launcher.hasher.HashedEntryAdapter;
|
||||||
import pro.gravit.launcher.request.WebSocketEvent;
|
import pro.gravit.launcher.request.WebSocketEvent;
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
import pro.gravit.launcher.request.auth.AuthRequest;
|
||||||
|
import pro.gravit.launcher.request.secure.VerifySecureLevelKeyRequest;
|
||||||
import pro.gravit.utils.ProviderMap;
|
import pro.gravit.utils.ProviderMap;
|
||||||
import pro.gravit.utils.UniversalJsonAdapter;
|
import pro.gravit.utils.UniversalJsonAdapter;
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
@ -97,8 +98,6 @@ public void registerResults() {
|
||||||
results.register("error", ErrorRequestEvent.class);
|
results.register("error", ErrorRequestEvent.class);
|
||||||
results.register("update", UpdateRequestEvent.class);
|
results.register("update", UpdateRequestEvent.class);
|
||||||
results.register("restoreSession", RestoreSessionRequestEvent.class);
|
results.register("restoreSession", RestoreSessionRequestEvent.class);
|
||||||
results.register("getSecureToken", GetSecureTokenRequestEvent.class);
|
|
||||||
results.register("verifySecureToken", VerifySecureTokenRequestEvent.class);
|
|
||||||
results.register("log", LogEvent.class);
|
results.register("log", LogEvent.class);
|
||||||
results.register("cmdExec", ExecCommandRequestEvent.class);
|
results.register("cmdExec", ExecCommandRequestEvent.class);
|
||||||
results.register("getAvailabilityAuth", GetAvailabilityAuthRequestEvent.class);
|
results.register("getAvailabilityAuth", GetAvailabilityAuthRequestEvent.class);
|
||||||
|
@ -108,6 +107,9 @@ public void registerResults() {
|
||||||
results.register("notification", NotificationEvent.class);
|
results.register("notification", NotificationEvent.class);
|
||||||
results.register("signal", SignalEvent.class);
|
results.register("signal", SignalEvent.class);
|
||||||
results.register("exit", ExitRequestEvent.class);
|
results.register("exit", ExitRequestEvent.class);
|
||||||
|
results.register("getSecureLevelInfo", GetSecureLevelInfoRequestEvent.class);
|
||||||
|
results.register("verifySecureLevelKey", VerifySecureLevelKeyRequestEvent.class);
|
||||||
|
results.register("securityReport", SecurityReportRequestEvent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void waitIfNotConnected() {
|
public void waitIfNotConnected() {
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(':LauncherAPI')
|
api project(':LauncherAPI')
|
||||||
compileOnly 'com.google.guava:guava:26.0-jre'
|
compileOnly group: 'com.google.guava', name: 'guava', version: rootProject['verGuavaC']
|
||||||
api files('../compat/authlib/authlib-clean.jar')
|
api files('../compat/authlib/authlib-clean.jar')
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
targetCompatibility = '1.8'
|
targetCompatibility = '1.8'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'org.fusesource.jansi:jansi:1.18'
|
compileOnly group: 'org.fusesource.jansi', name:'jansi', version: rootProject['verJansi']
|
||||||
compileOnly 'org.jline:jline:3.11.0'
|
compileOnly group: 'org.jline', name: 'jline', version: rootProject['verJline']
|
||||||
compileOnly 'org.jline:jline-reader:3.11.0'
|
compileOnly group: 'org.jline', name: 'jline-reader', version: rootProject['verJline']
|
||||||
compileOnly 'org.jline:jline-terminal:3.11.0'
|
compileOnly group: 'org.jline', name: 'jline-terminal', version: rootProject['verJline']
|
||||||
compileOnly 'org.bouncycastle:bcprov-jdk15:1.46'
|
compileOnly group: 'org.bouncycastle', name: 'bcprov-jdk15', version: rootProject['verBcprov']
|
||||||
api 'com.google.code.gson:gson:2.8.5'
|
api group: 'com.google.code.gson', name: 'gson', version: rootProject['verGson']
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.4.1'
|
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: rootProject['verJunit']
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
|
|
@ -15,8 +15,8 @@ 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 = 1;
|
public static final int PATCH = 2;
|
||||||
public static final int BUILD = 2;
|
public static final int BUILD = 1;
|
||||||
public static final Version.Type RELEASE = Type.BETA;
|
public static final Version.Type RELEASE = Type.BETA;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ task javadocJar(type: Jar) {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
pack project(':LauncherAuthlib')
|
pack project(':LauncherAuthlib')
|
||||||
pack 'io.netty:netty-codec-http:4.1.43.Final'
|
pack group: 'io.netty', name: 'netty-codec-http', version: rootProject['verNetty']
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
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.1'
|
version = '5.1.2'
|
||||||
|
|
||||||
|
apply from: 'props.gradle'
|
||||||
|
|
||||||
configure(subprojects.findAll { it.name != 'modules' }) {
|
configure(subprojects.findAll { it.name != 'modules' }) {
|
||||||
apply plugin: 'idea'
|
apply plugin: 'idea'
|
||||||
|
|
18
props.gradle
Normal file
18
props.gradle
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
project.ext {
|
||||||
|
verAsm = '7.2'
|
||||||
|
verNetty = '4.1.43.Final'
|
||||||
|
verOshiCore = '3.13.0'
|
||||||
|
verJunit = '5.6.0'
|
||||||
|
verGuavaC = '26.0-jre'
|
||||||
|
verJansi = '1.18'
|
||||||
|
verJline = '3.11.0'
|
||||||
|
verBcprov = '1.46'
|
||||||
|
verGson = '2.8.5'
|
||||||
|
verBcpkix = '1.61'
|
||||||
|
verSlf4j = '1.7.25'
|
||||||
|
verMySQLConn = '8.0.16'
|
||||||
|
verPostgreSQLConn = '42.2.6'
|
||||||
|
verProguard = '6.2.0'
|
||||||
|
verLaunch4j = '3.12'
|
||||||
|
verHibernate = '5.4.9.Final'
|
||||||
|
}
|
Loading…
Reference in a new issue