[REFACTOR] IDEA Code Reformat

This commit is contained in:
Gravita 2021-03-20 15:53:22 +07:00
parent 3b839da3d3
commit 0b1f3f66af
53 changed files with 560 additions and 556 deletions

View file

@ -78,11 +78,9 @@ 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);
} }

View file

@ -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;
}
} }

View file

@ -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;
}
} }

View file

@ -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();
}
}
} }

View file

@ -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) {

View file

@ -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;

View file

@ -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;
}
} }

View file

@ -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;

View file

@ -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;

View file

@ -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);
} }
} }

View file

@ -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 "[]";
@ -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());
}
} }

View file

@ -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());
}
}
}
} }

View file

@ -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);

View file

@ -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;
}
}
} }

View file

@ -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;
@ -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,6 +52,7 @@ 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);
@ -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();

View file

@ -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;
}
} }

View file

@ -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();

View file

@ -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;
}
}
} }

View file

@ -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;
@ -105,8 +105,7 @@ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
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);
} }
} }

View file

@ -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)));
}
} }

View file

@ -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);
}
} }

View file

@ -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");
@ -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);
}
}
} }

View file

@ -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;

View file

@ -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,10 +71,12 @@ 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) {

View file

@ -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;
@ -139,8 +138,7 @@ 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) {
@ -200,13 +198,15 @@ public static void verifyHDir(Path dir, HashedDir hdir, FileNameMatcher 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;
}); });
} }
@ -264,8 +264,7 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa
} }
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);
} }
} }

View file

@ -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;
} }
public enum TrustDebugMode {
TRUST_ALL
}
@Override @Override
public CheckClassResult checkCertificates(X509Certificate[] certs, CertificateChecker checker) { public CheckClassResult checkCertificates(X509Certificate[] certs, CertificateChecker checker) {
if (mode == TrustDebugMode.TRUST_ALL) return new CheckClassResult(CheckClassResultType.SUCCESS, null, null); if (mode == TrustDebugMode.TRUST_ALL) return new CheckClassResult(CheckClassResultType.SUCCESS, null, null);
return super.checkCertificates(certs, checker); return super.checkCertificates(certs, checker);
} }
public enum TrustDebugMode {
TRUST_ALL
}
} }

View file

@ -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");

View file

@ -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);

View file

@ -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;
}
} }

View file

@ -49,16 +49,6 @@ 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);
} }
/**
* The internal method used by the ModuleManager
* DO NOT TOUCH
*
* @param result Check result
*/
public final void setCheckResult(LauncherTrustManager.CheckClassResult result) {
if(this.checkResult != null) throw new IllegalStateException("Module already set check result");
this.checkResult = result;
}
public final LauncherTrustManager.CheckClassResultType getCheckStatus() { public final LauncherTrustManager.CheckClassResultType getCheckStatus() {
if (this.checkResult == null) return null; if (this.checkResult == null) return null;
@ -70,6 +60,17 @@ public final LauncherTrustManager.CheckClassResult getCheckResult() {
return new LauncherTrustManager.CheckClassResult(this.checkResult); return new LauncherTrustManager.CheckClassResult(this.checkResult);
} }
/**
* The internal method used by the ModuleManager
* DO NOT TOUCH
*
* @param result Check result
*/
public final void setCheckResult(LauncherTrustManager.CheckClassResult result) {
if (this.checkResult != null) throw new IllegalStateException("Module already set check result");
this.checkResult = result;
}
/** /**
* 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>:

View file

@ -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;

View file

@ -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) {
@ -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);
}
}
} }

View file

@ -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;
}
} }

View file

@ -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;
}
} }

View file

@ -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;
} }
} }

View file

@ -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));

View file

@ -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;

View file

@ -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 {

View file

@ -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,40 +19,22 @@ 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) {
this.type = type;
this.endCertificate = endCertificate;
this.rootCertificate = rootCertificate;
exception = null;
} }
public CheckClassResult(CheckClassResultType type, X509Certificate endCertificate, X509Certificate rootCertificate, Exception exception) { 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)) {
this.exception = exception; return (X509Certificate) certFactory.generateCertificate(input);
} catch (IOException | CertificateException e) {
LogHelper.error(e);
return null;
}
}).toArray(X509Certificate[]::new);
} }
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) { public CheckClassResult checkCertificates(X509Certificate[] certs, CertificateChecker checker) {
if (certs == null) return new CheckClassResult(CheckClassResultType.NOT_SIGNED, null, null); if (certs == null) return new CheckClassResult(CheckClassResultType.NOT_SIGNED, null, null);
X509Certificate rootCert = certs[certs.length - 1]; X509Certificate rootCert = certs[certs.length - 1];
@ -106,22 +87,6 @@ public void checkCertificatesSuccess( X509Certificate[] certs, CertificateChecke
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;
}
}
} }

View file

@ -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;

View file

@ -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
``` ```

View file

@ -1,6 +1,7 @@
# Контроллер авторизации методом json # Контроллер авторизации методом json
Route: Route:
```php ```php
Route::put('launcher/auth', 'LauncherAuthController@json'); Route::put('launcher/auth', 'LauncherAuthController@json');
``` ```

View file

@ -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`