mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 03:31:15 +03:00
[REFACTOR] IDEA Code Reformat
This commit is contained in:
parent
3b839da3d3
commit
0b1f3f66af
53 changed files with 560 additions and 556 deletions
58
.github/workflows/codeql-analysis.yml
vendored
58
.github/workflows/codeql-analysis.yml
vendored
|
@ -34,37 +34,37 @@ jobs:
|
||||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v1
|
uses: github/codeql-action/init@v1
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
# By default, queries listed here will override any specified in a config file.
|
# By default, queries listed here will override any specified in a config file.
|
||||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v1
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
# and modify them (or add more) to build your code if your project
|
# and modify them (or add more) to build your code if your project
|
||||||
# uses a compiled language
|
# uses a compiled language
|
||||||
|
|
||||||
#- run: |
|
#- run: |
|
||||||
# make bootstrap
|
# make bootstrap
|
||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v1
|
uses: github/codeql-action/analyze@v1
|
||||||
|
|
|
@ -125,7 +125,7 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La
|
||||||
|
|
||||||
runtime.verify();
|
runtime.verify();
|
||||||
config.verify();
|
config.verify();
|
||||||
if(config.sessions == null) config.sessions = new MemorySessionStorage();
|
if (config.sessions == null) config.sessions = new MemorySessionStorage();
|
||||||
if (config.components != null) {
|
if (config.components != null) {
|
||||||
LogHelper.debug("PreInit components");
|
LogHelper.debug("PreInit components");
|
||||||
config.components.forEach((k, v) -> {
|
config.components.forEach((k, v) -> {
|
||||||
|
|
|
@ -76,14 +76,12 @@ public static void main(String[] args) throws Exception {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
LauncherTrustManager.CheckClassResult result = certificateManager.checkClass(LaunchServer.class);
|
LauncherTrustManager.CheckClassResult result = certificateManager.checkClass(LaunchServer.class);
|
||||||
if(result.type == LauncherTrustManager.CheckClassResultType.SUCCESS) {
|
if (result.type == LauncherTrustManager.CheckClassResultType.SUCCESS) {
|
||||||
LogHelper.info("LaunchServer signed by %s", result.endCertificate.getSubjectDN().getName());
|
LogHelper.info("LaunchServer signed by %s", result.endCertificate.getSubjectDN().getName());
|
||||||
}
|
} else if (result.type == LauncherTrustManager.CheckClassResultType.NOT_SIGNED) {
|
||||||
else if(result.type == LauncherTrustManager.CheckClassResultType.NOT_SIGNED) {
|
|
||||||
// None
|
// None
|
||||||
}
|
} else {
|
||||||
else {
|
if (result.exception != null) {
|
||||||
if(result.exception != null) {
|
|
||||||
LogHelper.error(result.exception);
|
LogHelper.error(result.exception);
|
||||||
}
|
}
|
||||||
LogHelper.warning("LaunchServer signed incorrectly. Status: %s", result.type.name());
|
LogHelper.warning("LaunchServer signed incorrectly. Status: %s", result.type.name());
|
||||||
|
|
|
@ -35,12 +35,6 @@ public void normalizeHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInf
|
||||||
if (hardwareInfo.hwDiskId != null) hardwareInfo.hwDiskId = hardwareInfo.hwDiskId.trim();
|
if (hardwareInfo.hwDiskId != null) hardwareInfo.hwDiskId = hardwareInfo.hwDiskId.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class HardwareInfoCompareResult {
|
|
||||||
public double firstSpoofingLevel = 0.0;
|
|
||||||
public double secondSpoofingLevel = 0.0;
|
|
||||||
public double compareLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Required normalize HardwareInfo
|
//Required normalize HardwareInfo
|
||||||
public HardwareInfoCompareResult compareHardwareInfo(HardwareReportRequest.HardwareInfo first, HardwareReportRequest.HardwareInfo second) {
|
public HardwareInfoCompareResult compareHardwareInfo(HardwareReportRequest.HardwareInfo first, HardwareReportRequest.HardwareInfo second) {
|
||||||
HardwareInfoCompareResult result = new HardwareInfoCompareResult();
|
HardwareInfoCompareResult result = new HardwareInfoCompareResult();
|
||||||
|
@ -111,4 +105,10 @@ public void init(LaunchServer server) {
|
||||||
public void close() {
|
public void close() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class HardwareInfoCompareResult {
|
||||||
|
public double firstSpoofingLevel = 0.0;
|
||||||
|
public double secondSpoofingLevel = 0.0;
|
||||||
|
public double compareLevel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,17 +13,6 @@ public class JsonHWIDProvider extends HWIDProvider {
|
||||||
public URL addPublicKeyToHardwareInfoRequest;
|
public URL addPublicKeyToHardwareInfoRequest;
|
||||||
public String apiKey;
|
public String apiKey;
|
||||||
|
|
||||||
public static class RequestFind {
|
|
||||||
public byte[] publicKey;
|
|
||||||
public Client client;
|
|
||||||
public String apiKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ResultFind {
|
|
||||||
public String error;
|
|
||||||
public HardwareReportRequest.HardwareInfo info;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] publicKey, Client client) throws HWIDException {
|
public HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] publicKey, Client client) throws HWIDException {
|
||||||
try {
|
try {
|
||||||
|
@ -41,17 +30,6 @@ public HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] pub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RequestCreate {
|
|
||||||
public byte[] publicKey;
|
|
||||||
public Client client;
|
|
||||||
public HardwareReportRequest.HardwareInfo hardwareInfo;
|
|
||||||
public String apiKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ResultCreate {
|
|
||||||
public String error;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException {
|
public void createHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException {
|
||||||
try {
|
try {
|
||||||
|
@ -69,18 +47,6 @@ public void createHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RequestAddKey {
|
|
||||||
public byte[] publicKey;
|
|
||||||
public Client client;
|
|
||||||
public HardwareReportRequest.HardwareInfo hardwareInfo;
|
|
||||||
public String apiKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ResultAddKey {
|
|
||||||
public String error;
|
|
||||||
public boolean success;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException {
|
public boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException {
|
||||||
try {
|
try {
|
||||||
|
@ -98,4 +64,38 @@ public boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo har
|
||||||
throw new HWIDException(t);
|
throw new HWIDException(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class RequestFind {
|
||||||
|
public byte[] publicKey;
|
||||||
|
public Client client;
|
||||||
|
public String apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ResultFind {
|
||||||
|
public String error;
|
||||||
|
public HardwareReportRequest.HardwareInfo info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RequestCreate {
|
||||||
|
public byte[] publicKey;
|
||||||
|
public Client client;
|
||||||
|
public HardwareReportRequest.HardwareInfo hardwareInfo;
|
||||||
|
public String apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ResultCreate {
|
||||||
|
public String error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RequestAddKey {
|
||||||
|
public byte[] publicKey;
|
||||||
|
public Client client;
|
||||||
|
public HardwareReportRequest.HardwareInfo hardwareInfo;
|
||||||
|
public String apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ResultAddKey {
|
||||||
|
public String error;
|
||||||
|
public boolean success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
public class MemoryHWIDProvider extends HWIDProvider implements Reconfigurable {
|
public class MemoryHWIDProvider extends HWIDProvider implements Reconfigurable {
|
||||||
public double warningSpoofingLevel = -1.0;
|
public double warningSpoofingLevel = -1.0;
|
||||||
public double criticalCompareLevel = 1.0;
|
public double criticalCompareLevel = 1.0;
|
||||||
|
public Set<MemoryHWIDEntity> db = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Command> getCommands() {
|
public Map<String, Command> getCommands() {
|
||||||
|
@ -47,21 +48,6 @@ public void invoke(String... args) throws Exception {
|
||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class MemoryHWIDEntity {
|
|
||||||
public HardwareReportRequest.HardwareInfo hardware;
|
|
||||||
public byte[] publicKey;
|
|
||||||
public boolean banned;
|
|
||||||
public long id;
|
|
||||||
|
|
||||||
public MemoryHWIDEntity(HardwareReportRequest.HardwareInfo hardware, byte[] publicKey) {
|
|
||||||
this.hardware = hardware;
|
|
||||||
this.publicKey = publicKey;
|
|
||||||
this.id = SecurityHelper.newRandom().nextLong();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<MemoryHWIDEntity> db = ConcurrentHashMap.newKeySet();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] publicKey, Client client) throws HWIDException {
|
public HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] publicKey, Client client) throws HWIDException {
|
||||||
for (MemoryHWIDEntity e : db) {
|
for (MemoryHWIDEntity e : db) {
|
||||||
|
@ -96,4 +82,17 @@ public boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo har
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class MemoryHWIDEntity {
|
||||||
|
public HardwareReportRequest.HardwareInfo hardware;
|
||||||
|
public byte[] publicKey;
|
||||||
|
public boolean banned;
|
||||||
|
public long id;
|
||||||
|
|
||||||
|
public MemoryHWIDEntity(HardwareReportRequest.HardwareInfo hardware, byte[] publicKey) {
|
||||||
|
this.hardware = hardware;
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
this.id = SecurityHelper.newRandom().nextLong();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,14 @@
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public final class RequestAuthProvider extends AuthProvider {
|
public final class RequestAuthProvider extends AuthProvider {
|
||||||
|
private final HttpClient client = HttpClient.newBuilder()
|
||||||
|
.build();
|
||||||
public String url;
|
public String url;
|
||||||
public transient Pattern pattern;
|
public transient Pattern pattern;
|
||||||
public String response;
|
public String response;
|
||||||
public boolean flagsEnabled;
|
public boolean flagsEnabled;
|
||||||
public boolean usePermission = true;
|
public boolean usePermission = true;
|
||||||
public int timeout = 5000;
|
public int timeout = 5000;
|
||||||
private final HttpClient client = HttpClient.newBuilder()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(LaunchServer srv) {
|
public void init(LaunchServer srv) {
|
||||||
|
|
|
@ -12,7 +12,10 @@
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@ -26,7 +29,7 @@ public class MemorySessionStorage extends SessionStorage implements NeedGarbageC
|
||||||
@Override
|
@Override
|
||||||
public void init(LaunchServer server) {
|
public void init(LaunchServer server) {
|
||||||
super.init(server);
|
super.init(server);
|
||||||
if(autoDump) {
|
if (autoDump) {
|
||||||
loadSessionsData();
|
loadSessionsData();
|
||||||
garbageCollection();
|
garbageCollection();
|
||||||
}
|
}
|
||||||
|
@ -36,14 +39,14 @@ public void init(LaunchServer server) {
|
||||||
public byte[] getSessionData(UUID session) {
|
public byte[] getSessionData(UUID session) {
|
||||||
|
|
||||||
Entry e = clientSet.get(session);
|
Entry e = clientSet.get(session);
|
||||||
if(e == null) return null;
|
if (e == null) return null;
|
||||||
return e.data;
|
return e.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UUID> getSessionsFromUserUUID(UUID userUUID) {
|
public Stream<UUID> getSessionsFromUserUUID(UUID userUUID) {
|
||||||
Set<Entry> set = uuidIndex.get(userUUID);
|
Set<Entry> set = uuidIndex.get(userUUID);
|
||||||
if(set != null) return set.stream().map((e) -> e.sessionUuid);
|
if (set != null) return set.stream().map((e) -> e.sessionUuid);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +55,7 @@ public boolean writeSession(UUID userUUID, UUID sessionUUID, byte[] data) {
|
||||||
deleteSession(sessionUUID);
|
deleteSession(sessionUUID);
|
||||||
Entry e = new Entry(data, sessionUUID);
|
Entry e = new Entry(data, sessionUUID);
|
||||||
clientSet.put(sessionUUID, e);
|
clientSet.put(sessionUUID, e);
|
||||||
if(userUUID != null) {
|
if (userUUID != null) {
|
||||||
Set<Entry> uuidSet = uuidIndex.computeIfAbsent(userUUID, k -> ConcurrentHashMap.newKeySet());
|
Set<Entry> uuidSet = uuidIndex.computeIfAbsent(userUUID, k -> ConcurrentHashMap.newKeySet());
|
||||||
uuidSet.add(e);
|
uuidSet.add(e);
|
||||||
}
|
}
|
||||||
|
@ -61,10 +64,10 @@ public boolean writeSession(UUID userUUID, UUID sessionUUID, byte[] data) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteSession(UUID sessionUUID) {
|
public boolean deleteSession(UUID sessionUUID) {
|
||||||
Entry e =clientSet.remove(sessionUUID);
|
Entry e = clientSet.remove(sessionUUID);
|
||||||
if(e != null) {
|
if (e != null) {
|
||||||
Set<Entry> set = uuidIndex.get(sessionUUID);
|
Set<Entry> set = uuidIndex.get(sessionUUID);
|
||||||
if(set != null) {
|
if (set != null) {
|
||||||
removeUuidFromIndexSet(set, e, sessionUUID);
|
removeUuidFromIndexSet(set, e, sessionUUID);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -75,8 +78,8 @@ public boolean deleteSession(UUID sessionUUID) {
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteSessionsByUserUUID(UUID userUUID) {
|
public boolean deleteSessionsByUserUUID(UUID userUUID) {
|
||||||
Set<Entry> set = uuidIndex.get(userUUID);
|
Set<Entry> set = uuidIndex.get(userUUID);
|
||||||
if(set != null) {
|
if (set != null) {
|
||||||
for(Entry e : set) {
|
for (Entry e : set) {
|
||||||
clientSet.remove(e.sessionUuid);
|
clientSet.remove(e.sessionUuid);
|
||||||
}
|
}
|
||||||
set.clear();
|
set.clear();
|
||||||
|
@ -94,7 +97,7 @@ public void clear() {
|
||||||
public void dumpSessionsData() {
|
public void dumpSessionsData() {
|
||||||
DumpedData dumpedData = new DumpedData(clientSet, uuidIndex);
|
DumpedData dumpedData = new DumpedData(clientSet, uuidIndex);
|
||||||
Path path = Paths.get(dumpFile);
|
Path path = Paths.get(dumpFile);
|
||||||
try(Writer writer = IOHelper.newWriter(path)) {
|
try (Writer writer = IOHelper.newWriter(path)) {
|
||||||
Launcher.gsonManager.gson.toJson(dumpedData, writer);
|
Launcher.gsonManager.gson.toJson(dumpedData, writer);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
|
@ -103,8 +106,8 @@ public void dumpSessionsData() {
|
||||||
|
|
||||||
public void loadSessionsData() {
|
public void loadSessionsData() {
|
||||||
Path path = Paths.get(dumpFile);
|
Path path = Paths.get(dumpFile);
|
||||||
if(!Files.exists(path)) return;
|
if (!Files.exists(path)) return;
|
||||||
try(Reader reader = IOHelper.newReader(path)) {
|
try (Reader reader = IOHelper.newReader(path)) {
|
||||||
DumpedData data = Launcher.gsonManager.gson.fromJson(reader, DumpedData.class);
|
DumpedData data = Launcher.gsonManager.gson.fromJson(reader, DumpedData.class);
|
||||||
clientSet.putAll(data.clientSet);
|
clientSet.putAll(data.clientSet);
|
||||||
uuidIndex.putAll(data.uuidIndex);
|
uuidIndex.putAll(data.uuidIndex);
|
||||||
|
@ -135,7 +138,7 @@ public void unlockUser(UUID userUUID) {
|
||||||
|
|
||||||
private void removeUuidFromIndexSet(Set<Entry> set, Entry e, UUID session) {
|
private void removeUuidFromIndexSet(Set<Entry> set, Entry e, UUID session) {
|
||||||
set.remove(e);
|
set.remove(e);
|
||||||
if(set.isEmpty()) {
|
if (set.isEmpty()) {
|
||||||
uuidIndex.remove(session);
|
uuidIndex.remove(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,10 +150,10 @@ public void garbageCollection() {
|
||||||
Set<UUID> to_delete = new HashSet<>(32);
|
Set<UUID> to_delete = new HashSet<>(32);
|
||||||
clientSet.forEach((uuid, entry) -> {
|
clientSet.forEach((uuid, entry) -> {
|
||||||
long timestamp = entry.timestamp;
|
long timestamp = entry.timestamp;
|
||||||
if(timestamp + session_timeout < time)
|
if (timestamp + session_timeout < time)
|
||||||
to_delete.add(uuid);
|
to_delete.add(uuid);
|
||||||
});
|
});
|
||||||
for(UUID session : to_delete) {
|
for (UUID session : to_delete) {
|
||||||
deleteSession(session);
|
deleteSession(session);
|
||||||
}
|
}
|
||||||
to_delete.clear();
|
to_delete.clear();
|
||||||
|
@ -158,7 +161,7 @@ public void garbageCollection() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if(autoDump) {
|
if (autoDump) {
|
||||||
garbageCollection();
|
garbageCollection();
|
||||||
dumpSessionsData();
|
dumpSessionsData();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,30 +7,41 @@
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public abstract class SessionStorage {
|
public abstract class SessionStorage {
|
||||||
protected transient LaunchServer server;
|
|
||||||
public static ProviderMap<SessionStorage> providers = new ProviderMap<>();
|
public static ProviderMap<SessionStorage> providers = new ProviderMap<>();
|
||||||
private static boolean registeredProviders = false;
|
private static boolean registeredProviders = false;
|
||||||
public abstract byte[] getSessionData(UUID session);
|
protected transient LaunchServer server;
|
||||||
public abstract Stream<UUID> getSessionsFromUserUUID(UUID userUUID);
|
|
||||||
public abstract boolean writeSession(UUID userUUID, UUID sessionUUID, byte[] data);
|
|
||||||
public abstract boolean deleteSession(UUID sessionUUID);
|
|
||||||
public boolean deleteSessionsByUserUUID(UUID userUUID) {
|
|
||||||
getSessionsFromUserUUID(userUUID).forEach(this::deleteSession);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public abstract void clear();
|
|
||||||
public abstract void lockSession(UUID sessionUUID);
|
|
||||||
public abstract void lockUser(UUID userUUID);
|
|
||||||
public abstract void unlockSession(UUID sessionUUID);
|
|
||||||
public abstract void unlockUser(UUID userUUID);
|
|
||||||
public void init(LaunchServer server)
|
|
||||||
{
|
|
||||||
this.server = server;
|
|
||||||
}
|
|
||||||
public static void registerProviders() {
|
public static void registerProviders() {
|
||||||
if(!registeredProviders) {
|
if (!registeredProviders) {
|
||||||
providers.register("memory", MemorySessionStorage.class);
|
providers.register("memory", MemorySessionStorage.class);
|
||||||
registeredProviders = true;
|
registeredProviders = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract byte[] getSessionData(UUID session);
|
||||||
|
|
||||||
|
public abstract Stream<UUID> getSessionsFromUserUUID(UUID userUUID);
|
||||||
|
|
||||||
|
public abstract boolean writeSession(UUID userUUID, UUID sessionUUID, byte[] data);
|
||||||
|
|
||||||
|
public abstract boolean deleteSession(UUID sessionUUID);
|
||||||
|
|
||||||
|
public boolean deleteSessionsByUserUUID(UUID userUUID) {
|
||||||
|
getSessionsFromUserUUID(userUUID).forEach(this::deleteSession);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void clear();
|
||||||
|
|
||||||
|
public abstract void lockSession(UUID sessionUUID);
|
||||||
|
|
||||||
|
public abstract void lockUser(UUID userUUID);
|
||||||
|
|
||||||
|
public abstract void unlockSession(UUID sessionUUID);
|
||||||
|
|
||||||
|
public abstract void unlockUser(UUID userUUID);
|
||||||
|
|
||||||
|
public void init(LaunchServer server) {
|
||||||
|
this.server = server;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
public class CertificateAutogenTask implements LauncherBuildTask {
|
public class CertificateAutogenTask implements LauncherBuildTask {
|
||||||
|
private final LaunchServer server;
|
||||||
public X509Certificate certificate;
|
public X509Certificate certificate;
|
||||||
public X509CertificateHolder bcCertificate;
|
public X509CertificateHolder bcCertificate;
|
||||||
public CMSSignedDataGenerator signedDataGenerator;
|
public CMSSignedDataGenerator signedDataGenerator;
|
||||||
private final LaunchServer server;
|
|
||||||
|
|
||||||
public CertificateAutogenTask(LaunchServer server) {
|
public CertificateAutogenTask(LaunchServer server) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
|
|
|
@ -28,12 +28,12 @@
|
||||||
|
|
||||||
public class MainBuildTask implements LauncherBuildTask {
|
public class MainBuildTask implements LauncherBuildTask {
|
||||||
public final ClassMetadataReader reader;
|
public final ClassMetadataReader reader;
|
||||||
private final LaunchServer server;
|
|
||||||
public final Set<String> blacklist = new HashSet<>();
|
public final Set<String> blacklist = new HashSet<>();
|
||||||
public final List<Transformer> transformers = new ArrayList<>();
|
public final List<Transformer> transformers = new ArrayList<>();
|
||||||
public final IOHookSet<BuildContext> preBuildHook = new IOHookSet<>();
|
public final IOHookSet<BuildContext> preBuildHook = new IOHookSet<>();
|
||||||
public final IOHookSet<BuildContext> postBuildHook = new IOHookSet<>();
|
public final IOHookSet<BuildContext> postBuildHook = new IOHookSet<>();
|
||||||
public final Map<String, Object> properties = new HashMap<>();
|
public final Map<String, Object> properties = new HashMap<>();
|
||||||
|
private final LaunchServer server;
|
||||||
|
|
||||||
public MainBuildTask(LaunchServer srv) {
|
public MainBuildTask(LaunchServer srv) {
|
||||||
server = srv;
|
server = srv;
|
||||||
|
|
|
@ -39,7 +39,7 @@ public void invoke(String... args) {
|
||||||
LogHelper.subInfo("userUUID: %s | session %s", client.uuid == null ? "null" : client.uuid.toString(), client.session == null ? "null" : client.session);
|
LogHelper.subInfo("userUUID: %s | session %s", client.uuid == null ? "null" : client.uuid.toString(), client.session == null ? "null" : client.session);
|
||||||
LogHelper.subInfo("Data: checkSign %s | auth_id %s", client.checkSign ? "true" : "false",
|
LogHelper.subInfo("Data: checkSign %s | auth_id %s", client.checkSign ? "true" : "false",
|
||||||
client.auth_id);
|
client.auth_id);
|
||||||
if(client.trustLevel != null) {
|
if (client.trustLevel != null) {
|
||||||
LogHelper.subInfo("trustLevel | key %s | pubkey %s", client.trustLevel.keyChecked ? "checked" : "unchecked", client.trustLevel.publicKey == null ? "null" : Base64.getEncoder().encode(client.trustLevel.publicKey));
|
LogHelper.subInfo("trustLevel | key %s | pubkey %s", client.trustLevel.keyChecked ? "checked" : "unchecked", client.trustLevel.publicKey == null ? "null" : Base64.getEncoder().encode(client.trustLevel.publicKey));
|
||||||
}
|
}
|
||||||
LogHelper.subInfo("Permissions: %s (permissions %d | flags %d)", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.permissions, client.permissions == null ? 0 : client.permissions.flags);
|
LogHelper.subInfo("Permissions: %s (permissions %d | flags %d)", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.permissions, client.permissions == null ? 0 : client.permissions.flags);
|
||||||
|
|
|
@ -24,10 +24,8 @@ public String getUsageDescription() {
|
||||||
public void invoke(String... args) {
|
public void invoke(String... args) {
|
||||||
server.pingServerManager.map.forEach((name, data) -> {
|
server.pingServerManager.map.forEach((name, data) -> {
|
||||||
LogHelper.info("[%s] online %d / %d", name, data.lastReport == null ? -1 : data.lastReport.playersOnline, data.lastReport == null ? -1 : data.lastReport.maxPlayers);
|
LogHelper.info("[%s] online %d / %d", name, data.lastReport == null ? -1 : data.lastReport.playersOnline, data.lastReport == null ? -1 : data.lastReport.maxPlayers);
|
||||||
if(data.lastReport != null && data.lastReport.users != null)
|
if (data.lastReport != null && data.lastReport.users != null) {
|
||||||
{
|
for (PingServerReportRequest.PingServerReport.UsernameInfo user : data.lastReport.users) {
|
||||||
for(PingServerReportRequest.PingServerReport.UsernameInfo user : data.lastReport.users)
|
|
||||||
{
|
|
||||||
LogHelper.subInfo("User %s", user.username == null ? "null" : user.username);
|
LogHelper.subInfo("User %s", user.username == null ? "null" : user.username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,20 @@ public SecurityCheckCommand(LaunchServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void printCheckResult(LogHelper.Level level, String module, String comment, Boolean status) {
|
||||||
|
LogHelper.rawLog(() -> FormatHelper.rawFormat(level, LogHelper.getDataTime(), false).concat(String.format("[%s] %s - %s", module, comment, status == null ? "WARN" : (status ? "OK" : "FAIL"))),
|
||||||
|
() -> FormatHelper.rawAnsiFormat(level, LogHelper.getDataTime(), false)
|
||||||
|
.fgBright(Ansi.Color.WHITE)
|
||||||
|
.a("[")
|
||||||
|
.fgBright(Ansi.Color.BLUE)
|
||||||
|
.a(module)
|
||||||
|
.fgBright(Ansi.Color.WHITE)
|
||||||
|
.a("] ".concat(comment).concat(" - "))
|
||||||
|
.fgBright(status == null ? Ansi.Color.YELLOW : (status ? Ansi.Color.GREEN : Ansi.Color.RED))
|
||||||
|
.a(status == null ? "WARN" : (status ? "OK" : "FAIL"))
|
||||||
|
.reset().toString());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getArgsDescription() {
|
public String getArgsDescription() {
|
||||||
return "[]";
|
return "[]";
|
||||||
|
@ -158,7 +172,7 @@ public void invoke(String... args) {
|
||||||
if (tokenizer.hasMoreTokens() && tokenizer.nextToken().equals("mods")) {
|
if (tokenizer.hasMoreTokens() && tokenizer.nextToken().equals("mods")) {
|
||||||
String nextToken = tokenizer.nextToken();
|
String nextToken = tokenizer.nextToken();
|
||||||
if (!tokenizer.hasMoreTokens()) {
|
if (!tokenizer.hasMoreTokens()) {
|
||||||
if(!exc.endsWith("/")) {
|
if (!exc.endsWith("/")) {
|
||||||
printCheckResult(LogHelper.Level.INFO, profileModuleName, String.format("updateExclusions %s not safe. Cheats may be injected very easy!", exc), false);
|
printCheckResult(LogHelper.Level.INFO, profileModuleName, String.format("updateExclusions %s not safe. Cheats may be injected very easy!", exc), false);
|
||||||
bad = true;
|
bad = true;
|
||||||
}
|
}
|
||||||
|
@ -175,18 +189,4 @@ public void invoke(String... args) {
|
||||||
}
|
}
|
||||||
LogHelper.info("Check completed");
|
LogHelper.info("Check completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void printCheckResult(LogHelper.Level level, String module, String comment, Boolean status) {
|
|
||||||
LogHelper.rawLog(() -> FormatHelper.rawFormat(level, LogHelper.getDataTime(), false).concat(String.format("[%s] %s - %s", module, comment, status == null ? "WARN" : (status ? "OK" : "FAIL"))),
|
|
||||||
() -> FormatHelper.rawAnsiFormat(level, LogHelper.getDataTime(), false)
|
|
||||||
.fgBright(Ansi.Color.WHITE)
|
|
||||||
.a("[")
|
|
||||||
.fgBright(Ansi.Color.BLUE)
|
|
||||||
.a(module)
|
|
||||||
.fgBright(Ansi.Color.WHITE)
|
|
||||||
.a("] ".concat(comment).concat(" - "))
|
|
||||||
.fgBright(status == null ? Ansi.Color.YELLOW : (status ? Ansi.Color.GREEN : Ansi.Color.RED))
|
|
||||||
.a(status == null ? "WARN" : (status ? "OK" : "FAIL"))
|
|
||||||
.reset().toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,7 @@ public void init(LaunchServer.ReloadType type) {
|
||||||
protectHandler.init(server);
|
protectHandler.init(server);
|
||||||
protectHandler.checkLaunchServerLicense();
|
protectHandler.checkLaunchServerLicense();
|
||||||
}
|
}
|
||||||
if(sessions != null) {
|
if (sessions != null) {
|
||||||
sessions.init(server);
|
sessions.init(server);
|
||||||
server.registerObject("sessions", sessions);
|
server.registerObject("sessions", sessions);
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ public void close(LaunchServer.ReloadType type) {
|
||||||
server.unregisterObject("protectHandler", protectHandler);
|
server.unregisterObject("protectHandler", protectHandler);
|
||||||
protectHandler.close();
|
protectHandler.close();
|
||||||
}
|
}
|
||||||
if(sessions != null) {
|
if (sessions != null) {
|
||||||
server.unregisterObject("sessions", sessions);
|
server.unregisterObject("sessions", sessions);
|
||||||
if (sessions instanceof AutoCloseable) {
|
if (sessions instanceof AutoCloseable) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -68,6 +68,22 @@ public void syncModules() throws IOException {
|
||||||
IOHelper.walk(modulesDir, new ModulesVisitor(), false);
|
IOHelper.walk(modulesDir, new ModulesVisitor(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addClassFieldsToProperties(Map<String, Object> propertyMap, String prefix, Object object, Class<?> classOfObject) throws IllegalAccessException {
|
||||||
|
Field[] fields = classOfObject.getFields();
|
||||||
|
for (Field field : fields) {
|
||||||
|
if ((field.getModifiers() & Modifier.STATIC) != 0) continue;
|
||||||
|
Object obj = field.get(object);
|
||||||
|
String propertyName = prefix.concat(".").concat(field.getName().toLowerCase(Locale.US));
|
||||||
|
if (InjectClassAcceptor.isSerializableValue(obj)) {
|
||||||
|
LogHelper.dev("Property name %s", propertyName);
|
||||||
|
propertyMap.put(propertyName, obj);
|
||||||
|
} else {
|
||||||
|
//Try recursive add fields
|
||||||
|
addClassFieldsToProperties(propertyMap, propertyName, obj, obj.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static class ModuleEntity {
|
static class ModuleEntity {
|
||||||
public Path path;
|
public Path path;
|
||||||
public String moduleMainClass;
|
public String moduleMainClass;
|
||||||
|
@ -132,20 +148,4 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
||||||
return super.visitFile(file, attrs);
|
return super.visitFile(file, attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addClassFieldsToProperties(Map<String, Object> propertyMap, String prefix, Object object, Class<?> classOfObject) throws IllegalAccessException {
|
|
||||||
Field[] fields = classOfObject.getFields();
|
|
||||||
for (Field field : fields) {
|
|
||||||
if ((field.getModifiers() & Modifier.STATIC) != 0) continue;
|
|
||||||
Object obj = field.get(object);
|
|
||||||
String propertyName = prefix.concat(".").concat(field.getName().toLowerCase(Locale.US));
|
|
||||||
if (InjectClassAcceptor.isSerializableValue(obj)) {
|
|
||||||
LogHelper.dev("Property name %s", propertyName);
|
|
||||||
propertyMap.put(propertyName, obj);
|
|
||||||
} else {
|
|
||||||
//Try recursive add fields
|
|
||||||
addClassFieldsToProperties(propertyMap, propertyName, obj, obj.getClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,6 +210,7 @@ else if (mode == LauncherTrustManager.CheckMode.WARN_IN_NOT_SIGNED)
|
||||||
throw new SecurityException(e);
|
throw new SecurityException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LauncherTrustManager.CheckClassResult checkClass(Class<?> clazz) {
|
public LauncherTrustManager.CheckClassResult checkClass(Class<?> clazz) {
|
||||||
X509Certificate[] certificates = JVMHelper.getCertificates(clazz);
|
X509Certificate[] certificates = JVMHelper.getCertificates(clazz);
|
||||||
return trustManager.checkCertificates(certificates, trustManager::stdCertificateChecker);
|
return trustManager.checkCertificates(certificates, trustManager::stdCertificateChecker);
|
||||||
|
|
|
@ -9,30 +9,8 @@
|
||||||
|
|
||||||
public class PingServerManager {
|
public class PingServerManager {
|
||||||
public static final long REPORT_EXPIRED_TIME = 20 * 1000;
|
public static final long REPORT_EXPIRED_TIME = 20 * 1000;
|
||||||
|
|
||||||
public static class ServerInfoEntry {
|
|
||||||
public PingServerReportRequest.PingServerReport lastReport;
|
|
||||||
public long lastReportTime;
|
|
||||||
public final ClientProfile profile;
|
|
||||||
|
|
||||||
public ServerInfoEntry(ClientProfile profile, PingServerReportRequest.PingServerReport lastReport) {
|
|
||||||
this.lastReport = lastReport;
|
|
||||||
this.profile = profile;
|
|
||||||
this.lastReportTime = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServerInfoEntry(ClientProfile profile) {
|
|
||||||
this.profile = profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isExpired() {
|
|
||||||
return System.currentTimeMillis() - lastReportTime > REPORT_EXPIRED_TIME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Map<String, ServerInfoEntry> map = new HashMap<>();
|
public final Map<String, ServerInfoEntry> map = new HashMap<>();
|
||||||
private final LaunchServer server;
|
private final LaunchServer server;
|
||||||
|
|
||||||
public PingServerManager(LaunchServer server) {
|
public PingServerManager(LaunchServer server) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
}
|
}
|
||||||
|
@ -58,4 +36,24 @@ public boolean updateServer(String name, PingServerReportRequest.PingServerRepor
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ServerInfoEntry {
|
||||||
|
public final ClientProfile profile;
|
||||||
|
public PingServerReportRequest.PingServerReport lastReport;
|
||||||
|
public long lastReportTime;
|
||||||
|
|
||||||
|
public ServerInfoEntry(ClientProfile profile, PingServerReportRequest.PingServerReport lastReport) {
|
||||||
|
this.lastReport = lastReport;
|
||||||
|
this.profile = profile;
|
||||||
|
this.lastReportTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerInfoEntry(ClientProfile profile) {
|
||||||
|
this.profile = profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExpired() {
|
||||||
|
return System.currentTimeMillis() - lastReportTime > REPORT_EXPIRED_TIME;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
import pro.gravit.utils.HookSet;
|
import pro.gravit.utils.HookSet;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ public SessionManager(LaunchServer server) {
|
||||||
|
|
||||||
|
|
||||||
public boolean addClient(Client client) {
|
public boolean addClient(Client client) {
|
||||||
if(client == null || client.session == null) return false;
|
if (client == null || client.session == null) return false;
|
||||||
return server.config.sessions.writeSession(client.uuid, client.session, compressClient(client));
|
return server.config.sessions.writeSession(client.uuid, client.session, compressClient(client));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +37,7 @@ public boolean removeByUUID(UUID uuid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Set<UUID> getSavedUUIDs()
|
public Set<UUID> getSavedUUIDs() {
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,15 +52,16 @@ private byte[] compressClient(Client client) {
|
||||||
private Client decompressClient(byte[] client) {
|
private Client decompressClient(byte[] client) {
|
||||||
return Launcher.gsonManager.gson.fromJson(new String(client, StandardCharsets.UTF_8), Client.class); //Compress using later
|
return Launcher.gsonManager.gson.fromJson(new String(client, StandardCharsets.UTF_8), Client.class); //Compress using later
|
||||||
}
|
}
|
||||||
|
|
||||||
private Client restoreFromString(byte[] data) {
|
private Client restoreFromString(byte[] data) {
|
||||||
Client result = decompressClient(data);
|
Client result = decompressClient(data);
|
||||||
result.updateAuth(server);
|
result.updateAuth(server);
|
||||||
if(result.auth != null && (result.username != null)) {
|
if (result.auth != null && (result.username != null)) {
|
||||||
if(result.auth.handler instanceof RequiredDAO || result.auth.provider instanceof RequiredDAO || result.auth.textureProvider instanceof RequiredDAO) {
|
if (result.auth.handler instanceof RequiredDAO || result.auth.provider instanceof RequiredDAO || result.auth.textureProvider instanceof RequiredDAO) {
|
||||||
result.daoObject = server.config.dao.userDAO.findByUsername(result.username);
|
result.daoObject = server.config.dao.userDAO.findByUsername(result.username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(result.refCount == null) result.refCount = new AtomicInteger(1);
|
if (result.refCount == null) result.refCount = new AtomicInteger(1);
|
||||||
clientRestoreHook.hook(result);
|
clientRestoreHook.hook(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -71,9 +72,9 @@ public void garbageCollection() {
|
||||||
|
|
||||||
|
|
||||||
public Client getClient(UUID session) {
|
public Client getClient(UUID session) {
|
||||||
if(session == null) return null;
|
if (session == null) return null;
|
||||||
byte[] data = server.config.sessions.getSessionData(session);
|
byte[] data = server.config.sessions.getSessionData(session);
|
||||||
if(data == null) return null;
|
if (data == null) return null;
|
||||||
return restoreFromString(data);
|
return restoreFromString(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +102,7 @@ public void updateClient(UUID session) {
|
||||||
public Set<Client> getSessions() {
|
public Set<Client> getSessions() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void loadSessions(Set<Client> set) {
|
public void loadSessions(Set<Client> set) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|
|
@ -28,12 +28,12 @@ public void printModulesInfo() {
|
||||||
for (LauncherModule module : modules) {
|
for (LauncherModule module : modules) {
|
||||||
LauncherModuleInfo info = module.getModuleInfo();
|
LauncherModuleInfo info = module.getModuleInfo();
|
||||||
LauncherTrustManager.CheckClassResult checkStatus = module.getCheckResult();
|
LauncherTrustManager.CheckClassResult checkStatus = module.getCheckResult();
|
||||||
LogHelper.info("[MODULE] %s v: %s p: %d deps: %s sig: %s", info.name, info.version.getVersionString(), info.priority, Arrays.toString(info.dependencies), checkStatus == null ? "null": checkStatus.type);
|
LogHelper.info("[MODULE] %s v: %s p: %d deps: %s sig: %s", info.name, info.version.getVersionString(), info.priority, Arrays.toString(info.dependencies), checkStatus == null ? "null" : checkStatus.type);
|
||||||
if(checkStatus != null && checkStatus.endCertificate != null) {
|
if (checkStatus != null && checkStatus.endCertificate != null) {
|
||||||
X509Certificate cert = checkStatus.endCertificate;
|
X509Certificate cert = checkStatus.endCertificate;
|
||||||
LogHelper.info("[MODULE CERT] Module signer: %s", cert.getSubjectDN().getName());
|
LogHelper.info("[MODULE CERT] Module signer: %s", cert.getSubjectDN().getName());
|
||||||
}
|
}
|
||||||
if(checkStatus != null && checkStatus.rootCertificate != null) {
|
if (checkStatus != null && checkStatus.rootCertificate != null) {
|
||||||
X509Certificate cert = checkStatus.rootCertificate;
|
X509Certificate cert = checkStatus.rootCertificate;
|
||||||
LogHelper.info("[MODULE CERT] Module signer CA: %s", cert.getSubjectDN().getName());
|
LogHelper.info("[MODULE CERT] Module signer CA: %s", cert.getSubjectDN().getName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,22 +57,6 @@ public void updateAuth(LaunchServer server) {
|
||||||
else auth = server.config.getAuthProviderPair(auth_id);
|
else auth = server.config.getAuthProviderPair(auth_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public enum Type {
|
|
||||||
SERVER,
|
|
||||||
USER
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TrustLevel {
|
|
||||||
public byte[] verifySecureKey;
|
|
||||||
public boolean keyChecked;
|
|
||||||
public byte[] publicKey;
|
|
||||||
public HardwareReportRequest.HardwareInfo hardwareInfo;
|
|
||||||
// May be used later
|
|
||||||
public double rating;
|
|
||||||
public long latestMillis;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> T getProperty(String name) {
|
public <T> T getProperty(String name) {
|
||||||
if (properties == null) properties = new HashMap<>();
|
if (properties == null) properties = new HashMap<>();
|
||||||
|
@ -93,4 +77,20 @@ public void setSerializableProperty(String name, String value) {
|
||||||
if (serializableProperties == null) serializableProperties = new HashMap<>();
|
if (serializableProperties == null) serializableProperties = new HashMap<>();
|
||||||
properties.put(name, value);
|
properties.put(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public enum Type {
|
||||||
|
SERVER,
|
||||||
|
USER
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TrustLevel {
|
||||||
|
public byte[] verifySecureKey;
|
||||||
|
public boolean keyChecked;
|
||||||
|
public byte[] publicKey;
|
||||||
|
public HardwareReportRequest.HardwareInfo hardwareInfo;
|
||||||
|
// May be used later
|
||||||
|
public double rating;
|
||||||
|
public long latestMillis;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,20 +48,16 @@ public class WebSocketService {
|
||||||
public static final ProviderMap<WebSocketServerResponse> providers = new ProviderMap<>();
|
public static final ProviderMap<WebSocketServerResponse> providers = new ProviderMap<>();
|
||||||
public final ChannelGroup channels;
|
public final ChannelGroup channels;
|
||||||
public final BiHookSet<WebSocketRequestContext, ChannelHandlerContext> hook = new BiHookSet<>();
|
public final BiHookSet<WebSocketRequestContext, ChannelHandlerContext> hook = new BiHookSet<>();
|
||||||
private final LaunchServer server;
|
|
||||||
private final Gson gson;
|
|
||||||
|
|
||||||
//Statistic data
|
//Statistic data
|
||||||
public final AtomicLong shortRequestLatency = new AtomicLong();
|
public final AtomicLong shortRequestLatency = new AtomicLong();
|
||||||
public final AtomicLong shortRequestCounter = new AtomicLong();
|
public final AtomicLong shortRequestCounter = new AtomicLong();
|
||||||
|
|
||||||
public final AtomicLong middleRequestLatency = new AtomicLong();
|
public final AtomicLong middleRequestLatency = new AtomicLong();
|
||||||
public final AtomicLong middleRequestCounter = new AtomicLong();
|
public final AtomicLong middleRequestCounter = new AtomicLong();
|
||||||
|
|
||||||
public final AtomicLong longRequestLatency = new AtomicLong();
|
public final AtomicLong longRequestLatency = new AtomicLong();
|
||||||
public final AtomicLong longRequestCounter = new AtomicLong();
|
public final AtomicLong longRequestCounter = new AtomicLong();
|
||||||
|
|
||||||
public final AtomicLong lastRequestTime = new AtomicLong();
|
public final AtomicLong lastRequestTime = new AtomicLong();
|
||||||
|
private final LaunchServer server;
|
||||||
|
private final Gson gson;
|
||||||
|
|
||||||
public WebSocketService(ChannelGroup channels, LaunchServer server) {
|
public WebSocketService(ChannelGroup channels, LaunchServer server) {
|
||||||
this.channels = channels;
|
this.channels = channels;
|
||||||
|
@ -69,15 +65,6 @@ public WebSocketService(ChannelGroup channels, LaunchServer server) {
|
||||||
this.gson = Launcher.gsonManager.gson;
|
this.gson = Launcher.gsonManager.gson;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forEachActiveChannels(BiConsumer<Channel, WebSocketFrameHandler> callback) {
|
|
||||||
for(Channel channel : channels) {
|
|
||||||
if (channel == null || channel.pipeline() == null) continue;
|
|
||||||
WebSocketFrameHandler wsHandler = channel.pipeline().get(WebSocketFrameHandler.class);
|
|
||||||
if (wsHandler == null) continue;
|
|
||||||
callback.accept(channel, wsHandler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void registerResponses() {
|
public static void registerResponses() {
|
||||||
providers.register("auth", AuthResponse.class);
|
providers.register("auth", AuthResponse.class);
|
||||||
providers.register("checkServer", CheckServerResponse.class);
|
providers.register("checkServer", CheckServerResponse.class);
|
||||||
|
@ -104,6 +91,15 @@ public static void registerResponses() {
|
||||||
providers.register("features", FeaturesResponse.class);
|
providers.register("features", FeaturesResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void forEachActiveChannels(BiConsumer<Channel, WebSocketFrameHandler> callback) {
|
||||||
|
for (Channel channel : channels) {
|
||||||
|
if (channel == null || channel.pipeline() == null) continue;
|
||||||
|
WebSocketFrameHandler wsHandler = channel.pipeline().get(WebSocketFrameHandler.class);
|
||||||
|
if (wsHandler == null) continue;
|
||||||
|
callback.accept(channel, wsHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) {
|
public void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) {
|
||||||
long startTimeNanos = System.nanoTime();
|
long startTimeNanos = System.nanoTime();
|
||||||
String request = frame.text();
|
String request = frame.text();
|
||||||
|
@ -217,29 +213,29 @@ public void sendObjectToUUID(UUID userUuid, Object obj, Type type) {
|
||||||
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
||||||
if (wsHandler == null) continue;
|
if (wsHandler == null) continue;
|
||||||
Client client = wsHandler.getClient();
|
Client client = wsHandler.getClient();
|
||||||
if(client == null || !userUuid.equals(client.uuid)) continue;
|
if (client == null || !userUuid.equals(client.uuid)) continue;
|
||||||
ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type)), ch.voidPromise());
|
ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type)), ch.voidPromise());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateDaoObject(UUID userUuid, User daoObject, Consumer<Channel> callback) {
|
public void updateDaoObject(UUID userUuid, User daoObject, Consumer<Channel> callback) {
|
||||||
for(Channel ch : channels) {
|
for (Channel ch : channels) {
|
||||||
if (ch == null || ch.pipeline() == null) continue;
|
if (ch == null || ch.pipeline() == null) continue;
|
||||||
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
||||||
if (wsHandler == null) continue;
|
if (wsHandler == null) continue;
|
||||||
Client client = wsHandler.getClient();
|
Client client = wsHandler.getClient();
|
||||||
if(client == null || client.daoObject == null || !userUuid.equals(client.uuid)) continue;
|
if (client == null || client.daoObject == null || !userUuid.equals(client.uuid)) continue;
|
||||||
client.daoObject = daoObject;
|
client.daoObject = daoObject;
|
||||||
if(callback != null) callback.accept(ch);
|
if (callback != null) callback.accept(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Channel getChannelFromConnectUUID(UUID connectUuid) {
|
public Channel getChannelFromConnectUUID(UUID connectUuid) {
|
||||||
for(Channel ch : channels) {
|
for (Channel ch : channels) {
|
||||||
if (ch == null || ch.pipeline() == null) continue;
|
if (ch == null || ch.pipeline() == null) continue;
|
||||||
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
||||||
if (wsHandler == null) continue;
|
if (wsHandler == null) continue;
|
||||||
if(connectUuid.equals(wsHandler.getConnectUUID())) {
|
if (connectUuid.equals(wsHandler.getConnectUUID())) {
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,27 +244,27 @@ public Channel getChannelFromConnectUUID(UUID connectUuid) {
|
||||||
|
|
||||||
public boolean kickByUserUUID(UUID userUuid, boolean isClose) {
|
public boolean kickByUserUUID(UUID userUuid, boolean isClose) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
for(Channel ch : channels) {
|
for (Channel ch : channels) {
|
||||||
if (ch == null || ch.pipeline() == null) continue;
|
if (ch == null || ch.pipeline() == null) continue;
|
||||||
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
||||||
if (wsHandler == null) continue;
|
if (wsHandler == null) continue;
|
||||||
Client client = wsHandler.getClient();
|
Client client = wsHandler.getClient();
|
||||||
if(client == null || client.daoObject == null || !userUuid.equals(client.uuid)) continue;
|
if (client == null || client.daoObject == null || !userUuid.equals(client.uuid)) continue;
|
||||||
ExitResponse.exit(server, wsHandler, ch, ExitRequestEvent.ExitReason.SERVER);
|
ExitResponse.exit(server, wsHandler, ch, ExitRequestEvent.ExitReason.SERVER);
|
||||||
if(isClose) ch.close();
|
if (isClose) ch.close();
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean kickByConnectUUID(UUID connectUuid, boolean isClose) {
|
public boolean kickByConnectUUID(UUID connectUuid, boolean isClose) {
|
||||||
for(Channel ch : channels) {
|
for (Channel ch : channels) {
|
||||||
if (ch == null || ch.pipeline() == null) continue;
|
if (ch == null || ch.pipeline() == null) continue;
|
||||||
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
||||||
if (wsHandler == null) continue;
|
if (wsHandler == null) continue;
|
||||||
if(connectUuid.equals(wsHandler.getConnectUUID())) {
|
if (connectUuid.equals(wsHandler.getConnectUUID())) {
|
||||||
ExitResponse.exit(server, wsHandler, ch, ExitRequestEvent.ExitReason.SERVER);
|
ExitResponse.exit(server, wsHandler, ch, ExitRequestEvent.ExitReason.SERVER);
|
||||||
if(isClose) ch.close();
|
if (isClose) ch.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,16 +273,16 @@ public boolean kickByConnectUUID(UUID connectUuid, boolean isClose) {
|
||||||
|
|
||||||
public boolean kickByIP(String ip, boolean isClose) {
|
public boolean kickByIP(String ip, boolean isClose) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
for(Channel ch : channels) {
|
for (Channel ch : channels) {
|
||||||
if (ch == null || ch.pipeline() == null) continue;
|
if (ch == null || ch.pipeline() == null) continue;
|
||||||
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class);
|
||||||
if(wsHandler == null) continue;
|
if (wsHandler == null) continue;
|
||||||
String clientIp;
|
String clientIp;
|
||||||
if(wsHandler.context != null && wsHandler.context.ip != null) clientIp = wsHandler.context.ip;
|
if (wsHandler.context != null && wsHandler.context.ip != null) clientIp = wsHandler.context.ip;
|
||||||
else clientIp = IOHelper.getIP(ch.remoteAddress());
|
else clientIp = IOHelper.getIP(ch.remoteAddress());
|
||||||
if(ip.equals(clientIp)) {
|
if (ip.equals(clientIp)) {
|
||||||
ExitResponse.exit(server, wsHandler, ch, ExitRequestEvent.ExitReason.SERVER);
|
ExitResponse.exit(server, wsHandler, ch, ExitRequestEvent.ExitReason.SERVER);
|
||||||
if(isClose) ch.close();
|
if (isClose) ch.close();
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
public class NettyWebAPIHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
|
public class NettyWebAPIHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
|
||||||
|
private static final TreeSet<SeverletPathPair> severletList = new TreeSet<>(Comparator.comparingInt((e) -> -e.key.length()));
|
||||||
private final NettyConnectContext context;
|
private final NettyConnectContext context;
|
||||||
|
|
||||||
public NettyWebAPIHandler(NettyConnectContext context) {
|
public NettyWebAPIHandler(NettyConnectContext context) {
|
||||||
|
@ -16,23 +17,6 @@ public NettyWebAPIHandler(NettyConnectContext context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface SimpleSeverletHandler {
|
|
||||||
void handle(ChannelHandlerContext ctx, FullHttpRequest msg, NettyConnectContext context) throws Exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SeverletPathPair {
|
|
||||||
public final String key;
|
|
||||||
public final SimpleSeverletHandler callback;
|
|
||||||
|
|
||||||
public SeverletPathPair(String key, SimpleSeverletHandler callback) {
|
|
||||||
this.key = key;
|
|
||||||
this.callback = callback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final TreeSet<SeverletPathPair> severletList = new TreeSet<>(Comparator.comparingInt((e) -> -e.key.length()));
|
|
||||||
|
|
||||||
public static SeverletPathPair addNewSeverlet(String path, SimpleSeverletHandler callback) {
|
public static SeverletPathPair addNewSeverlet(String path, SimpleSeverletHandler callback) {
|
||||||
SeverletPathPair pair = new SeverletPathPair("/webapi/".concat(path), callback);
|
SeverletPathPair pair = new SeverletPathPair("/webapi/".concat(path), callback);
|
||||||
severletList.add(pair);
|
severletList.add(pair);
|
||||||
|
@ -64,4 +48,19 @@ protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) thro
|
||||||
ctx.fireChannelRead(msg);
|
ctx.fireChannelRead(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface SimpleSeverletHandler {
|
||||||
|
void handle(ChannelHandlerContext ctx, FullHttpRequest msg, NettyConnectContext context) throws Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SeverletPathPair {
|
||||||
|
public final String key;
|
||||||
|
public final SimpleSeverletHandler callback;
|
||||||
|
|
||||||
|
public SeverletPathPair(String key, SimpleSeverletHandler callback) {
|
||||||
|
this.key = key;
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@ public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocket
|
||||||
|
|
||||||
public final LaunchServer srv;
|
public final LaunchServer srv;
|
||||||
public final WebSocketService service;
|
public final WebSocketService service;
|
||||||
|
public final BiHookSet<ChannelHandlerContext, WebSocketFrame> hooks = new BiHookSet<>();
|
||||||
private final UUID connectUUID = UUID.randomUUID();
|
private final UUID connectUUID = UUID.randomUUID();
|
||||||
public NettyConnectContext context;
|
public NettyConnectContext context;
|
||||||
public final BiHookSet<ChannelHandlerContext, WebSocketFrame> hooks = new BiHookSet<>();
|
|
||||||
private Client client;
|
private Client client;
|
||||||
private ScheduledFuture<?> future;
|
private ScheduledFuture<?> future;
|
||||||
|
|
||||||
|
@ -37,9 +37,9 @@ public Client getClient() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClient(Client client) {
|
public void setClient(Client client) {
|
||||||
if(this.client != null) this.client.refCount.decrementAndGet();
|
if (this.client != null) this.client.refCount.decrementAndGet();
|
||||||
this.client = client;
|
this.client = client;
|
||||||
if(client != null) client.refCount.incrementAndGet();
|
if (client != null) client.refCount.incrementAndGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final UUID getConnectUUID() {
|
public final UUID getConnectUUID() {
|
||||||
|
@ -98,15 +98,14 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {
|
||||||
@Override
|
@Override
|
||||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||||
if (future != null) future.cancel(true);
|
if (future != null) future.cancel(true);
|
||||||
if(LogHelper.isDevEnabled()) {
|
if (LogHelper.isDevEnabled()) {
|
||||||
LogHelper.dev("Client %s disconnected", IOHelper.getIP(ctx.channel().remoteAddress()));
|
LogHelper.dev("Client %s disconnected", IOHelper.getIP(ctx.channel().remoteAddress()));
|
||||||
}
|
}
|
||||||
int refCount = client.refCount.decrementAndGet();
|
int refCount = client.refCount.decrementAndGet();
|
||||||
if(client.session != null) {
|
if (client.session != null) {
|
||||||
if(refCount == 0) {
|
if (refCount == 0) {
|
||||||
srv.sessionManager.addClient(client);
|
srv.sessionManager.addClient(client);
|
||||||
}
|
} else if (refCount < 0) {
|
||||||
else if(refCount < 0) {
|
|
||||||
LogHelper.warning("Client session %s reference counter invalid - %d", client.session, refCount);
|
LogHelper.warning("Client session %s reference counter invalid - %d", client.session, refCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,7 +230,7 @@ public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) thr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (UnsupportedTemporalTypeException e) {
|
} catch (UnsupportedTemporalTypeException e) {
|
||||||
if(LogHelper.isDebugEnabled()) {
|
if (LogHelper.isDebugEnabled()) {
|
||||||
LogHelper.warning("Request access If-Modifed-Since: %s not parsed correctly", ifModifiedSince);
|
LogHelper.warning("Request access If-Modifed-Since: %s not parsed correctly", ifModifiedSince);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,16 +10,6 @@
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class CurrentUserResponse extends SimpleResponse {
|
public class CurrentUserResponse extends SimpleResponse {
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return "currentUser";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
|
||||||
sendResult(new CurrentUserRequestEvent(collectUserInfoFromClient(client)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(Client client) throws IOException {
|
public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(Client client) throws IOException {
|
||||||
CurrentUserRequestEvent.UserInfo result = new CurrentUserRequestEvent.UserInfo();
|
CurrentUserRequestEvent.UserInfo result = new CurrentUserRequestEvent.UserInfo();
|
||||||
if (client.auth != null && client.isAuth && client.username != null) {
|
if (client.auth != null && client.isAuth && client.username != null) {
|
||||||
|
@ -31,4 +21,14 @@ public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(Client
|
||||||
result.permissions = client.permissions;
|
result.permissions = client.permissions;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "currentUser";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
|
sendResult(new CurrentUserRequestEvent(collectUserInfoFromClient(client)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,18 @@ public class ExitResponse extends SimpleResponse {
|
||||||
public boolean exitAll;
|
public boolean exitAll;
|
||||||
public String username;
|
public String username;
|
||||||
|
|
||||||
|
public static void exit(LaunchServer server, WebSocketFrameHandler wsHandler, Channel channel, ExitRequestEvent.ExitReason reason) {
|
||||||
|
|
||||||
|
Client chClient = wsHandler.getClient();
|
||||||
|
Client newCusClient = new Client(null);
|
||||||
|
newCusClient.checkSign = chClient.checkSign;
|
||||||
|
wsHandler.setClient(newCusClient);
|
||||||
|
if (chClient.session != null) server.sessionManager.remove(chClient.session);
|
||||||
|
ExitRequestEvent event = new ExitRequestEvent(reason);
|
||||||
|
event.requestUUID = RequestEvent.eventUUID;
|
||||||
|
wsHandler.service.sendObject(channel, event);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "exit";
|
return "exit";
|
||||||
|
@ -61,16 +73,4 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
sendResult(new ExitRequestEvent(ExitRequestEvent.ExitReason.NO_EXIT));
|
sendResult(new ExitRequestEvent(ExitRequestEvent.ExitReason.NO_EXIT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void exit(LaunchServer server, WebSocketFrameHandler wsHandler, Channel channel, ExitRequestEvent.ExitReason reason) {
|
|
||||||
|
|
||||||
Client chClient = wsHandler.getClient();
|
|
||||||
Client newCusClient = new Client(null);
|
|
||||||
newCusClient.checkSign = chClient.checkSign;
|
|
||||||
wsHandler.setClient(newCusClient);
|
|
||||||
if (chClient.session != null) server.sessionManager.remove(chClient.session);
|
|
||||||
ExitRequestEvent event = new ExitRequestEvent(reason);
|
|
||||||
event.requestUUID = RequestEvent.eventUUID;
|
|
||||||
wsHandler.service.sendObject(channel, event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,18 +21,18 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
if(session == null) {
|
if (session == null) {
|
||||||
sendError("Session invalid");
|
sendError("Session invalid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Client[] rClient = {null};
|
final Client[] rClient = {null};
|
||||||
service.forEachActiveChannels((channel, handler) -> {
|
service.forEachActiveChannels((channel, handler) -> {
|
||||||
Client c = handler.getClient();
|
Client c = handler.getClient();
|
||||||
if(c != null && session.equals(c.session)) {
|
if (c != null && session.equals(c.session)) {
|
||||||
rClient[0] = c;
|
rClient[0] = c;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if(rClient[0] == null) {
|
if (rClient[0] == null) {
|
||||||
rClient[0] = server.sessionManager.getClient(session);
|
rClient[0] = server.sessionManager.getClient(session);
|
||||||
}
|
}
|
||||||
if (rClient[0] == null) {
|
if (rClient[0] == null) {
|
||||||
|
|
|
@ -25,45 +25,6 @@ public class ClientLauncherWrapper {
|
||||||
@LauncherInject("launcher.memory")
|
@LauncherInject("launcher.memory")
|
||||||
public static int launcherMemoryLimit;
|
public static int launcherMemoryLimit;
|
||||||
|
|
||||||
public static class JavaVersion {
|
|
||||||
public final Path jvmDir;
|
|
||||||
public final int version;
|
|
||||||
public boolean enabledJavaFX;
|
|
||||||
|
|
||||||
public JavaVersion(Path jvmDir, int version) {
|
|
||||||
this.jvmDir = jvmDir;
|
|
||||||
this.version = version;
|
|
||||||
this.enabledJavaFX = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JavaVersion getCurrentJavaVersion() {
|
|
||||||
return new JavaVersion(Paths.get(System.getProperty("java.home")), JVMHelper.getVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JavaVersion getByPath(Path jvmDir) throws IOException {
|
|
||||||
Path releaseFile = jvmDir.resolve("release");
|
|
||||||
if (!IOHelper.isFile(releaseFile)) return null;
|
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.load(IOHelper.newReader(releaseFile));
|
|
||||||
int javaVersion = getJavaVersion(properties.getProperty("JAVA_VERSION").replaceAll("\"", ""));
|
|
||||||
JavaVersion resultJavaVersion = new JavaVersion(jvmDir, javaVersion);
|
|
||||||
if (javaVersion <= 8) {
|
|
||||||
resultJavaVersion.enabledJavaFX = isExistExtJavaLibrary(jvmDir, "jfxrt");
|
|
||||||
} else {
|
|
||||||
resultJavaVersion.enabledJavaFX = tryFindModule(jvmDir, "javafx.base") != null;
|
|
||||||
if (!resultJavaVersion.enabledJavaFX)
|
|
||||||
resultJavaVersion.enabledJavaFX = tryFindModule(jvmDir.resolve("jre"), "javafx.base") != null;
|
|
||||||
}
|
|
||||||
return resultJavaVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isExistExtJavaLibrary(Path jvmDir, String name) {
|
|
||||||
Path jrePath = jvmDir.resolve("lib").resolve("ext").resolve(name.concat(".jar"));
|
|
||||||
Path jdkPath = jvmDir.resolve("jre").resolve("lib").resolve("ext").resolve(name.concat(".jar"));
|
|
||||||
return IOHelper.isFile(jrePath) || IOHelper.isFile(jdkPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] arguments) throws IOException, InterruptedException {
|
public static void main(String[] arguments) throws IOException, InterruptedException {
|
||||||
LogHelper.printVersion("Launcher");
|
LogHelper.printVersion("Launcher");
|
||||||
LogHelper.printLicense("Launcher");
|
LogHelper.printLicense("Launcher");
|
||||||
|
@ -136,7 +97,7 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
||||||
}
|
}
|
||||||
args.add(MAGIC_ARG);
|
args.add(MAGIC_ARG);
|
||||||
args.add("-XX:+DisableAttachMechanism");
|
args.add("-XX:+DisableAttachMechanism");
|
||||||
if(launcherMemoryLimit != 0) {
|
if (launcherMemoryLimit != 0) {
|
||||||
args.add(String.format("-Xmx%dM", launcherMemoryLimit));
|
args.add(String.format("-Xmx%dM", launcherMemoryLimit));
|
||||||
}
|
}
|
||||||
//Collections.addAll(args, "-javaagent:".concat(pathLauncher));
|
//Collections.addAll(args, "-javaagent:".concat(pathLauncher));
|
||||||
|
@ -246,4 +207,43 @@ public static int getJavaVersion(String version) {
|
||||||
}
|
}
|
||||||
return Integer.parseInt(version);
|
return Integer.parseInt(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class JavaVersion {
|
||||||
|
public final Path jvmDir;
|
||||||
|
public final int version;
|
||||||
|
public boolean enabledJavaFX;
|
||||||
|
|
||||||
|
public JavaVersion(Path jvmDir, int version) {
|
||||||
|
this.jvmDir = jvmDir;
|
||||||
|
this.version = version;
|
||||||
|
this.enabledJavaFX = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JavaVersion getCurrentJavaVersion() {
|
||||||
|
return new JavaVersion(Paths.get(System.getProperty("java.home")), JVMHelper.getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JavaVersion getByPath(Path jvmDir) throws IOException {
|
||||||
|
Path releaseFile = jvmDir.resolve("release");
|
||||||
|
if (!IOHelper.isFile(releaseFile)) return null;
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(IOHelper.newReader(releaseFile));
|
||||||
|
int javaVersion = getJavaVersion(properties.getProperty("JAVA_VERSION").replaceAll("\"", ""));
|
||||||
|
JavaVersion resultJavaVersion = new JavaVersion(jvmDir, javaVersion);
|
||||||
|
if (javaVersion <= 8) {
|
||||||
|
resultJavaVersion.enabledJavaFX = isExistExtJavaLibrary(jvmDir, "jfxrt");
|
||||||
|
} else {
|
||||||
|
resultJavaVersion.enabledJavaFX = tryFindModule(jvmDir, "javafx.base") != null;
|
||||||
|
if (!resultJavaVersion.enabledJavaFX)
|
||||||
|
resultJavaVersion.enabledJavaFX = tryFindModule(jvmDir.resolve("jre"), "javafx.base") != null;
|
||||||
|
}
|
||||||
|
return resultJavaVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isExistExtJavaLibrary(Path jvmDir, String name) {
|
||||||
|
Path jrePath = jvmDir.resolve("lib").resolve("ext").resolve(name.concat(".jar"));
|
||||||
|
Path jdkPath = jvmDir.resolve("jre").resolve("lib").resolve("ext").resolve(name.concat(".jar"));
|
||||||
|
return IOHelper.isFile(jrePath) || IOHelper.isFile(jdkPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.security.*;
|
import java.security.KeyPair;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.SecureRandom;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.interfaces.ECPrivateKey;
|
import java.security.interfaces.ECPrivateKey;
|
||||||
import java.security.interfaces.ECPublicKey;
|
import java.security.interfaces.ECPublicKey;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package pro.gravit.launcher.api;
|
package pro.gravit.launcher.api;
|
||||||
|
|
||||||
import pro.gravit.launcher.Launcher;
|
|
||||||
import pro.gravit.launcher.LauncherTrustManager;
|
import pro.gravit.launcher.LauncherTrustManager;
|
||||||
import pro.gravit.launcher.utils.ApiBridgeService;
|
import pro.gravit.launcher.utils.ApiBridgeService;
|
||||||
|
|
||||||
|
@ -45,6 +44,7 @@ public enum CheckClassResultTypeApi {
|
||||||
UNCOMPAT,
|
UNCOMPAT,
|
||||||
UNKNOWN
|
UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CheckClassResultApi {
|
public static class CheckClassResultApi {
|
||||||
public final CheckClassResultTypeApi type;
|
public final CheckClassResultTypeApi type;
|
||||||
public final X509Certificate endCertificate;
|
public final X509Certificate endCertificate;
|
||||||
|
@ -71,12 +71,14 @@ private CheckClassResultApi(CheckClassResultApi orig) {
|
||||||
this.rootCertificate = orig.rootCertificate;
|
this.rootCertificate = orig.rootCertificate;
|
||||||
this.endCertificate = orig.endCertificate;
|
this.endCertificate = orig.endCertificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CheckClassResultApi fromCheckClassResult(LauncherTrustManager.CheckClassResult result) {
|
private static CheckClassResultApi fromCheckClassResult(LauncherTrustManager.CheckClassResult result) {
|
||||||
if(result == null) return null;
|
if (result == null) return null;
|
||||||
return new CheckClassResultApi(fromType(result.type), result.endCertificate, result.rootCertificate, result.exception);
|
return new CheckClassResultApi(fromType(result.type), result.endCertificate, result.rootCertificate, result.exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CheckClassResultTypeApi fromType(LauncherTrustManager.CheckClassResultType type) {
|
private static CheckClassResultTypeApi fromType(LauncherTrustManager.CheckClassResultType type) {
|
||||||
if(type == null) return null;
|
if (type == null) return null;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NOT_SIGNED:
|
case NOT_SIGNED:
|
||||||
return CheckClassResultTypeApi.NOT_SIGNED;
|
return CheckClassResultTypeApi.NOT_SIGNED;
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
import java.nio.file.SimpleFileVisitor;
|
import java.nio.file.SimpleFileVisitor;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@ -82,7 +81,7 @@ public static void main(String[] args) throws Throwable {
|
||||||
LauncherGuardManager.initGuard(true);
|
LauncherGuardManager.initGuard(true);
|
||||||
LogHelper.debug("Reading ClientLauncher params");
|
LogHelper.debug("Reading ClientLauncher params");
|
||||||
ClientLauncherProcess.ClientParams params = readParams(new InetSocketAddress("127.0.0.1", Launcher.getConfig().clientPort));
|
ClientLauncherProcess.ClientParams params = readParams(new InetSocketAddress("127.0.0.1", Launcher.getConfig().clientPort));
|
||||||
if(params.profile.classLoaderConfig != ClientProfile.ClassLoaderConfig.AGENT) {
|
if (params.profile.classLoaderConfig != ClientProfile.ClassLoaderConfig.AGENT) {
|
||||||
LauncherEngine.verifyNoAgent();
|
LauncherEngine.verifyNoAgent();
|
||||||
}
|
}
|
||||||
ClientProfile profile = params.profile;
|
ClientProfile profile = params.profile;
|
||||||
|
@ -127,7 +126,7 @@ public static void main(String[] args) throws Throwable {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if(params.profile.classLoaderConfig == ClientProfile.ClassLoaderConfig.LAUNCHER) {
|
if (params.profile.classLoaderConfig == ClientProfile.ClassLoaderConfig.LAUNCHER) {
|
||||||
ClientClassLoader classLoader = new ClientClassLoader(classpath.toArray(new URL[0]), ClassLoader.getSystemClassLoader());
|
ClientClassLoader classLoader = new ClientClassLoader(classpath.toArray(new URL[0]), ClassLoader.getSystemClassLoader());
|
||||||
ClientLauncherEntryPoint.classLoader = classLoader;
|
ClientLauncherEntryPoint.classLoader = classLoader;
|
||||||
Thread.currentThread().setContextClassLoader(classLoader);
|
Thread.currentThread().setContextClassLoader(classLoader);
|
||||||
|
@ -139,11 +138,10 @@ public static void main(String[] args) throws Throwable {
|
||||||
ClientService.nativePath = classLoader.nativePath;
|
ClientService.nativePath = classLoader.nativePath;
|
||||||
classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL());
|
classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL());
|
||||||
ClientService.baseURLs = classLoader.getURLs();
|
ClientService.baseURLs = classLoader.getURLs();
|
||||||
}
|
} else if (params.profile.classLoaderConfig == ClientProfile.ClassLoaderConfig.AGENT) {
|
||||||
else if(params.profile.classLoaderConfig == ClientProfile.ClassLoaderConfig.AGENT) {
|
|
||||||
ClientLauncherEntryPoint.classLoader = ClassLoader.getSystemClassLoader();
|
ClientLauncherEntryPoint.classLoader = ClassLoader.getSystemClassLoader();
|
||||||
classpath.add(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL());
|
classpath.add(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL());
|
||||||
for(URL url : classpath) {
|
for (URL url : classpath) {
|
||||||
LauncherAgent.addJVMClassPath(Paths.get(url.toURI()));
|
LauncherAgent.addJVMClassPath(Paths.get(url.toURI()));
|
||||||
}
|
}
|
||||||
ClientService.instrumentation = LauncherAgent.inst;
|
ClientService.instrumentation = LauncherAgent.inst;
|
||||||
|
@ -198,15 +196,17 @@ public static void verifyHDir(Path dir, HashedDir hdir, FileNameMatcher matcher,
|
||||||
HashedDir currentHDir = new HashedDir(dir, matcher, true, digest);
|
HashedDir currentHDir = new HashedDir(dir, matcher, true, digest);
|
||||||
HashedDir.Diff diff = hdir.diff(currentHDir, matcher);
|
HashedDir.Diff diff = hdir.diff(currentHDir, matcher);
|
||||||
if (!diff.isSame()) {
|
if (!diff.isSame()) {
|
||||||
if(LogHelper.isDebugEnabled()) {
|
if (LogHelper.isDebugEnabled()) {
|
||||||
diff.extra.walk(File.separator, (e, k, v) -> {
|
diff.extra.walk(File.separator, (e, k, v) -> {
|
||||||
if(v.getType().equals(HashedEntry.Type.FILE)) { LogHelper.error("Extra file %s", e); }
|
if (v.getType().equals(HashedEntry.Type.FILE)) {
|
||||||
else LogHelper.error("Extra %s", e);
|
LogHelper.error("Extra file %s", e);
|
||||||
|
} else LogHelper.error("Extra %s", e);
|
||||||
return HashedDir.WalkAction.CONTINUE;
|
return HashedDir.WalkAction.CONTINUE;
|
||||||
});
|
});
|
||||||
diff.mismatch.walk(File.separator, (e,k,v) -> {
|
diff.mismatch.walk(File.separator, (e, k, v) -> {
|
||||||
if(v.getType().equals(HashedEntry.Type.FILE)) { LogHelper.error("Mismatch file %s", e); }
|
if (v.getType().equals(HashedEntry.Type.FILE)) {
|
||||||
else LogHelper.error("Mismatch %s", e);
|
LogHelper.error("Mismatch file %s", e);
|
||||||
|
} else LogHelper.error("Mismatch %s", e);
|
||||||
return HashedDir.WalkAction.CONTINUE;
|
return HashedDir.WalkAction.CONTINUE;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -263,9 +263,8 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa
|
||||||
System.setProperty("minecraft.applet.TargetDirectory", params.clientDir);
|
System.setProperty("minecraft.applet.TargetDirectory", params.clientDir);
|
||||||
}
|
}
|
||||||
Collections.addAll(args, profile.getClientArgs());
|
Collections.addAll(args, profile.getClientArgs());
|
||||||
for(OptionalAction action : params.actions) {
|
for (OptionalAction action : params.actions) {
|
||||||
if(action instanceof OptionalActionClientArgs)
|
if (action instanceof OptionalActionClientArgs) {
|
||||||
{
|
|
||||||
args.addAll(((OptionalActionClientArgs) action).args);
|
args.addAll(((OptionalActionClientArgs) action).args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,8 +278,8 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa
|
||||||
LogHelper.debug("Args: " + copy);
|
LogHelper.debug("Args: " + copy);
|
||||||
// Resolve main class and method
|
// Resolve main class and method
|
||||||
Class<?> mainClass = classLoader.loadClass(profile.getMainClass());
|
Class<?> mainClass = classLoader.loadClass(profile.getMainClass());
|
||||||
if(LogHelper.isDevEnabled() && classLoader instanceof URLClassLoader) {
|
if (LogHelper.isDevEnabled() && classLoader instanceof URLClassLoader) {
|
||||||
for (URL u : ((URLClassLoader)classLoader).getURLs()) {
|
for (URL u : ((URLClassLoader) classLoader).getURLs()) {
|
||||||
LogHelper.dev("ClassLoader URL: %s", u.toString());
|
LogHelper.dev("ClassLoader URL: %s", u.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,7 +287,7 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa
|
||||||
LauncherEngine.modulesManager.invokeEvent(new ClientProcessPreInvokeMainClassEvent(params, profile, args));
|
LauncherEngine.modulesManager.invokeEvent(new ClientProcessPreInvokeMainClassEvent(params, profile, args));
|
||||||
{
|
{
|
||||||
List<String> compatClasses = profile.getCompatClasses();
|
List<String> compatClasses = profile.getCompatClasses();
|
||||||
for(String e : compatClasses) {
|
for (String e : compatClasses) {
|
||||||
Class<?> clazz = classLoader.loadClass(e);
|
Class<?> clazz = classLoader.loadClass(e);
|
||||||
MethodHandle runMethod = MethodHandles.publicLookup().findStatic(clazz, "run", MethodType.methodType(void.class));
|
MethodHandle runMethod = MethodHandles.publicLookup().findStatic(clazz, "run", MethodType.methodType(void.class));
|
||||||
runMethod.invoke();
|
runMethod.invoke();
|
||||||
|
|
|
@ -117,7 +117,7 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
||||||
processArgs.add(executeFile.toString());
|
processArgs.add(executeFile.toString());
|
||||||
processArgs.addAll(jvmArgs);
|
processArgs.addAll(jvmArgs);
|
||||||
//ADD CLASSPATH
|
//ADD CLASSPATH
|
||||||
if(params.profile.classLoaderConfig == ClientProfile.ClassLoaderConfig.AGENT) {
|
if (params.profile.classLoaderConfig == ClientProfile.ClassLoaderConfig.AGENT) {
|
||||||
processArgs.add("-javaagent:".concat(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toAbsolutePath().toString()));
|
processArgs.add("-javaagent:".concat(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toAbsolutePath().toString()));
|
||||||
}
|
}
|
||||||
if (useLegacyJavaClassPathProperty) {
|
if (useLegacyJavaClassPathProperty) {
|
||||||
|
|
|
@ -6,26 +6,29 @@
|
||||||
|
|
||||||
public class DebugLauncherTrustManager extends LauncherTrustManager {
|
public class DebugLauncherTrustManager extends LauncherTrustManager {
|
||||||
private final TrustDebugMode mode;
|
private final TrustDebugMode mode;
|
||||||
|
|
||||||
public DebugLauncherTrustManager(X509Certificate[] trustSigners) {
|
public DebugLauncherTrustManager(X509Certificate[] trustSigners) {
|
||||||
super(trustSigners);
|
super(trustSigners);
|
||||||
this.mode = null;
|
this.mode = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DebugLauncherTrustManager() {
|
public DebugLauncherTrustManager() {
|
||||||
super(new X509Certificate[0]);
|
super(new X509Certificate[0]);
|
||||||
this.mode = null;
|
this.mode = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DebugLauncherTrustManager(TrustDebugMode mode) {
|
public DebugLauncherTrustManager(TrustDebugMode mode) {
|
||||||
super(new X509Certificate[0]);
|
super(new X509Certificate[0]);
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckClassResult checkCertificates(X509Certificate[] certs, CertificateChecker checker) {
|
||||||
|
if (mode == TrustDebugMode.TRUST_ALL) return new CheckClassResult(CheckClassResultType.SUCCESS, null, null);
|
||||||
|
return super.checkCertificates(certs, checker);
|
||||||
|
}
|
||||||
|
|
||||||
public enum TrustDebugMode {
|
public enum TrustDebugMode {
|
||||||
TRUST_ALL
|
TRUST_ALL
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CheckClassResult checkCertificates(X509Certificate[] certs, CertificateChecker checker) {
|
|
||||||
if(mode == TrustDebugMode.TRUST_ALL) return new CheckClassResult(CheckClassResultType.SUCCESS, null, null);
|
|
||||||
return super.checkCertificates(certs, checker);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ public class DebugMain {
|
||||||
public static String[] moduleClasses = System.getProperty("launcherdebug.modules", "").split(",");
|
public static String[] moduleClasses = System.getProperty("launcherdebug.modules", "").split(",");
|
||||||
public static String[] moduleFiles = System.getProperty("launcherdebug.modulefiles", "").split(",");
|
public static String[] moduleFiles = System.getProperty("launcherdebug.modulefiles", "").split(",");
|
||||||
public static LauncherConfig.LauncherEnvironment environment = LauncherConfig.LauncherEnvironment.valueOf(System.getProperty("launcherdebug.env", "STD"));
|
public static LauncherConfig.LauncherEnvironment environment = LauncherConfig.LauncherEnvironment.valueOf(System.getProperty("launcherdebug.env", "STD"));
|
||||||
|
|
||||||
public static void main(String[] args) throws Throwable {
|
public static void main(String[] args) throws Throwable {
|
||||||
LogHelper.printVersion("Launcher");
|
LogHelper.printVersion("Launcher");
|
||||||
LogHelper.printLicense("Launcher");
|
LogHelper.printLicense("Launcher");
|
||||||
|
@ -35,12 +36,12 @@ public static void main(String[] args) throws Throwable {
|
||||||
Launcher.applyLauncherEnv(environment);
|
Launcher.applyLauncherEnv(environment);
|
||||||
LauncherEngine.modulesManager = new ClientModuleManager();
|
LauncherEngine.modulesManager = new ClientModuleManager();
|
||||||
LauncherEngine.modulesManager.loadModule(new ClientLauncherCoreModule());
|
LauncherEngine.modulesManager.loadModule(new ClientLauncherCoreModule());
|
||||||
for(String moduleClassName : moduleClasses) {
|
for (String moduleClassName : moduleClasses) {
|
||||||
if(moduleClassName.isEmpty()) continue;
|
if (moduleClassName.isEmpty()) continue;
|
||||||
LauncherEngine.modulesManager.loadModule(newModule(moduleClassName));
|
LauncherEngine.modulesManager.loadModule(newModule(moduleClassName));
|
||||||
}
|
}
|
||||||
for(String moduleFileName : moduleFiles) {
|
for (String moduleFileName : moduleFiles) {
|
||||||
if(moduleFileName.isEmpty()) continue;
|
if (moduleFileName.isEmpty()) continue;
|
||||||
LauncherEngine.modulesManager.loadModule(Paths.get(moduleFileName));
|
LauncherEngine.modulesManager.loadModule(Paths.get(moduleFileName));
|
||||||
}
|
}
|
||||||
LauncherEngine.modulesManager.initModules(null);
|
LauncherEngine.modulesManager.initModules(null);
|
||||||
|
|
|
@ -10,6 +10,7 @@ public static LauncherTrustManager.CheckClassResult checkCertificates(X509Certif
|
||||||
LauncherTrustManager trustManager = Launcher.getConfig().trustManager;
|
LauncherTrustManager trustManager = Launcher.getConfig().trustManager;
|
||||||
return trustManager.checkCertificates(certs, trustManager::stdCertificateChecker);
|
return trustManager.checkCertificates(certs, trustManager::stdCertificateChecker);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkCertificatesSuccess(X509Certificate[] certs) throws Exception {
|
public static void checkCertificatesSuccess(X509Certificate[] certs) throws Exception {
|
||||||
LauncherTrustManager trustManager = Launcher.getConfig().trustManager;
|
LauncherTrustManager trustManager = Launcher.getConfig().trustManager;
|
||||||
trustManager.checkCertificatesSuccess(certs, trustManager::stdCertificateChecker);
|
trustManager.checkCertificatesSuccess(certs, trustManager::stdCertificateChecker);
|
||||||
|
|
|
@ -65,9 +65,9 @@ public GraphicsCard getGraphicCard() {
|
||||||
List<GraphicsCard> graphicsCards = hardware.getGraphicsCards();
|
List<GraphicsCard> graphicsCards = hardware.getGraphicsCards();
|
||||||
GraphicsCard result = null;
|
GraphicsCard result = null;
|
||||||
long size = 0;
|
long size = 0;
|
||||||
for(GraphicsCard card : graphicsCards) {
|
for (GraphicsCard card : graphicsCards) {
|
||||||
long vram = card.getVRam();
|
long vram = card.getVRam();
|
||||||
if(vram > size) {
|
if (vram > size) {
|
||||||
result = card;
|
result = card;
|
||||||
size = vram;
|
size = vram;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public GraphicsCard getGraphicCard() {
|
||||||
|
|
||||||
public String getGraphicCardName() {
|
public String getGraphicCardName() {
|
||||||
GraphicsCard card = getGraphicCard();
|
GraphicsCard card = getGraphicCard();
|
||||||
if(card == null) {
|
if (card == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return card.getName();
|
return card.getName();
|
||||||
|
@ -85,7 +85,7 @@ public String getGraphicCardName() {
|
||||||
|
|
||||||
public long getGraphicCardMemory() {
|
public long getGraphicCardMemory() {
|
||||||
GraphicsCard card = getGraphicCard();
|
GraphicsCard card = getGraphicCard();
|
||||||
if(card == null) {
|
if (card == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return card.getVRam();
|
return card.getVRam();
|
||||||
|
|
|
@ -5,12 +5,6 @@
|
||||||
import pro.gravit.launcher.profiles.PlayerProfile;
|
import pro.gravit.launcher.profiles.PlayerProfile;
|
||||||
|
|
||||||
public class CurrentUserRequestEvent extends RequestEvent {
|
public class CurrentUserRequestEvent extends RequestEvent {
|
||||||
public static class UserInfo {
|
|
||||||
public ClientPermissions permissions;
|
|
||||||
public String accessToken;
|
|
||||||
public PlayerProfile playerProfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final UserInfo userInfo;
|
public final UserInfo userInfo;
|
||||||
|
|
||||||
public CurrentUserRequestEvent(UserInfo userInfo) {
|
public CurrentUserRequestEvent(UserInfo userInfo) {
|
||||||
|
@ -21,4 +15,10 @@ public CurrentUserRequestEvent(UserInfo userInfo) {
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "currentUser";
|
return "currentUser";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class UserInfo {
|
||||||
|
public ClientPermissions permissions;
|
||||||
|
public String accessToken;
|
||||||
|
public PlayerProfile playerProfile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,17 @@ public final void setContext(LauncherModulesContext context) {
|
||||||
this.modulesConfigManager = context.getModulesConfigManager();
|
this.modulesConfigManager = context.getModulesConfigManager();
|
||||||
this.setInitStatus(InitStatus.PRE_INIT_WAIT);
|
this.setInitStatus(InitStatus.PRE_INIT_WAIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final LauncherTrustManager.CheckClassResultType getCheckStatus() {
|
||||||
|
if (this.checkResult == null) return null;
|
||||||
|
return this.checkResult.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final LauncherTrustManager.CheckClassResult getCheckResult() {
|
||||||
|
if (this.checkResult == null) return null;
|
||||||
|
return new LauncherTrustManager.CheckClassResult(this.checkResult);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The internal method used by the ModuleManager
|
* The internal method used by the ModuleManager
|
||||||
* DO NOT TOUCH
|
* DO NOT TOUCH
|
||||||
|
@ -56,20 +67,10 @@ public final void setContext(LauncherModulesContext context) {
|
||||||
* @param result Check result
|
* @param result Check result
|
||||||
*/
|
*/
|
||||||
public final void setCheckResult(LauncherTrustManager.CheckClassResult result) {
|
public final void setCheckResult(LauncherTrustManager.CheckClassResult result) {
|
||||||
if(this.checkResult != null) throw new IllegalStateException("Module already set check result");
|
if (this.checkResult != null) throw new IllegalStateException("Module already set check result");
|
||||||
this.checkResult = result;
|
this.checkResult = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final LauncherTrustManager.CheckClassResultType getCheckStatus() {
|
|
||||||
if(this.checkResult == null) return null;
|
|
||||||
return this.checkResult.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final LauncherTrustManager.CheckClassResult getCheckResult() {
|
|
||||||
if(this.checkResult == null) return null;
|
|
||||||
return new LauncherTrustManager.CheckClassResult(this.checkResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called before initializing all modules and resolving dependencies.
|
* This method is called before initializing all modules and resolving dependencies.
|
||||||
* <b>You can</b>:
|
* <b>You can</b>:
|
||||||
|
|
|
@ -17,11 +17,6 @@
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.SimpleFileVisitor;
|
import java.nio.file.SimpleFileVisitor;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.NoSuchProviderException;
|
|
||||||
import java.security.SignatureException;
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -122,7 +117,7 @@ private boolean checkDepend(LauncherModule module) {
|
||||||
@Override
|
@Override
|
||||||
public LauncherModule loadModule(LauncherModule module) {
|
public LauncherModule loadModule(LauncherModule module) {
|
||||||
if (modules.contains(module)) return module;
|
if (modules.contains(module)) return module;
|
||||||
if(module.getCheckStatus() == null) {
|
if (module.getCheckStatus() == null) {
|
||||||
LauncherTrustManager.CheckClassResult result = checkModuleClass(module.getClass());
|
LauncherTrustManager.CheckClassResult result = checkModuleClass(module.getClass());
|
||||||
verifyClassCheckResult(result);
|
verifyClassCheckResult(result);
|
||||||
module.setCheckResult(result);
|
module.setCheckResult(result);
|
||||||
|
@ -198,17 +193,17 @@ else if (mode == LauncherTrustManager.CheckMode.WARN_IN_NOT_SIGNED)
|
||||||
public LauncherTrustManager.CheckClassResult checkModuleClass(Class<? extends LauncherModule> clazz) {
|
public LauncherTrustManager.CheckClassResult checkModuleClass(Class<? extends LauncherModule> clazz) {
|
||||||
if (trustManager == null) return null;
|
if (trustManager == null) return null;
|
||||||
X509Certificate[] certificates = getCertificates(clazz);
|
X509Certificate[] certificates = getCertificates(clazz);
|
||||||
return trustManager.checkCertificates(certificates,trustManager::stdCertificateChecker);
|
return trustManager.checkCertificates(certificates, trustManager::stdCertificateChecker);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean verifyClassCheckResult(LauncherTrustManager.CheckClassResult result) {
|
public boolean verifyClassCheckResult(LauncherTrustManager.CheckClassResult result) {
|
||||||
if(result == null) return false;
|
if (result == null) return false;
|
||||||
return result.type == LauncherTrustManager.CheckClassResultType.SUCCESS;
|
return result.type == LauncherTrustManager.CheckClassResultType.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void verifyClassCheckResultExceptional(LauncherTrustManager.CheckClassResult result) throws Exception {
|
public void verifyClassCheckResultExceptional(LauncherTrustManager.CheckClassResult result) throws Exception {
|
||||||
if(verifyClassCheckResult(result)) return;
|
if (verifyClassCheckResult(result)) return;
|
||||||
if(result.exception != null) throw result.exception;
|
if (result.exception != null) throw result.exception;
|
||||||
throw new SecurityException(result.type.name());
|
throw new SecurityException(result.type.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,12 @@ public final class ClientProfile implements Comparable<ClientProfile> {
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private final List<String> clientArgs = new ArrayList<>();
|
private final List<String> clientArgs = new ArrayList<>();
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
|
private final List<String> compatClasses = new ArrayList<>();
|
||||||
|
@LauncherNetworkAPI
|
||||||
|
private final Map<String, String> properties = new HashMap<>();
|
||||||
|
@LauncherNetworkAPI
|
||||||
|
private final List<ServerProfile> servers = new ArrayList<>(1);
|
||||||
|
@LauncherNetworkAPI
|
||||||
public SecurityManagerConfig securityManagerConfig = SecurityManagerConfig.CLIENT;
|
public SecurityManagerConfig securityManagerConfig = SecurityManagerConfig.CLIENT;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
public ClassLoaderConfig classLoaderConfig = ClassLoaderConfig.LAUNCHER;
|
public ClassLoaderConfig classLoaderConfig = ClassLoaderConfig.LAUNCHER;
|
||||||
|
@ -81,24 +87,6 @@ public final class ClientProfile implements Comparable<ClientProfile> {
|
||||||
// Client launcher
|
// Client launcher
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private String mainClass;
|
private String mainClass;
|
||||||
@LauncherNetworkAPI
|
|
||||||
private final List<String> compatClasses = new ArrayList<>();
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
private final Map<String, String> properties = new HashMap<>();
|
|
||||||
|
|
||||||
public static class ServerProfile {
|
|
||||||
public String name;
|
|
||||||
public String serverAddress;
|
|
||||||
public int serverPort;
|
|
||||||
public boolean isDefault = true;
|
|
||||||
|
|
||||||
public InetSocketAddress toSocketAddress() {
|
|
||||||
return InetSocketAddress.createUnresolved(serverAddress, serverPort);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
private final List<ServerProfile> servers = new ArrayList<>(1);
|
|
||||||
|
|
||||||
public ServerProfile getDefaultServerProfile() {
|
public ServerProfile getDefaultServerProfile() {
|
||||||
for (ServerProfile profile : servers) {
|
for (ServerProfile profile : servers) {
|
||||||
|
@ -420,7 +408,7 @@ public void verify() {
|
||||||
for (String s : clientArgs) {
|
for (String s : clientArgs) {
|
||||||
if (s == null) throw new IllegalArgumentException("Found null entry in clientArgs");
|
if (s == null) throw new IllegalArgumentException("Found null entry in clientArgs");
|
||||||
}
|
}
|
||||||
for(String s : compatClasses) {
|
for (String s : compatClasses) {
|
||||||
if (s == null) throw new IllegalArgumentException("Found null entry in compatClasses");
|
if (s == null) throw new IllegalArgumentException("Found null entry in compatClasses");
|
||||||
}
|
}
|
||||||
for (OptionalFile f : updateOptional) {
|
for (OptionalFile f : updateOptional) {
|
||||||
|
@ -546,5 +534,16 @@ public interface pushOptionalClassPathCallback {
|
||||||
void run(String[] opt) throws IOException;
|
void run(String[] opt) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ServerProfile {
|
||||||
|
public String name;
|
||||||
|
public String serverAddress;
|
||||||
|
public int serverPort;
|
||||||
|
public boolean isDefault = true;
|
||||||
|
|
||||||
|
public InetSocketAddress toSocketAddress() {
|
||||||
|
return InetSocketAddress.createUnresolved(serverAddress, serverPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,19 @@ public class OptionalView {
|
||||||
public Map<OptionalFile, Set<OptionalFile>> dependenciesCountMap = new HashMap<>();
|
public Map<OptionalFile, Set<OptionalFile>> dependenciesCountMap = new HashMap<>();
|
||||||
public Set<OptionalFile> all;
|
public Set<OptionalFile> all;
|
||||||
|
|
||||||
|
public OptionalView(ClientProfile profile) {
|
||||||
|
this.all = profile.getOptional();
|
||||||
|
for (OptionalFile f : this.all) {
|
||||||
|
if (f.mark) enable(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public OptionalView(OptionalView view) {
|
||||||
|
this.enabled = new HashSet<>(view.enabled);
|
||||||
|
this.dependenciesCountMap = new HashMap<>(view.dependenciesCountMap);
|
||||||
|
this.all = view.all;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends OptionalAction> Set<T> getActionsByClass(Class<T> clazz) {
|
public <T extends OptionalAction> Set<T> getActionsByClass(Class<T> clazz) {
|
||||||
Set<T> results = new HashSet<>();
|
Set<T> results = new HashSet<>();
|
||||||
|
@ -91,17 +104,4 @@ public void disable(OptionalFile file) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public OptionalView(ClientProfile profile) {
|
|
||||||
this.all = profile.getOptional();
|
|
||||||
for (OptionalFile f : this.all) {
|
|
||||||
if (f.mark) enable(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public OptionalView(OptionalView view) {
|
|
||||||
this.enabled = new HashSet<>(view.enabled);
|
|
||||||
this.dependenciesCountMap = new HashMap<>(view.dependenciesCountMap);
|
|
||||||
this.all = view.all;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,13 @@
|
||||||
public class OptionalActionFile extends OptionalAction {
|
public class OptionalActionFile extends OptionalAction {
|
||||||
public Map<String, String> files;
|
public Map<String, String> files;
|
||||||
|
|
||||||
|
public OptionalActionFile() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public OptionalActionFile(Map<String, String> files) {
|
||||||
|
this.files = files;
|
||||||
|
}
|
||||||
|
|
||||||
public void injectToHashedDir(HashedDir dir) {
|
public void injectToHashedDir(HashedDir dir) {
|
||||||
if (files == null) return;
|
if (files == null) return;
|
||||||
files.forEach((k, v) -> {
|
files.forEach((k, v) -> {
|
||||||
|
@ -28,11 +35,4 @@ public void disableInHashedDir(HashedDir dir) {
|
||||||
firstPath.parent.remove(firstPath.name);
|
firstPath.parent.remove(firstPath.name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public OptionalActionFile() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public OptionalActionFile(Map<String, String> files) {
|
|
||||||
this.files = files;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,14 @@
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PingServerReportRequest extends Request<PingServerReportRequestEvent> {
|
public class PingServerReportRequest extends Request<PingServerReportRequestEvent> {
|
||||||
|
public final String name;
|
||||||
|
public final PingServerReport data;
|
||||||
|
|
||||||
|
public PingServerReportRequest(String name, PingServerReport data) {
|
||||||
|
this.name = name;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "pingServerReport";
|
return "pingServerReport";
|
||||||
|
@ -15,6 +23,14 @@ public static class PingServerReport {
|
||||||
public final String name;
|
public final String name;
|
||||||
public final int maxPlayers; // player slots
|
public final int maxPlayers; // player slots
|
||||||
public final int playersOnline;
|
public final int playersOnline;
|
||||||
|
//Server addional info
|
||||||
|
public double tps; //Server tps
|
||||||
|
public List<UsernameInfo> users;
|
||||||
|
public PingServerReport(String name, int maxPlayers, int playersOnline) {
|
||||||
|
this.name = name;
|
||||||
|
this.maxPlayers = maxPlayers;
|
||||||
|
this.playersOnline = playersOnline;
|
||||||
|
}
|
||||||
|
|
||||||
public static class UsernameInfo {
|
public static class UsernameInfo {
|
||||||
public final String username;
|
public final String username;
|
||||||
|
@ -23,23 +39,5 @@ public UsernameInfo(String username) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Server addional info
|
|
||||||
public double tps; //Server tps
|
|
||||||
public List<UsernameInfo> users;
|
|
||||||
|
|
||||||
public PingServerReport(String name, int maxPlayers, int playersOnline) {
|
|
||||||
this.name = name;
|
|
||||||
this.maxPlayers = maxPlayers;
|
|
||||||
this.playersOnline = playersOnline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final String name;
|
|
||||||
public final PingServerReport data;
|
|
||||||
|
|
||||||
public PingServerReportRequest(String name, PingServerReport data) {
|
|
||||||
this.name = name;
|
|
||||||
this.data = data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
import io.netty.handler.ssl.SslContextBuilder;
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
import pro.gravit.launcher.CertificatePinningTrustManager;
|
import pro.gravit.launcher.CertificatePinningTrustManager;
|
||||||
import pro.gravit.launcher.LauncherInject;
|
import pro.gravit.launcher.LauncherInject;
|
||||||
import pro.gravit.launcher.LauncherNetworkAPI;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
|
@ -25,11 +24,12 @@
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
|
|
||||||
public abstract class ClientJSONPoint {
|
public abstract class ClientJSONPoint {
|
||||||
|
|
||||||
private static final EventLoopGroup group = new NioEventLoopGroup();
|
private static final EventLoopGroup group = new NioEventLoopGroup();
|
||||||
|
@LauncherInject("launcher.certificatePinning")
|
||||||
|
private static boolean isCertificatePinning;
|
||||||
protected final Bootstrap bootstrap = new Bootstrap();
|
protected final Bootstrap bootstrap = new Bootstrap();
|
||||||
private final URI uri;
|
private final URI uri;
|
||||||
public boolean isClosed;
|
public boolean isClosed;
|
||||||
|
@ -37,8 +37,6 @@ public abstract class ClientJSONPoint {
|
||||||
protected WebSocketClientHandler webSocketClientHandler;
|
protected WebSocketClientHandler webSocketClientHandler;
|
||||||
protected boolean ssl = false;
|
protected boolean ssl = false;
|
||||||
protected int port;
|
protected int port;
|
||||||
@LauncherInject("launcher.certificatePinning")
|
|
||||||
private static boolean isCertificatePinning;
|
|
||||||
|
|
||||||
public ClientJSONPoint(final String uri) throws SSLException {
|
public ClientJSONPoint(final String uri) throws SSLException {
|
||||||
this(URI.create(uri));
|
this(URI.create(uri));
|
||||||
|
@ -60,7 +58,7 @@ public ClientJSONPoint(URI uri) throws SSLException {
|
||||||
final SslContext sslCtx;
|
final SslContext sslCtx;
|
||||||
if (ssl) {
|
if (ssl) {
|
||||||
SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
|
SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
|
||||||
if(isCertificatePinning) {
|
if (isCertificatePinning) {
|
||||||
try {
|
try {
|
||||||
sslContextBuilder.trustManager(CertificatePinningTrustManager.getTrustManager());
|
sslContextBuilder.trustManager(CertificatePinningTrustManager.getTrustManager());
|
||||||
} catch (KeyStoreException | NoSuchAlgorithmException | IOException | CertificateException e) {
|
} catch (KeyStoreException | NoSuchAlgorithmException | IOException | CertificateException e) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package pro.gravit.launcher;
|
package pro.gravit.launcher;
|
||||||
|
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
@ -28,10 +27,10 @@
|
||||||
public class AsyncDownloader {
|
public class AsyncDownloader {
|
||||||
public static final Callback IGNORE = (ignored) -> {
|
public static final Callback IGNORE = (ignored) -> {
|
||||||
};
|
};
|
||||||
public final Callback callback;
|
|
||||||
@LauncherInject("launcher.certificatePinning")
|
@LauncherInject("launcher.certificatePinning")
|
||||||
private static boolean isCertificatePinning;
|
private static boolean isCertificatePinning;
|
||||||
private static volatile SSLSocketFactory sslSocketFactory;
|
private static volatile SSLSocketFactory sslSocketFactory;
|
||||||
|
public final Callback callback;
|
||||||
|
|
||||||
public AsyncDownloader(Callback callback) {
|
public AsyncDownloader(Callback callback) {
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
@ -43,7 +42,7 @@ public AsyncDownloader() {
|
||||||
|
|
||||||
public void downloadFile(URL url, Path target, long size) throws IOException {
|
public void downloadFile(URL url, Path target, long size) throws IOException {
|
||||||
URLConnection connection = url.openConnection();
|
URLConnection connection = url.openConnection();
|
||||||
if(isCertificatePinning) {
|
if (isCertificatePinning) {
|
||||||
HttpsURLConnection connection1 = (HttpsURLConnection) connection;
|
HttpsURLConnection connection1 = (HttpsURLConnection) connection;
|
||||||
try {
|
try {
|
||||||
connection1.setSSLSocketFactory(makeSSLSocketFactory());
|
connection1.setSSLSocketFactory(makeSSLSocketFactory());
|
||||||
|
@ -58,7 +57,7 @@ public void downloadFile(URL url, Path target, long size) throws IOException {
|
||||||
|
|
||||||
public void downloadFile(URL url, Path target) throws IOException {
|
public void downloadFile(URL url, Path target) throws IOException {
|
||||||
URLConnection connection = url.openConnection();
|
URLConnection connection = url.openConnection();
|
||||||
if(isCertificatePinning) {
|
if (isCertificatePinning) {
|
||||||
HttpsURLConnection connection1 = (HttpsURLConnection) connection;
|
HttpsURLConnection connection1 = (HttpsURLConnection) connection;
|
||||||
try {
|
try {
|
||||||
connection1.setSSLSocketFactory(makeSSLSocketFactory());
|
connection1.setSSLSocketFactory(makeSSLSocketFactory());
|
||||||
|
@ -72,7 +71,7 @@ public void downloadFile(URL url, Path target) throws IOException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SSLSocketFactory makeSSLSocketFactory() throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, KeyManagementException {
|
public SSLSocketFactory makeSSLSocketFactory() throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, KeyManagementException {
|
||||||
if(sslSocketFactory != null) return sslSocketFactory;
|
if (sslSocketFactory != null) return sslSocketFactory;
|
||||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
sslContext.init(null, CertificatePinningTrustManager.getTrustManager().getTrustManagers(), new SecureRandom());
|
sslContext.init(null, CertificatePinningTrustManager.getTrustManager().getTrustManagers(), new SecureRandom());
|
||||||
sslSocketFactory = sslContext.getSocketFactory();
|
sslSocketFactory = sslContext.getSocketFactory();
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
import javax.net.ssl.TrustManager;
|
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
import javax.net.ssl.X509TrustManager;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -22,6 +20,7 @@ public final class CertificatePinningTrustManager {
|
||||||
private static List<byte[]> secureConfigCertificates;
|
private static List<byte[]> secureConfigCertificates;
|
||||||
private static X509Certificate[] certs = null;
|
private static X509Certificate[] certs = null;
|
||||||
private volatile static TrustManagerFactory INSTANCE;
|
private volatile static TrustManagerFactory INSTANCE;
|
||||||
|
|
||||||
private static X509Certificate[] getInternalCertificates() {
|
private static X509Certificate[] getInternalCertificates() {
|
||||||
CertificateFactory certFactory = null;
|
CertificateFactory certFactory = null;
|
||||||
try {
|
try {
|
||||||
|
@ -41,19 +40,19 @@ private static X509Certificate[] getInternalCertificates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static X509Certificate[] getCertificates() {
|
public static X509Certificate[] getCertificates() {
|
||||||
if(certs == null) certs = getInternalCertificates();
|
if (certs == null) certs = getInternalCertificates();
|
||||||
return Arrays.copyOf(certs, certs.length);
|
return Arrays.copyOf(certs, certs.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TrustManagerFactory getTrustManager() throws KeyStoreException, NoSuchAlgorithmException, IOException, CertificateException {
|
public static TrustManagerFactory getTrustManager() throws KeyStoreException, NoSuchAlgorithmException, IOException, CertificateException {
|
||||||
if(INSTANCE != null) return INSTANCE;
|
if (INSTANCE != null) return INSTANCE;
|
||||||
if(certs == null) certs = getInternalCertificates();
|
if (certs == null) certs = getInternalCertificates();
|
||||||
TrustManagerFactory factory = TrustManagerFactory.getInstance("X.509");
|
TrustManagerFactory factory = TrustManagerFactory.getInstance("X.509");
|
||||||
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
|
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||||
keystore.load(null, null);
|
keystore.load(null, null);
|
||||||
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (X509Certificate cert: certs) {
|
for (X509Certificate cert : certs) {
|
||||||
String alias = Integer.toString(i);
|
String alias = Integer.toString(i);
|
||||||
keystore.setCertificateEntry(alias, cert);
|
keystore.setCertificateEntry(alias, cert);
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package pro.gravit.launcher;
|
package pro.gravit.launcher;
|
||||||
|
|
||||||
import pro.gravit.utils.helper.JVMHelper;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
@ -20,43 +19,25 @@ public class LauncherTrustManager {
|
||||||
private final X509Certificate[] trustSigners;
|
private final X509Certificate[] trustSigners;
|
||||||
private final List<X509Certificate> trustCache = new ArrayList<>();
|
private final List<X509Certificate> trustCache = new ArrayList<>();
|
||||||
|
|
||||||
public enum CheckClassResultType {
|
public LauncherTrustManager(X509Certificate[] trustSigners) {
|
||||||
NOT_SIGNED,
|
this.trustSigners = trustSigners;
|
||||||
SUCCESS,
|
|
||||||
UNTRUSTED,
|
|
||||||
UNVERIFED,
|
|
||||||
UNCOMPAT
|
|
||||||
}
|
}
|
||||||
public static class CheckClassResult {
|
|
||||||
public final CheckClassResultType type;
|
|
||||||
public final X509Certificate endCertificate;
|
|
||||||
public final X509Certificate rootCertificate;
|
|
||||||
public final Exception exception;
|
|
||||||
|
|
||||||
public CheckClassResult(CheckClassResultType type, X509Certificate endCertificate, X509Certificate rootCertificate) {
|
public LauncherTrustManager(List<byte[]> encodedCertificate) throws CertificateException {
|
||||||
this.type = type;
|
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
||||||
this.endCertificate = endCertificate;
|
trustSigners = encodedCertificate.stream().map((cert) -> {
|
||||||
this.rootCertificate = rootCertificate;
|
try (InputStream input = new ByteArrayInputStream(cert)) {
|
||||||
exception = null;
|
return (X509Certificate) certFactory.generateCertificate(input);
|
||||||
}
|
} catch (IOException | CertificateException e) {
|
||||||
|
LogHelper.error(e);
|
||||||
public CheckClassResult(CheckClassResultType type, X509Certificate endCertificate, X509Certificate rootCertificate, Exception exception) {
|
return null;
|
||||||
this.type = type;
|
}
|
||||||
this.endCertificate = endCertificate;
|
}).toArray(X509Certificate[]::new);
|
||||||
this.rootCertificate = rootCertificate;
|
|
||||||
this.exception = exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CheckClassResult(CheckClassResult orig) {
|
|
||||||
this.type = orig.type;
|
|
||||||
this.exception = orig.exception;
|
|
||||||
this.rootCertificate = orig.rootCertificate;
|
|
||||||
this.endCertificate = orig.endCertificate;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public CheckClassResult checkCertificates( X509Certificate[] certs, CertificateChecker checker) {
|
|
||||||
if(certs == null) return new CheckClassResult(CheckClassResultType.NOT_SIGNED, null, null);
|
public CheckClassResult checkCertificates(X509Certificate[] certs, CertificateChecker checker) {
|
||||||
X509Certificate rootCert = certs[certs.length-1];
|
if (certs == null) return new CheckClassResult(CheckClassResultType.NOT_SIGNED, null, null);
|
||||||
|
X509Certificate rootCert = certs[certs.length - 1];
|
||||||
X509Certificate endCert = certs[0];
|
X509Certificate endCert = certs[0];
|
||||||
for (int i = 0; i < certs.length; ++i) {
|
for (int i = 0; i < certs.length; ++i) {
|
||||||
X509Certificate cert = certs[i];
|
X509Certificate cert = certs[i];
|
||||||
|
@ -80,7 +61,7 @@ public CheckClassResult checkCertificates( X509Certificate[] certs, CertificateC
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
if(isTrusted(cert)) {
|
if (isTrusted(cert)) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
return new CheckClassResult(CheckClassResultType.UNTRUSTED, endCert, rootCert);
|
return new CheckClassResult(CheckClassResultType.UNTRUSTED, endCert, rootCert);
|
||||||
|
@ -99,29 +80,13 @@ public CheckClassResult checkCertificates( X509Certificate[] certs, CertificateC
|
||||||
return new CheckClassResult(CheckClassResultType.SUCCESS, endCert, rootCert);
|
return new CheckClassResult(CheckClassResultType.SUCCESS, endCert, rootCert);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkCertificatesSuccess( X509Certificate[] certs, CertificateChecker checker) throws Exception {
|
public void checkCertificatesSuccess(X509Certificate[] certs, CertificateChecker checker) throws Exception {
|
||||||
CheckClassResult result = checkCertificates(certs, checker);
|
CheckClassResult result = checkCertificates(certs, checker);
|
||||||
if(result.type == CheckClassResultType.SUCCESS) return;
|
if (result.type == CheckClassResultType.SUCCESS) return;
|
||||||
if(result.exception != null) throw result.exception;
|
if (result.exception != null) throw result.exception;
|
||||||
throw new SecurityException(result.type.name());
|
throw new SecurityException(result.type.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
public LauncherTrustManager(X509Certificate[] trustSigners) {
|
|
||||||
this.trustSigners = trustSigners;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LauncherTrustManager(List<byte[]> encodedCertificate) throws CertificateException {
|
|
||||||
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
|
||||||
trustSigners = encodedCertificate.stream().map((cert) -> {
|
|
||||||
try (InputStream input = new ByteArrayInputStream(cert)) {
|
|
||||||
return (X509Certificate) certFactory.generateCertificate(input);
|
|
||||||
} catch (IOException | CertificateException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).toArray(X509Certificate[]::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void checkCertificate(X509Certificate[] certs, CertificateChecker checker) throws CertificateException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
|
public void checkCertificate(X509Certificate[] certs, CertificateChecker checker) throws CertificateException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
|
||||||
if (certs == null) throw new SecurityException("Object not signed");
|
if (certs == null) throw new SecurityException("Object not signed");
|
||||||
|
@ -193,6 +158,15 @@ public void stdCertificateChecker(X509Certificate cert, X509Certificate signer,
|
||||||
else
|
else
|
||||||
isCertificateCA(cert);
|
isCertificateCA(cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum CheckClassResultType {
|
||||||
|
NOT_SIGNED,
|
||||||
|
SUCCESS,
|
||||||
|
UNTRUSTED,
|
||||||
|
UNVERIFED,
|
||||||
|
UNCOMPAT
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public enum CheckMode {
|
public enum CheckMode {
|
||||||
EXCEPTION_IN_NOT_SIGNED, WARN_IN_NOT_SIGNED, NONE_IN_NOT_SIGNED
|
EXCEPTION_IN_NOT_SIGNED, WARN_IN_NOT_SIGNED, NONE_IN_NOT_SIGNED
|
||||||
|
@ -201,4 +175,32 @@ public enum CheckMode {
|
||||||
public interface CertificateChecker {
|
public interface CertificateChecker {
|
||||||
void check(X509Certificate cert, X509Certificate signer, int number) throws SecurityException;
|
void check(X509Certificate cert, X509Certificate signer, int number) throws SecurityException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class CheckClassResult {
|
||||||
|
public final CheckClassResultType type;
|
||||||
|
public final X509Certificate endCertificate;
|
||||||
|
public final X509Certificate rootCertificate;
|
||||||
|
public final Exception exception;
|
||||||
|
|
||||||
|
public CheckClassResult(CheckClassResultType type, X509Certificate endCertificate, X509Certificate rootCertificate) {
|
||||||
|
this.type = type;
|
||||||
|
this.endCertificate = endCertificate;
|
||||||
|
this.rootCertificate = rootCertificate;
|
||||||
|
exception = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CheckClassResult(CheckClassResultType type, X509Certificate endCertificate, X509Certificate rootCertificate, Exception exception) {
|
||||||
|
this.type = type;
|
||||||
|
this.endCertificate = endCertificate;
|
||||||
|
this.rootCertificate = rootCertificate;
|
||||||
|
this.exception = exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CheckClassResult(CheckClassResult orig) {
|
||||||
|
this.type = orig.type;
|
||||||
|
this.exception = orig.exception;
|
||||||
|
this.rootCertificate = orig.rootCertificate;
|
||||||
|
this.endCertificate = orig.endCertificate;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,18 +106,6 @@ public void moveTo(String elementName, HashedDir target, String targetElementNam
|
||||||
target.map.put(targetElementName, entry);
|
target.map.put(targetElementName, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FindRecursiveResult {
|
|
||||||
public final HashedDir parent;
|
|
||||||
public final HashedEntry entry;
|
|
||||||
public final String name;
|
|
||||||
|
|
||||||
public FindRecursiveResult(HashedDir parent, HashedEntry entry, String name) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.entry = entry;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public FindRecursiveResult findRecursive(String path) {
|
public FindRecursiveResult findRecursive(String path) {
|
||||||
StringTokenizer t = new StringTokenizer(path, "/");
|
StringTokenizer t = new StringTokenizer(path, "/");
|
||||||
HashedDir current = this;
|
HashedDir current = this;
|
||||||
|
@ -334,6 +322,18 @@ public interface WalkCallback {
|
||||||
WalkAction walked(String path, String name, HashedEntry entry) throws IOException;
|
WalkAction walked(String path, String name, HashedEntry entry) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class FindRecursiveResult {
|
||||||
|
public final HashedDir parent;
|
||||||
|
public final HashedEntry entry;
|
||||||
|
public final String name;
|
||||||
|
|
||||||
|
public FindRecursiveResult(HashedDir parent, HashedEntry entry, String name) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.entry = entry;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final class Diff {
|
public static final class Diff {
|
||||||
|
|
||||||
public final HashedDir mismatch;
|
public final HashedDir mismatch;
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
# Modification of the launcher sashok724's v3 from Gravit [![Build Status](https://travis-ci.com/GravitLauncher/Launcher.svg?branch=master)](https://travis-ci.com/GravitLauncher/Launcher)
|
# Modification of the launcher sashok724's v3 from Gravit [![Build Status](https://travis-ci.com/GravitLauncher/Launcher.svg?branch=master)](https://travis-ci.com/GravitLauncher/Launcher)
|
||||||
|
|
||||||
* [Discord channel](https://discord.gg/CBmkyqh)
|
* [Discord channel](https://discord.gg/CBmkyqh)
|
||||||
* [See license](LICENSE)
|
* [See license](LICENSE)
|
||||||
* [See code of conduct](CODE_OF_CONDUCT.md)
|
* [See code of conduct](CODE_OF_CONDUCT.md)
|
||||||
* [WIKI](https://launcher.gravit.pro)
|
* [WIKI](https://launcher.gravit.pro)
|
||||||
* Get it (requires cURL):
|
* Get it (requires cURL):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -s https://raw.githubusercontent.com/GravitLauncher/Launcher/master/get_it.sh | sh
|
curl -s https://raw.githubusercontent.com/GravitLauncher/Launcher/master/get_it.sh | sh
|
||||||
```
|
```
|
||||||
|
|
|
@ -48,7 +48,7 @@ public void run() throws IOException {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogHelper.info("Found MainClass %s", mainClassName);
|
LogHelper.info("Found MainClass %s", mainClassName);
|
||||||
if(agentClassName != null) {
|
if (agentClassName != null) {
|
||||||
LogHelper.info("Found PremainClass %s", agentClassName);
|
LogHelper.info("Found PremainClass %s", agentClassName);
|
||||||
}
|
}
|
||||||
System.out.println("Print your server name:");
|
System.out.println("Print your server name:");
|
||||||
|
@ -96,7 +96,7 @@ public void run() throws IOException {
|
||||||
writer.append(JVMHelper.jvmProperty("serverwrapper.modulesDir", "modules_srv"));
|
writer.append(JVMHelper.jvmProperty("serverwrapper.modulesDir", "modules_srv"));
|
||||||
writer.append(" ");
|
writer.append(" ");
|
||||||
}
|
}
|
||||||
if(agentClassName != null) {
|
if (agentClassName != null) {
|
||||||
writer.append("-javaagent:ServerWrapper.jar ");
|
writer.append("-javaagent:ServerWrapper.jar ");
|
||||||
writer.append("-Dserverwrapper.agentproxy=".concat(agentClassName));
|
writer.append("-Dserverwrapper.agentproxy=".concat(agentClassName));
|
||||||
writer.append(" ");
|
writer.append(" ");
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#Контроллер авторизации методом json
|
# Контроллер авторизации методом json
|
||||||
|
|
||||||
Route:
|
Route:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
Route::put('launcher/auth', 'LauncherAuthController@json');
|
Route::put('launcher/auth', 'LauncherAuthController@json');
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
com.mojang.authlib-clean.jar
|
com.mojang.authlib-clean.jar
|
||||||
-----------------
|
-----------------
|
||||||
Этот JAR - заготовка для сборки LauncherAuthlib.
|
Этот JAR - заготовка для сборки LauncherAuthlib. Из неё удалены не используемые клиентом классы, а так же классы,
|
||||||
Из неё удалены не используемые клиентом классы, а так же классы, реализованные в LauncherAuthlib.
|
реализованные в LauncherAuthlib.
|
||||||
|
|
||||||
GameProfile-combined.class
|
GameProfile-combined.class
|
||||||
--------------------------
|
--------------------------
|
||||||
Этот класс - результат слияния ASM'ом методов из Authlib 1.7.2 и Authlib 1.7.10+, в нём есть метод как для получения
|
Этот класс - результат слияния ASM'ом методов из Authlib 1.7.2 и Authlib 1.7.10+, в нём есть метод как для получения
|
||||||
UUID старого образца (без чёрточек, например `d3730e7436794ba6-8ab2a24ac9e755d4`),
|
UUID старого образца (без чёрточек, например `d3730e7436794ba6-8ab2a24ac9e755d4`), так и нового
|
||||||
так и нового образца (`d3730e74-3679-4ba6-8ab2-a24ac9e755d4`). Уже включён в `com.mojang.authlib-clean.jar`
|
образца (`d3730e74-3679-4ba6-8ab2-a24ac9e755d4`). Уже включён в `com.mojang.authlib-clean.jar`
|
||||||
|
|
||||||
MinecraftSessionService-combined.class
|
MinecraftSessionService-combined.class
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
Этот класс - результат слияния ASM'ом методов из Authlib 1.10.2 и Authlib 1.11+, в нём есть метод как для авторизации
|
Этот класс - результат слияния ASM'ом методов из Authlib 1.10.2 и Authlib 1.11+, в нём есть метод как для авторизации на
|
||||||
на сервере с учётом InetAddress, так и без него. Уже включён в `com.mojang.authlib-clean.jar`
|
сервере с учётом InetAddress, так и без него. Уже включён в `com.mojang.authlib-clean.jar`
|
||||||
|
|
Loading…
Reference in a new issue