Merge branch 'dev' of github.com:GravitLauncher/Launcher into dev

This commit is contained in:
Zaxar163 2019-12-09 16:08:23 +01:00
commit 47e5902e94
No known key found for this signature in database
GPG key ID: 1FE4F2E1F053831B
61 changed files with 622 additions and 620 deletions

View file

@ -16,29 +16,17 @@
-keepattributes Signature
-adaptresourcefilecontents META-INF/MANIFEST.MF
-keeppackagenames com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.**, pro.gravit.launcher.api.**
-keeppackagenames com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.**, pro.gravit.launcher.api.**, pro.gravit.utils.**, pro.gravit.launcher.request.**, pro.gravit.launcher.events.**, pro.gravit.launcher.profiles.**
-keep class com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.**, pro.gravit.launcher.api.** {
-keep class com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.**, pro.gravit.launcher.api.**, pro.gravit.utils.**, pro.gravit.launcher.request.**, pro.gravit.launcher.events.**, pro.gravit.launcher.profiles.** {
*;
}
-keepclassmembers @pro.gravit.launcher.LauncherAPI class ** {
<fields>;
<methods>;
}
-keepclassmembers @pro.gravit.launcher.LauncherNetworkAPI class ** {
<fields>;
<methods>;
}
-keepclassmembers class ** {
@pro.gravit.launcher.LauncherAPI
<fields>;
@pro.gravit.launcher.LauncherAPI
<methods>;
}
-keepclassmembers class ** {
@pro.gravit.launcher.LauncherNetworkAPI
<fields>;

View file

@ -53,7 +53,7 @@ task javadocJar(type: Jar) {
}
dependencies {
pack project(':LauncherAuthlib')
pack project(':LauncherAPI')
bundle 'com.github.oshi:oshi-core:3.13.0'
pack 'io.netty:netty-codec-http:4.1.43.Final'
pack 'org.ow2.asm:asm-tree:7.1'

View file

@ -7,7 +7,7 @@
public abstract class JSApplication extends Application {
private static final AtomicReference<JSApplication> INSTANCE = new AtomicReference<>();
@LauncherAPI
public static JSApplication getInstance() {
return INSTANCE.get();
}

View file

@ -10,7 +10,7 @@
import java.nio.file.Path;
import java.util.jar.JarFile;
@LauncherAPI
public final class LauncherAgent {
private static boolean isAgentStarted = false;
public static Instrumentation inst;

View file

@ -126,7 +126,7 @@ private LauncherEngine() {
}
@LauncherAPI
public void start(String... args) throws Throwable {
//Launcher.modulesManager = new ClientModuleManager(this);
ClientPreGuiPhase event = new ClientPreGuiPhase(null);

View file

@ -8,21 +8,17 @@
import java.util.*;
public class NewLauncherSettings {
@LauncherAPI
@LauncherNetworkAPI
public Map<String, UserSettings> userSettings = new HashMap<>();
@LauncherAPI
@LauncherNetworkAPI
public List<String> features = new ArrayList<>();
@LauncherAPI
@LauncherNetworkAPI
public String consoleUnlockKey;
public static class HashedStoreEntry {
@LauncherAPI
public final HashedDir hdir;
@LauncherAPI
public final String name;
@LauncherAPI
public final String fullPath;
@LauncherAPI
public transient boolean needSave = false;
public HashedStoreEntry(HashedDir hdir, String name, String fullPath) {
@ -32,10 +28,9 @@ public HashedStoreEntry(HashedDir hdir, String name, String fullPath) {
}
}
@LauncherAPI
@LauncherNetworkAPI
public final transient List<HashedStoreEntry> lastHDirs = new ArrayList<>(16);
@LauncherAPI
public void putHDir(String name, Path path, HashedDir dir) {
String fullPath = path.toAbsolutePath().toString();
lastHDirs.removeIf((e) -> e.fullPath.equals(fullPath) && e.name.equals(name));

View file

@ -0,0 +1,89 @@
package pro.gravit.launcher.client;
import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.JVMHelper;
import java.net.URL;
import java.net.URLClassLoader;
public class ClientClassLoader extends URLClassLoader {
public String nativePath;
/**
* Constructs a new URLClassLoader for the specified URLs using the
* default delegation parent {@code ClassLoader}. The URLs will
* be searched in the order specified for classes and resources after
* first searching in the parent class loader. Any URL that ends with
* a '/' is assumed to refer to a directory. Otherwise, the URL is
* assumed to refer to a JAR file which will be downloaded and opened
* as needed.
*
* <p>If there is a security manager, this method first
* calls the security manager's {@code checkCreateClassLoader} method
* to ensure creation of a class loader is allowed.
*
* @param urls the URLs from which to load classes and resources
* @throws SecurityException if a security manager exists and its
* {@code checkCreateClassLoader} method doesn't allow
* creation of a class loader.
* @throws NullPointerException if {@code urls} is {@code null}.
* @see SecurityManager#checkCreateClassLoader
*/
public ClientClassLoader(URL[] urls) {
super(urls);
}
/**
* Constructs a new URLClassLoader for the given URLs. The URLs will be
* searched in the order specified for classes and resources after first
* searching in the specified parent class loader. Any {@code jar:}
* scheme URL is assumed to refer to a JAR file. Any {@code file:} scheme
* URL that ends with a '/' is assumed to refer to a directory. Otherwise,
* the URL is assumed to refer to a JAR file which will be downloaded and
* opened as needed.
*
* <p>If there is a security manager, this method first
* calls the security manager's {@code checkCreateClassLoader} method
* to ensure creation of a class loader is allowed.
*
* @param urls the URLs from which to load classes and resources
* @param parent the parent class loader for delegation
* @throws SecurityException if a security manager exists and its
* {@code checkCreateClassLoader} method doesn't allow
* creation of a class loader.
* @throws NullPointerException if {@code urls} is {@code null}.
* @see SecurityManager#checkCreateClassLoader
*/
public ClientClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}
@Override
public String findLibrary(String name) {
return nativePath.concat(IOHelper.PLATFORM_SEPARATOR).concat(getNativePrefix()).concat(name).concat(getNativeEx());
}
public String getNativeEx()
{
if(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
return ".dll";
else if(JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
return ".so";
else if(JVMHelper.OS_TYPE == JVMHelper.OS.MACOSX)
return ".dylib";
return "";
}
public String getNativePrefix()
{
if(JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
return "lib";
else if(JVMHelper.OS_TYPE == JVMHelper.OS.MACOSX)
return "lib";
return "";
}
@Override
public void addURL(URL url) {
super.addURL(url);
}
}

View file

@ -10,7 +10,6 @@
import pro.gravit.launcher.hasher.FileNameMatcher;
import pro.gravit.launcher.hasher.HashedDir;
import pro.gravit.launcher.hwid.HWIDProvider;
import pro.gravit.launcher.hwid.OshiHWIDProvider;
import pro.gravit.launcher.managers.ClientGsonManager;
import pro.gravit.launcher.managers.ClientHookManager;
import pro.gravit.launcher.modules.events.PreConfigPhase;
@ -50,7 +49,7 @@
public final class ClientLauncher {
@LauncherAPI
public static int getClientJVMBits() {
return LauncherGuardManager.guard.getClientJVMBits();
}
@ -72,30 +71,30 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
public static final class Params extends StreamObject {
// Client paths
@LauncherAPI
public final Path assetDir;
@LauncherAPI
public final Path clientDir;
// Client params
@LauncherAPI
public final PlayerProfile pp;
@LauncherAPI
public final String accessToken;
@LauncherAPI
public final boolean autoEnter;
@LauncherAPI
public final boolean fullScreen;
@LauncherAPI
public final int ram;
@LauncherAPI
public final int width;
@LauncherAPI
public final int height;
@LauncherAPI
public final long session;
@LauncherAPI
public Params(byte[] launcherDigest, Path assetDir, Path clientDir, PlayerProfile pp, String accessToken,
boolean autoEnter, boolean fullScreen, int ram, int width, int height) {
// Client paths
@ -112,7 +111,7 @@ public Params(byte[] launcherDigest, Path assetDir, Path clientDir, PlayerProfil
this.session = Request.getSession();
}
@LauncherAPI
public Params(HInput input) throws Exception {
session = input.readLong();
// Client paths
@ -163,16 +162,16 @@ public void write(HOutput output) throws IOException {
// Constants
private static final Path NATIVES_DIR = IOHelper.toPath("natives");
private static final Path RESOURCEPACKS_DIR = IOHelper.toPath("resourcepacks");
private static PublicURLClassLoader classLoader;
private static ClientClassLoader classLoader;
public static class ClientUserProperties {
@LauncherAPI
String[] skinURL;
@LauncherAPI
String[] skinDigest;
@LauncherAPI
String[] cloakURL;
@LauncherAPI
String[] cloakDigest;
}
@ -234,7 +233,7 @@ private static void addClientArgs(Collection<String> args, ClientProfile profile
}
}
@LauncherAPI
public static void setJavaBinPath(Path javaBinPath) {
JavaBinPath = javaBinPath;
}
@ -249,7 +248,7 @@ private static void addClientLegacyArgs(Collection<String> args, ClientProfile p
Collections.addAll(args, "--assetsDir", params.assetDir.toString());
}
@LauncherAPI
public static void checkJVMBitsAndVersion() {
if (JVMHelper.JVM_BITS != JVMHelper.OS_BITS) {
String error = String.format("У Вас установлена Java %d, но Ваша система определена как %d. Установите Java правильной разрядности", JVMHelper.JVM_BITS, JVMHelper.OS_BITS);
@ -267,7 +266,7 @@ public static void checkJVMBitsAndVersion() {
}
}
@LauncherAPI
public static boolean isLaunched() {
return Launcher.LAUNCHED.get();
}
@ -292,6 +291,10 @@ private static void launch(ClientProfile profile, Params params) throws Throwabl
LogHelper.debug("Args: " + copy);
// Resolve main class and method
Class<?> mainClass = classLoader.loadClass(profile.getMainClass());
for(URL u : classLoader.getURLs())
{
LogHelper.info("ClassLoader URL: %s", u.toString());
}
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)).asFixedArity();
Launcher.LAUNCHED.set(true);
JVMHelper.fullGC();
@ -318,7 +321,7 @@ public static void setClientStarted() {
public static PlayerProfile playerProfile;
@LauncherAPI
public static Process launch(
HashedDir assetHDir, HashedDir clientHDir,
ClientProfile profile, Params params, boolean pipeOutput) throws Throwable {
@ -429,7 +432,7 @@ public ClientLaunchContext(Params params, ClientProfile profile, HashedDir asset
}
}
@LauncherAPI
public static void main(String... args) throws Throwable {
LauncherEngine.IS_CLIENT.set(true);
LauncherEngine engine = LauncherEngine.clientInstance();
@ -468,19 +471,18 @@ public static void main(String... args) throws Throwable {
LogHelper.debug("Verifying ClientLauncher sign and classpath");
LinkedList<Path> classPath = resolveClassPathList(params.clientDir, profile.getClassPath());
for (Path classpathURL : classPath) {
LauncherAgent.addJVMClassPath(classpathURL.normalize().toAbsolutePath());
//LauncherAgent.addJVMClassPath(classpathURL.normalize().toAbsolutePath());
}
profile.pushOptionalClassPath(cp -> {
LinkedList<Path> optionalClassPath = resolveClassPathList(params.clientDir, cp);
for (Path classpathURL : optionalClassPath) {
LauncherAgent.addJVMClassPath(classpathURL.normalize().toAbsolutePath());
//LauncherAgent.addJVMClassPath(classpathURL.normalize().toAbsolutePath());
}
});
URL[] classpathurls = resolveClassPath(params.clientDir, profile.getClassPath());
classLoader = new PublicURLClassLoader(classpathurls, ClassLoader.getSystemClassLoader());
classLoader = new ClientClassLoader(classpathurls, ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(classLoader);
classLoader.nativePath = params.clientDir.resolve(NATIVES_DIR).toString();
PublicURLClassLoader.systemclassloader = classLoader;
// Start client with WatchService monitoring
boolean digest = !profile.isUpdateFastCheck();
LogHelper.debug("Restore sessions");
@ -507,6 +509,8 @@ public static void main(String... args) throws Throwable {
AuthService.uuid = params.pp.uuid;
ClientService.instrumentation = LauncherAgent.inst;
ClientService.classLoader = classLoader;
classLoader.addURL(IOHelper.getCodeSource(ClientLauncher.class).toUri().toURL());
//classForName(classLoader, "com.google.common.collect.ForwardingMultimap");
ClientService.baseURLs = classpathurls;
LogHelper.debug("Starting JVM and client WatchService");
FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher();
@ -532,6 +536,13 @@ public static void main(String... args) throws Throwable {
launch(profile, params);
}
}
public static void classForName(ClassLoader loader, String name)
{
try {
Class.forName(name, false, loader);
} catch (ClassNotFoundException ignored) {
}
}
private static URL[] resolveClassPath(Path clientDir, String... classPath) throws IOException {
return resolveClassPathStream(clientDir, classPath).map(IOHelper::toURL).toArray(URL[]::new);
@ -559,7 +570,7 @@ private static void initGson(ClientModuleManager moduleManager) {
Launcher.gsonManager.initGson();
}
@LauncherAPI
public static void setProfile(ClientProfile profile) {
Launcher.profile = profile;
LogHelper.debug("New Profile name: %s", profile.getTitle());

View file

@ -1,7 +1,6 @@
package pro.gravit.launcher.client;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.JVMHelper;
import pro.gravit.utils.helper.LogHelper;
@ -17,26 +16,26 @@ public class DirBridge {
public static final String CUSTOMDIR_PROPERTY = "launcher.customdir";
public static final String USE_OPTDIR_PROPERTY = "launcher.useoptdir";
@LauncherAPI
public static Path dir;
@LauncherAPI
public static Path dirStore;
@LauncherAPI
public static Path dirProjectStore;
@LauncherAPI
public static Path dirUpdates;
@LauncherAPI
public static Path defaultUpdatesDir;
@LauncherAPI
public static boolean useLegacyDir;
@LauncherAPI
public static void move(Path newDir) throws IOException {
IOHelper.move(dirUpdates, newDir);
dirUpdates = newDir;
}
@LauncherAPI
public static Path getAppDataDir() throws IOException {
boolean isCustomDir = Boolean.getBoolean(System.getProperty(USE_CUSTOMDIR_PROPERTY, "false"));
if (isCustomDir) {
@ -66,12 +65,12 @@ public static Path getAppDataDir() throws IOException {
}
}
@LauncherAPI
public static Path getLauncherDir(String projectname) throws IOException {
return getAppDataDir().resolve(projectname);
}
@LauncherAPI
public static Path getStoreDir(String projectname) throws IOException {
if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
return getAppDataDir().resolve("store");
@ -81,22 +80,22 @@ else if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
return getAppDataDir().resolve("minecraftStore");
}
@LauncherAPI
public static Path getProjectStoreDir(String projectname) throws IOException {
return getStoreDir(projectname).resolve(projectname);
}
@LauncherAPI
public static Path getGuardDir() {
return dir.resolve("guard");
}
@LauncherAPI
public static Path getLegacyLauncherDir(String projectname) {
return IOHelper.HOME_DIR.resolve(projectname);
}
@LauncherAPI
public static void setUseLegacyDir(boolean b) {
useLegacyDir = b;
}

View file

@ -2,7 +2,6 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.profiles.ClientProfile;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.HOutput;
@ -24,11 +23,11 @@ public final class ServerPinger {
private final JsonParser parser = new JsonParser();
public static final class Result {
@LauncherAPI
public final int onlinePlayers;
@LauncherAPI
public final int maxPlayers;
@LauncherAPI
public final String raw;
public Result(int onlinePlayers, int maxPlayers, String raw) {
@ -39,7 +38,7 @@ public Result(int onlinePlayers, int maxPlayers, String raw) {
this.raw = raw;
}
@LauncherAPI
public boolean isOverfilled() {
return onlinePlayers >= maxPlayers;
}
@ -75,7 +74,7 @@ private static void writeUTF16String(HOutput output, String s) throws IOExceptio
private Instant cacheTime = null;
@LauncherAPI
public ServerPinger(ClientProfile profile) {
this.address = Objects.requireNonNull(profile.getServerSocketAddress(), "address");
this.version = Objects.requireNonNull(profile.getVersion(), "version");
@ -194,7 +193,7 @@ private Result modernPing(HInput input, HOutput output) throws IOException {
return new Result(online, max, response);
}
@LauncherAPI
public Result ping() throws IOException {
Instant now = Instant.now();
synchronized (cacheLock) {

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.managers;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.hasher.FileNameMatcher;
import pro.gravit.launcher.hasher.HashedDir;
import pro.gravit.launcher.hasher.HashedEntry;
@ -19,15 +18,15 @@ public class HasherStore {
public Map<String, HasherStoreEnity> store;
public static class HasherStoreEnity {
@LauncherAPI
public HashedDir hdir;
@LauncherAPI
public Path dir;
@LauncherAPI
public Collection<String> shared;
}
@LauncherAPI
public void addProfileUpdateDir(ClientProfile profile, Path dir, HashedDir hdir) {
HasherStoreEnity e = new HasherStoreEnity();
e.hdir = hdir;
@ -37,7 +36,7 @@ public void addProfileUpdateDir(ClientProfile profile, Path dir, HashedDir hdir)
store.put(profile.getTitle(), e);
}
@LauncherAPI
public void copyCompareFilesTo(String name, Path targetDir, HashedDir targetHDir, String[] shared) {
store.forEach((key, e) -> {
if (key.equals(name)) return;
@ -47,7 +46,7 @@ public void copyCompareFilesTo(String name, Path targetDir, HashedDir targetHDir
});
}
@LauncherAPI
public void recurseCopy(String filename, HashedEntry entry, String name, Path targetDir, Path sourceDir) {
if (!IOHelper.isDir(targetDir)) {
try {

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.managers;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.NewLauncherSettings;
import pro.gravit.launcher.client.DirBridge;
import pro.gravit.launcher.config.JsonConfigurable;
@ -32,26 +31,26 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
}
@LauncherAPI
public static NewLauncherSettings settings;
public SettingsManager() {
super(NewLauncherSettings.class, DirBridge.dir.resolve("settings.json"));
}
@LauncherAPI
@Override
public NewLauncherSettings getConfig() {
return settings;
}
@LauncherAPI
@Override
public NewLauncherSettings getDefaultConfig() {
return new NewLauncherSettings();
}
@LauncherAPI
@Override
public void setConfig(NewLauncherSettings config) {
settings = config;
@ -63,13 +62,13 @@ public void setConfig(NewLauncherSettings config) {
}
}
@LauncherAPI
public void loadHDirStore(Path storePath) throws IOException {
Files.createDirectories(storePath);
IOHelper.walk(storePath, new StoreFileVisitor(), false);
}
@LauncherAPI
public void saveHDirStore(Path storeProjectPath) throws IOException {
Files.createDirectories(storeProjectPath);
for (NewLauncherSettings.HashedStoreEntry e : settings.lastHDirs) {
@ -84,12 +83,12 @@ public void saveHDirStore(Path storeProjectPath) throws IOException {
}
}
@LauncherAPI
public void loadHDirStore() throws IOException {
loadHDirStore(DirBridge.dirStore);
}
@LauncherAPI
public void saveHDirStore() throws IOException {
saveHDirStore(DirBridge.dirProjectStore);
}

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.utils;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.hasher.FileNameMatcher;
import pro.gravit.launcher.hasher.HashedDir;
import pro.gravit.launcher.hasher.HashedEntry;
@ -69,7 +68,7 @@ private static Deque<String> toPath(Iterable<Path> path) {
private final boolean digest;
@LauncherAPI
public DirWatcher(Path dir, HashedDir hdir, FileNameMatcher matcher, boolean digest) throws IOException {
this.dir = Objects.requireNonNull(dir, "dir");
this.hdir = Objects.requireNonNull(hdir, "hdir");
@ -83,7 +82,7 @@ public DirWatcher(Path dir, HashedDir hdir, FileNameMatcher matcher, boolean dig
}
@Override
@LauncherAPI
public void close() throws IOException {
service.close();
}
@ -124,7 +123,7 @@ private void processLoop() throws IOException, InterruptedException {
}
@Override
@LauncherAPI
public void run() {
try {
processLoop();

View file

@ -8,17 +8,17 @@
public class ClientPermissions {
public static final ClientPermissions DEFAULT = new ClientPermissions();
@LauncherAPI
@LauncherNetworkAPI
public boolean canAdmin;
@LauncherAPI
@LauncherNetworkAPI
public boolean canServer;
@LauncherAPI
@LauncherNetworkAPI
public final boolean canUSR1;
@LauncherAPI
@LauncherNetworkAPI
public final boolean canUSR2;
@LauncherAPI
@LauncherNetworkAPI
public final boolean canUSR3;
@LauncherAPI
@LauncherNetworkAPI
public boolean canBot;
public ClientPermissions(HInput input) throws IOException {
@ -43,7 +43,7 @@ public ClientPermissions(long data) {
canBot = (data & (1 << 5)) != 0;
}
@LauncherAPI
public long toLong() {
long result = 0;
result |= !canAdmin ? 0 : 1;

View file

@ -20,42 +20,42 @@
public final class Launcher {
// Authlib constants
@LauncherAPI
public static final String SKIN_URL_PROPERTY = "skinURL";
@LauncherAPI
public static final String SKIN_DIGEST_PROPERTY = "skinDigest";
@LauncherAPI
public static final String CLOAK_URL_PROPERTY = "cloakURL";
@LauncherAPI
public static final String CLOAK_DIGEST_PROPERTY = "cloakDigest";
// Used to determine from clientside is launched from launcher
public static final AtomicBoolean LAUNCHED = new AtomicBoolean(false);
private static final AtomicReference<LauncherConfig> CONFIG = new AtomicReference<>();
@LauncherAPI
public static final int PROTOCOL_MAGIC_LEGACY = 0x724724_00 + 24;
@LauncherAPI
public static final int PROTOCOL_MAGIC = 0xA205B064; // e = 2.718281828
// Constants
@LauncherAPI
public static final String RUNTIME_DIR = "runtime";
@LauncherAPI
public static final String GUARD_DIR = "guard";
@LauncherAPI
public static final String CONFIG_FILE = "config.bin";
@LauncherAPI
public static ClientProfile profile;
@LauncherAPI
public static final String INIT_SCRIPT_FILE = "init.js";
@LauncherAPI
public static final String API_SCRIPT_FILE = "engine/api.js";
public static final String CONFIG_SCRIPT_FILE = "config.js";
private static final Pattern UUID_PATTERN = Pattern.compile("-", Pattern.LITERAL);
public static GsonManager gsonManager;
@LauncherAPI
public static LauncherConfig getConfig() {
LauncherConfig config = CONFIG.get();
if (config == null) {
@ -69,12 +69,12 @@ public static LauncherConfig getConfig() {
return config;
}
@LauncherAPI
public static void setConfig(LauncherConfig cfg) {
CONFIG.set(cfg);
}
@LauncherAPI
public static URL getResourceURL(String name) throws IOException {
LauncherConfig config = getConfig();
byte[] validDigest = config.runtime.get(name);
@ -105,7 +105,7 @@ public static URL getResourceURL(String name, String prefix) throws IOException
return url;
}
@LauncherAPI
public static String toHash(UUID uuid) {
return UUID_PATTERN.matcher(uuid.toString()).replaceAll("");
}

View file

@ -24,16 +24,16 @@ public static AutogenConfig getAutogenConfig() {
// Instance
public String address;
@LauncherAPI
public final String projectName;
public final int clientPort;
public String secretKeyClient;
public String oemUnlockKey;
public final LauncherTrustManager trustManager;
@LauncherAPI
public final ECPublicKey publicKey;
@LauncherAPI
public final Map<String, byte[]> runtime;
public final boolean isWarningMissArchJava;
public boolean isNettyEnabled;
@ -45,7 +45,7 @@ public static AutogenConfig getAutogenConfig() {
public final String secureCheckSalt;
public final String passwordEncryptKey;
@LauncherAPI
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
publicKey = SecurityHelper.toPublicECKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
secureCheckHash = config.secureCheckHash;
@ -84,7 +84,7 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException
runtime = Collections.unmodifiableMap(localResources);
}
@LauncherAPI
public LauncherConfig(String address, ECPublicKey publicKey, Map<String, byte[]> runtime, String projectName) {
this.address = address;
this.publicKey = publicKey;

View file

@ -1,7 +1,5 @@
package pro.gravit.launcher.config;
import pro.gravit.launcher.LauncherAPI;
import java.lang.reflect.Type;
import java.nio.file.Path;
@ -9,7 +7,7 @@ public abstract class JsonConfigurable<T> implements JsonConfigurableInterface<T
private transient final Type type;
protected transient final Path configPath;
@LauncherAPI
public JsonConfigurable(Type type, Path configPath) {
this.type = type;
this.configPath = configPath;
@ -25,12 +23,12 @@ public Type getType() {
return type;
}
@LauncherAPI
public abstract T getConfig();
@LauncherAPI
public abstract T getDefaultConfig();
@LauncherAPI
public abstract void setConfig(T config);
}

View file

@ -2,7 +2,6 @@
import com.google.gson.Gson;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.LogHelper;
@ -13,24 +12,24 @@
import java.nio.file.Path;
public interface JsonConfigurableInterface<T> {
@LauncherAPI
default void saveConfig() throws IOException {
saveConfig(getPath());
}
@LauncherAPI
default void loadConfig() throws IOException {
loadConfig(getPath());
}
@LauncherAPI
default void saveConfig(Gson gson, Path configPath) throws IOException {
try (BufferedWriter writer = IOHelper.newWriter(configPath)) {
gson.toJson(getConfig(), getType(), writer);
}
}
@LauncherAPI
default void loadConfig(Gson gson, Path configPath) throws IOException {
if (generateConfigIfNotExists(configPath)) return;
try (BufferedReader reader = IOHelper.newReader(configPath)) {
@ -41,29 +40,29 @@ default void loadConfig(Gson gson, Path configPath) throws IOException {
}
}
@LauncherAPI
default void saveConfig(Path configPath) throws IOException {
saveConfig(Launcher.gsonManager.configGson, configPath);
}
@LauncherAPI
default void loadConfig(Path configPath) throws IOException {
loadConfig(Launcher.gsonManager.configGson, configPath);
}
@LauncherAPI
default void resetConfig() throws IOException {
setConfig(getDefaultConfig());
saveConfig();
}
@LauncherAPI
default void resetConfig(Path newPath) throws IOException {
setConfig(getDefaultConfig());
saveConfig(newPath);
}
@LauncherAPI
default boolean generateConfigIfNotExists(Path path) throws IOException {
if (IOHelper.isFile(path))
return false;
@ -71,7 +70,7 @@ default boolean generateConfigIfNotExists(Path path) throws IOException {
return true;
}
@LauncherAPI
default boolean generateConfigIfNotExists() throws IOException {
if (IOHelper.isFile(getPath()))
return false;
@ -79,16 +78,16 @@ default boolean generateConfigIfNotExists() throws IOException {
return true;
}
@LauncherAPI
T getConfig();
@LauncherAPI
T getDefaultConfig();
@LauncherAPI
void setConfig(T config);
@LauncherAPI
Path getPath();
Type getType();

View file

@ -1,10 +1,10 @@
package pro.gravit.launcher.events.request;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.events.RequestEvent;
public class VerifySecureTokenRequestEvent extends RequestEvent {
@LauncherAPI
@LauncherNetworkAPI
public final boolean success;
@Override

View file

@ -1,22 +1,22 @@
package pro.gravit.launcher.hwid;
import com.google.gson.Gson;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import java.util.Objects;
import java.util.StringJoiner;
public class OshiHWID implements HWID {
public static Gson gson = new Gson();
@LauncherAPI
@LauncherNetworkAPI
public long totalMemory = 0;
@LauncherAPI
@LauncherNetworkAPI
public String serialNumber;
@LauncherAPI
@LauncherNetworkAPI
public String HWDiskSerial;
@LauncherAPI
@LauncherNetworkAPI
public String processorID;
@LauncherAPI
@LauncherNetworkAPI
public String macAddr;
@Override

View file

@ -1,6 +1,6 @@
package pro.gravit.launcher.profiles;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.hasher.FileNameMatcher;
import pro.gravit.launcher.hasher.HashedDir;
import pro.gravit.launcher.profiles.optional.OptionalDepend;
@ -14,7 +14,7 @@
import java.util.*;
public final class ClientProfile implements Comparable<ClientProfile> {
@LauncherAPI
public enum Version {
MC125("1.2.5", 29),
MC147("1.4.7", 51),
@ -73,54 +73,54 @@ public String toString() {
private static final FileNameMatcher ASSET_MATCHER = new FileNameMatcher(
new String[0], new String[]{"indexes", "objects"}, new String[0]);
// Version
@LauncherAPI
@LauncherNetworkAPI
private String version;
@LauncherAPI
@LauncherNetworkAPI
private String assetIndex;
@LauncherAPI
@LauncherNetworkAPI
private String dir;
@LauncherAPI
@LauncherNetworkAPI
private String assetDir;
// Client
@LauncherAPI
@LauncherNetworkAPI
private int sortIndex;
@LauncherAPI
@LauncherNetworkAPI
private UUID uuid;
@LauncherAPI
@LauncherNetworkAPI
private String title;
@LauncherAPI
@LauncherNetworkAPI
private String info;
@LauncherAPI
@LauncherNetworkAPI
private String serverAddress;
@LauncherAPI
@LauncherNetworkAPI
private int serverPort;
// Updater and client watch service
@LauncherAPI
@LauncherNetworkAPI
private final List<String> update = new ArrayList<>();
@LauncherAPI
@LauncherNetworkAPI
private final List<String> updateExclusions = new ArrayList<>();
@LauncherAPI
@LauncherNetworkAPI
private final List<String> updateShared = new ArrayList<>();
@LauncherAPI
@LauncherNetworkAPI
private final List<String> updateVerify = new ArrayList<>();
@LauncherAPI
@LauncherNetworkAPI
private final Set<OptionalFile> updateOptional = new HashSet<>();
@LauncherAPI
@LauncherNetworkAPI
private boolean updateFastCheck;
@LauncherAPI
@LauncherNetworkAPI
private boolean useWhitelist;
// Client launcher
@LauncherAPI
@LauncherNetworkAPI
private String mainClass;
@LauncherAPI
@LauncherNetworkAPI
private final List<String> jvmArgs = new ArrayList<>();
@LauncherAPI
@LauncherNetworkAPI
private final List<String> classPath = new ArrayList<>();
@LauncherAPI
@LauncherNetworkAPI
private final List<String> clientArgs = new ArrayList<>();
@LauncherAPI
@LauncherNetworkAPI
private final List<String> whitelist = new ArrayList<>();
@Override
@ -128,27 +128,27 @@ public int compareTo(ClientProfile o) {
return Integer.compare(getSortIndex(), o.getSortIndex());
}
@LauncherAPI
public String getAssetIndex() {
return assetIndex;
}
@LauncherAPI
public FileNameMatcher getAssetUpdateMatcher() {
return getVersion().compareTo(Version.MC1710) >= 0 ? ASSET_MATCHER : null;
}
@LauncherAPI
public String[] getClassPath() {
return classPath.toArray(new String[0]);
}
@LauncherAPI
public String[] getClientArgs() {
return clientArgs.toArray(new String[0]);
}
@LauncherAPI
public String getDir() {
return dir;
}
@ -157,12 +157,12 @@ public void setDir(String dir) {
this.dir = dir;
}
@LauncherAPI
public String getAssetDir() {
return assetDir;
}
@LauncherAPI
public FileNameMatcher getClientUpdateMatcher(/*boolean excludeOptional*/) {
String[] updateArray = update.toArray(new String[0]);
String[] verifyArray = updateVerify.toArray(new String[0]);
@ -179,27 +179,27 @@ public FileNameMatcher getClientUpdateMatcher(/*boolean excludeOptional*/) {
return new FileNameMatcher(updateArray, verifyArray, exclusionsArray);
}
@LauncherAPI
public String[] getJvmArgs() {
return jvmArgs.toArray(new String[0]);
}
@LauncherAPI
public String getMainClass() {
return mainClass;
}
@LauncherAPI
public String getServerAddress() {
return serverAddress;
}
@LauncherAPI
public Set<OptionalFile> getOptional() {
return updateOptional;
}
@LauncherAPI
public void updateOptionalGraph() {
for (OptionalFile file : updateOptional) {
if (file.dependenciesFile != null) {
@ -217,19 +217,19 @@ public void updateOptionalGraph() {
}
}
@LauncherAPI
public OptionalFile getOptionalFile(String file, OptionalType type) {
for (OptionalFile f : updateOptional)
if (f.type.equals(type) && f.name.equals(file)) return f;
return null;
}
@LauncherAPI
public Collection<String> getShared() {
return updateShared;
}
@LauncherAPI
public void markOptional(String name, OptionalType type) {
OptionalFile file = getOptionalFile(name, type);
if (file == null) {
@ -238,7 +238,7 @@ public void markOptional(String name, OptionalType type) {
markOptional(file);
}
@LauncherAPI
public void markOptional(OptionalFile file) {
if (file.mark) return;
@ -257,7 +257,7 @@ public void markOptional(OptionalFile file) {
}
}
@LauncherAPI
public void unmarkOptional(String name, OptionalType type) {
OptionalFile file = getOptionalFile(name, type);
if (file == null) {
@ -266,7 +266,7 @@ public void unmarkOptional(String name, OptionalType type) {
unmarkOptional(file);
}
@LauncherAPI
public void unmarkOptional(OptionalFile file) {
if (!file.mark) return;
file.mark = false;
@ -330,58 +330,58 @@ public interface pushOptionalClassPathCallback {
void run(String[] opt) throws IOException;
}
@LauncherAPI
public int getServerPort() {
return serverPort;
}
@LauncherAPI
public InetSocketAddress getServerSocketAddress() {
return InetSocketAddress.createUnresolved(getServerAddress(), getServerPort());
}
@LauncherAPI
public int getSortIndex() {
return sortIndex;
}
@LauncherAPI
public String getTitle() {
return title;
}
@LauncherAPI
public String getInfo() {
return info;
}
@LauncherAPI
public Version getVersion() {
return Version.byName(version);
}
@LauncherAPI
public boolean isUpdateFastCheck() {
return updateFastCheck;
}
@LauncherAPI
public boolean isWhitelistContains(String username) {
if (!useWhitelist) return true;
return whitelist.stream().anyMatch(profileCaseSensitive ? e -> e.equals(username) : e -> e.equalsIgnoreCase(username));
}
@LauncherAPI
public void setTitle(String title) {
this.title = title;
}
@LauncherAPI
public void setInfo(String info) {
this.info = info;
}
@LauncherAPI
public void setVersion(Version version) {
this.version = version.name;
}
@ -399,7 +399,7 @@ public UUID getUUID() {
return uuid;
}
@LauncherAPI
public void verify() {
// Version
getVersion();

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.profiles;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.HOutput;
import pro.gravit.launcher.serialize.stream.StreamObject;
@ -12,26 +11,26 @@
import java.util.UUID;
public final class PlayerProfile extends StreamObject {
@LauncherAPI
public static PlayerProfile newOfflineProfile(String username) {
return new PlayerProfile(offlineUUID(username), username, null, null);
}
@LauncherAPI
public static UUID offlineUUID(String username) {
return UUID.nameUUIDFromBytes(IOHelper.encodeASCII("OfflinePlayer:" + username));
}
@LauncherAPI
public final UUID uuid;
@LauncherAPI
public final String username;
@LauncherAPI
public final Texture skin, cloak;
@LauncherAPI
public PlayerProfile(HInput input) throws IOException {
uuid = input.readUUID();
username = VerifyHelper.verifyUsername(input.readString(64));
@ -39,7 +38,7 @@ public PlayerProfile(HInput input) throws IOException {
cloak = input.readBoolean() ? new Texture(input) : null;
}
@LauncherAPI
public PlayerProfile(UUID uuid, String username, Texture skin, Texture cloak) {
this.uuid = Objects.requireNonNull(uuid, "uuid");
this.username = VerifyHelper.verifyUsername(username);

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.profiles;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.HOutput;
import pro.gravit.launcher.serialize.stream.StreamObject;
@ -17,18 +16,18 @@ public final class Texture extends StreamObject {
private static final SecurityHelper.DigestAlgorithm DIGEST_ALGO = SecurityHelper.DigestAlgorithm.SHA256;
// Instance
@LauncherAPI
public final String url;
@LauncherAPI
public final byte[] digest;
@LauncherAPI
public Texture(HInput input) throws IOException {
url = IOHelper.verifyURL(input.readASCII(2048));
digest = input.readByteArray(-DIGEST_ALGO.bytes);
}
@LauncherAPI
public Texture(String url, boolean cloak) throws IOException {
this.url = IOHelper.verifyURL(url);
@ -45,7 +44,7 @@ public Texture(String url, boolean cloak) throws IOException {
digest = SecurityHelper.digest(DIGEST_ALGO, new URL(url));
}
@LauncherAPI
public Texture(String url, byte[] digest) {
this.url = IOHelper.verifyURL(url);
this.digest = Objects.requireNonNull(digest, "digest");

View file

@ -1,10 +1,10 @@
package pro.gravit.launcher.profiles.optional;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
public class OptionalDepend {
@LauncherAPI
@LauncherNetworkAPI
public String name;
@LauncherAPI
@LauncherNetworkAPI
public OptionalType type;
}

View file

@ -1,6 +1,6 @@
package pro.gravit.launcher.profiles.optional;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.HOutput;
import pro.gravit.utils.helper.LogHelper;
@ -10,33 +10,33 @@
import java.util.Set;
public class OptionalFile {
@LauncherAPI
@LauncherNetworkAPI
public String[] list;
@LauncherAPI
@LauncherNetworkAPI
public OptionalType type;
@LauncherAPI
@LauncherNetworkAPI
public boolean mark;
@LauncherAPI
@LauncherNetworkAPI
public final boolean visible = true;
@LauncherAPI
@LauncherNetworkAPI
public String name;
@LauncherAPI
@LauncherNetworkAPI
public String info;
@LauncherAPI
@LauncherNetworkAPI
public OptionalDepend[] dependenciesFile;
@LauncherAPI
@LauncherNetworkAPI
public OptionalDepend[] conflictFile;
@LauncherAPI
@LauncherNetworkAPI
public transient OptionalFile[] dependencies;
@LauncherAPI
@LauncherNetworkAPI
public transient OptionalFile[] conflict;
@LauncherAPI
@LauncherNetworkAPI
public int subTreeLevel = 1;
@LauncherAPI
@LauncherNetworkAPI
public boolean isPreset;
@LauncherAPI
@LauncherNetworkAPI
public final long permissions = 0L;
@LauncherAPI
public transient Set<OptionalFile> dependenciesCount;
@Override
@ -51,32 +51,32 @@ public int hashCode() {
return Objects.hash(name);
}
@LauncherAPI
public OptionalType getType() {
return OptionalType.FILE;
}
@LauncherAPI
public String getName() {
return name;
}
@LauncherAPI
public boolean isVisible() {
return visible;
}
@LauncherAPI
public boolean isMark() {
return mark;
}
@LauncherAPI
public long getPermissions() {
return permissions;
}
@LauncherAPI
public void writeType(HOutput output) throws IOException {
switch (type) {
@ -98,7 +98,7 @@ public void writeType(HOutput output) throws IOException {
}
}
@LauncherAPI
public static OptionalType readType(HInput input) throws IOException {
int t = input.readInt();
OptionalType type;

View file

@ -1,15 +1,14 @@
package pro.gravit.launcher.profiles.optional;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
@LauncherAPI
public enum OptionalType {
@LauncherAPI
@LauncherNetworkAPI
FILE,
@LauncherAPI
@LauncherNetworkAPI
CLASSPATH,
@LauncherAPI
@LauncherNetworkAPI
JVMARGS,
@LauncherAPI
@LauncherNetworkAPI
CLIENTARGS
}

View file

@ -1,7 +1,6 @@
package pro.gravit.launcher.request;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.request.websockets.StandartClientWebSocketService;
import pro.gravit.launcher.request.websockets.WebSocketRequest;
@ -24,14 +23,14 @@ public static long getSession() {
return Request.session;
}
@LauncherAPI
public static void requestError(String message) throws RequestException {
throw new RequestException(message);
}
private transient final AtomicBoolean started = new AtomicBoolean(false);
@LauncherAPI
public R request() throws Exception {
if (!started.compareAndSet(false, true))
throw new IllegalStateException("Request already started");
@ -40,7 +39,7 @@ public R request() throws Exception {
return requestDo(service);
}
@LauncherAPI
public R request(StandartClientWebSocketService service) throws Exception {
if (!started.compareAndSet(false, true))
throw new IllegalStateException("Request already started");

View file

@ -1,23 +1,21 @@
package pro.gravit.launcher.request;
import pro.gravit.launcher.LauncherAPI;
import java.io.IOException;
public final class RequestException extends IOException {
private static final long serialVersionUID = 7558237657082664821L;
@LauncherAPI
public RequestException(String message) {
super(message);
}
@LauncherAPI
public RequestException(String message, Throwable exc) {
super(message, exc);
}
@LauncherAPI
public RequestException(Throwable exc) {
super(exc);
}

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.request;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.stream.EnumSerializer;
@ -15,7 +14,7 @@ public enum RequestType implements EnumSerializer.Itf {
CUSTOM(255); // Custom requests
private static final EnumSerializer<RequestType> SERIALIZER = new EnumSerializer<>(RequestType.class);
@LauncherAPI
public static RequestType read(HInput input) throws IOException {
return SERIALIZER.read(input);
}

View file

@ -1,12 +1,11 @@
package pro.gravit.launcher.request.admin;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.events.request.ExecCommandRequestEvent;
import pro.gravit.launcher.request.Request;
import pro.gravit.launcher.request.websockets.WebSocketRequest;
public class ExecCommandRequest extends Request<ExecCommandRequestEvent> implements WebSocketRequest {
@LauncherAPI
public final String cmd;
public ExecCommandRequest(String cmd) {

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.request.auth;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.events.request.AuthRequestEvent;
import pro.gravit.launcher.hwid.HWID;
@ -46,7 +45,7 @@ public enum ConnectTypes {
PROXY
}
@LauncherAPI
public AuthRequest(String login, byte[] password, HWID hwid) {
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
this.password = new AuthECPassword(password.clone());
@ -57,7 +56,7 @@ public AuthRequest(String login, byte[] password, HWID hwid) {
authType = ConnectTypes.CLIENT;
}
@LauncherAPI
public AuthRequest(String login, byte[] password, HWID hwid, String auth_id) {
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
this.password = new AuthECPassword(password.clone());
@ -68,7 +67,7 @@ public AuthRequest(String login, byte[] password, HWID hwid, String auth_id) {
authType = ConnectTypes.CLIENT;
}
@LauncherAPI
public AuthRequest(String login, byte[] password, HWID hwid, String customText, String auth_id) {
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
this.password = new AuthECPassword(password.clone());

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.request.auth;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.events.request.CheckServerRequestEvent;
import pro.gravit.launcher.request.Request;
@ -13,7 +12,7 @@ public final class CheckServerRequest extends Request<CheckServerRequestEvent> i
@LauncherNetworkAPI
private final String serverID;
@LauncherAPI
public CheckServerRequest(String username, String serverID) {
this.username = VerifyHelper.verifyUsername(username);
this.serverID = VerifyHelper.verifyServerID(serverID);

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.request.auth;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.events.request.JoinServerRequestEvent;
import pro.gravit.launcher.request.Request;
@ -17,7 +16,7 @@ public final class JoinServerRequest extends Request<JoinServerRequestEvent> imp
@LauncherNetworkAPI
private final String serverID;
@LauncherAPI
public JoinServerRequest(String username, String accessToken, String serverID) {
this.username = VerifyHelper.verifyUsername(username);
this.accessToken = accessToken;

View file

@ -1,7 +1,6 @@
package pro.gravit.launcher.request.update;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.events.request.LauncherRequestEvent;
import pro.gravit.launcher.request.Request;
@ -30,16 +29,16 @@ public final class LauncherRequest extends Request<LauncherRequestEvent> impleme
public final String secureSalt;
@LauncherNetworkAPI
public int launcher_type = EXE_BINARY ? 2 : 1;
@LauncherAPI
public static final Path BINARY_PATH = IOHelper.getCodeSource(Launcher.class);
@LauncherAPI
public static final Path C_BINARY_PATH = BINARY_PATH.getParent().resolve(IOHelper.getFileName(BINARY_PATH) + ".tmp");
@LauncherAPI
public static final boolean EXE_BINARY = IOHelper.hasExtension(BINARY_PATH, "exe");
@LauncherAPI
public static void update(LauncherRequestEvent result) throws IOException {
List<String> args = new ArrayList<>(8);
args.add(IOHelper.resolveJavaBin(null).toString());
@ -90,7 +89,6 @@ public LauncherRequestEvent requestDo(StandartClientWebSocketService service) th
return result;
}
@LauncherAPI
public LauncherRequest() {
Path launcherPath = IOHelper.getCodeSource(LauncherRequest.class);
try {

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.request.uuid;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.events.request.BatchProfileByUsernameRequestEvent;
import pro.gravit.launcher.request.Request;
@ -22,7 +21,7 @@ static class Entry {
@LauncherNetworkAPI
private final Entry[] list;
@LauncherAPI
public BatchProfileByUsernameRequest(String... usernames) throws IOException {
this.list = new Entry[usernames.length];
for (int i = 0; i < usernames.length; ++i) {

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.request.uuid;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.events.request.ProfileByUUIDRequestEvent;
import pro.gravit.launcher.request.Request;
@ -13,7 +12,7 @@ public final class ProfileByUUIDRequest extends Request<ProfileByUUIDRequestEven
@LauncherNetworkAPI
private final UUID uuid;
@LauncherAPI
public ProfileByUUIDRequest(UUID uuid) {
this.uuid = Objects.requireNonNull(uuid, "uuid");
}

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.request.uuid;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.events.request.ProfileByUsernameRequestEvent;
import pro.gravit.launcher.request.Request;
@ -11,7 +10,7 @@ public final class ProfileByUsernameRequest extends Request<ProfileByUsernameReq
@LauncherNetworkAPI
private final String username;
@LauncherAPI
public ProfileByUsernameRequest(String username) {
this.username = VerifyHelper.verifyUsername(username);
}

View file

@ -1,21 +1,19 @@
package com.mojang.authlib.yggdrasil;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.profiles.PlayerProfile;
import pro.gravit.launcher.request.auth.CheckServerRequest;
import pro.gravit.launcher.request.auth.JoinServerRequest;
import pro.gravit.launcher.request.uuid.BatchProfileByUsernameRequest;
import pro.gravit.launcher.request.uuid.ProfileByUUIDRequest;
import pro.gravit.launcher.request.uuid.ProfileByUsernameRequest;
import pro.gravit.launcher.serialize.SerializeLimits;
import pro.gravit.utils.helper.LogHelper;
import java.util.UUID;
// Used to bypass Launcher's class name obfuscation and access API
@LauncherAPI
public class CompatBridge {
public static final int PROFILES_MAX_BATCH_SIZE = SerializeLimits.MAX_BATCH_SIZE;
public static final int PROFILES_MAX_BATCH_SIZE = 128;
public static CompatProfile checkServer(String username, String serverID) throws Exception {
LogHelper.debug("CompatBridge.checkServer, Username: '%s', Server ID: %s", username, serverID);

View file

@ -1,13 +1,12 @@
package com.mojang.authlib.yggdrasil;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.profiles.PlayerProfile;
import pro.gravit.utils.helper.SecurityHelper;
import java.util.UUID;
@LauncherAPI
public class CompatProfile {
public static final String SKIN_URL_PROPERTY = Launcher.SKIN_URL_PROPERTY;
public static final String SKIN_DIGEST_PROPERTY = Launcher.SKIN_DIGEST_PROPERTY;

View file

@ -1,6 +1,5 @@
package com.mojang.authlib.yggdrasil;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.request.auth.CheckServerRequest;
import pro.gravit.launcher.request.auth.JoinServerRequest;
import pro.gravit.utils.helper.CommonHelper;
@ -8,7 +7,7 @@
import pro.gravit.utils.helper.LogHelper;
// Used by 1.6.4 and below versions
@LauncherAPI
public class LegacyBridge {
public static boolean checkServer(String username, String serverID) throws Exception {
LogHelper.debug("LegacyBridge.checkServer, Username: '%s', Server ID: %s", username, serverID);

View file

@ -6,7 +6,6 @@
import com.mojang.authlib.ProfileLookupCallback;
import pro.gravit.launcher.profiles.PlayerProfile;
import pro.gravit.launcher.request.uuid.BatchProfileByUsernameRequest;
import pro.gravit.launcher.serialize.SerializeLimits;
import pro.gravit.utils.helper.LogHelper;
import pro.gravit.utils.helper.VerifyHelper;
@ -37,8 +36,8 @@ public YggdrasilGameProfileRepository() {
public void findProfilesByNames(String[] usernames, Agent agent, ProfileLookupCallback callback) {
int offset = 0;
while (offset < usernames.length) {
String[] sliceUsernames = Arrays.copyOfRange(usernames, offset, Math.min(offset + SerializeLimits.MAX_BATCH_SIZE, usernames.length));
offset += SerializeLimits.MAX_BATCH_SIZE;
String[] sliceUsernames = Arrays.copyOfRange(usernames, offset, Math.min(offset + 128, usernames.length));
offset += 128;
// Batch Username-To-UUID request
PlayerProfile[] sliceProfiles;

View file

@ -1,14 +0,0 @@
package pro.gravit.launcher;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This annotation implies that method/field/class should not be renamed or obfuscated
*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface LauncherAPI {
}

View file

@ -1,7 +1,5 @@
package pro.gravit.launcher.hasher;
import pro.gravit.launcher.LauncherAPI;
import java.util.Collection;
public final class FileNameMatcher {
@ -36,7 +34,7 @@ private static boolean anyMatch(String[] entries, Collection<String> path) {
private final String[] exclusions;
@LauncherAPI
public FileNameMatcher(String[] update, String[] verify, String[] exclusions) {
this.update = update;
this.verify = verify;

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.hasher;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.HOutput;
@ -19,9 +18,9 @@
public final class HashedDir extends HashedEntry {
public static final class Diff {
@LauncherAPI
public final HashedDir mismatch;
@LauncherAPI
public final HashedDir extra;
private Diff(HashedDir mismatch, HashedDir extra) {
@ -29,7 +28,7 @@ private Diff(HashedDir mismatch, HashedDir extra) {
this.extra = extra;
}
@LauncherAPI
public boolean isSame() {
return mismatch.isEmpty() && extra.isEmpty();
}
@ -105,11 +104,11 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
@LauncherNetworkAPI
private final Map<String, HashedEntry> map = new HashMap<>(32);
@LauncherAPI
public HashedDir() {
}
@LauncherAPI
public HashedDir(HInput input) throws IOException {
int entriesCount = input.readLength(0);
for (int i = 0; i < entriesCount; i++) {
@ -134,19 +133,19 @@ public HashedDir(HInput input) throws IOException {
}
}
@LauncherAPI
public HashedDir(Path dir, FileNameMatcher matcher, boolean allowSymlinks, boolean digest) throws IOException {
IOHelper.walk(dir, new HashFileVisitor(dir, matcher, allowSymlinks, digest), true);
}
@LauncherAPI
public Diff diff(HashedDir other, FileNameMatcher matcher) {
HashedDir mismatch = sideDiff(other, matcher, new LinkedList<>(), true);
HashedDir extra = other.sideDiff(this, matcher, new LinkedList<>(), false);
return new Diff(mismatch, extra);
}
@LauncherAPI
public Diff compare(HashedDir other, FileNameMatcher matcher) {
HashedDir mismatch = sideDiff(other, matcher, new LinkedList<>(), true);
HashedDir extra = other.sideDiff(this, matcher, new LinkedList<>(), false);
@ -190,7 +189,7 @@ public void removeR(String name) {
}
}
@LauncherAPI
public HashedEntry getEntry(String name) {
return map.get(name);
}
@ -200,17 +199,17 @@ public Type getType() {
return Type.DIR;
}
@LauncherAPI
public boolean isEmpty() {
return map.isEmpty();
}
@LauncherAPI
public Map<String, HashedEntry> map() {
return Collections.unmodifiableMap(map);
}
@LauncherAPI
public HashedEntry resolve(Iterable<String> path) {
HashedEntry current = this;
for (String pathEntry : path) {

View file

@ -1,6 +1,6 @@
package pro.gravit.launcher.hasher;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.stream.EnumSerializer;
import pro.gravit.launcher.serialize.stream.StreamObject;
@ -8,7 +8,7 @@
import java.io.IOException;
public abstract class HashedEntry extends StreamObject {
@LauncherAPI
public enum Type implements EnumSerializer.Itf {
DIR(1), FILE(2);
private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class);
@ -29,12 +29,12 @@ public int getNumber() {
}
}
@LauncherAPI
@LauncherNetworkAPI
public boolean flag; // For external usage
@LauncherAPI
public abstract Type getType();
@LauncherAPI
public abstract long size();
}

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.hasher;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.HOutput;
@ -17,23 +16,23 @@ public final class HashedFile extends HashedEntry {
public static final DigestAlgorithm DIGEST_ALGO = DigestAlgorithm.MD5;
// Instance
@LauncherAPI
@LauncherNetworkAPI
public final long size;
@LauncherNetworkAPI
private final byte[] digest;
@LauncherAPI
public HashedFile(HInput input) throws IOException {
this(input.readVarLong(), input.readBoolean() ? input.readByteArray(-DIGEST_ALGO.bytes) : null);
}
@LauncherAPI
public HashedFile(long size, byte[] digest) {
this.size = VerifyHelper.verifyLong(size, VerifyHelper.L_NOT_NEGATIVE, "Illegal size: " + size);
this.digest = digest == null ? null : DIGEST_ALGO.verify(digest).clone();
}
@LauncherAPI
public HashedFile(Path file, long size, boolean digest) throws IOException {
this(size, digest ? SecurityHelper.digest(DIGEST_ALGO, file) : null);
}
@ -43,12 +42,12 @@ public Type getType() {
return Type.FILE;
}
@LauncherAPI
public boolean isSame(HashedFile o) {
return size == o.size && (digest == null || o.digest == null || Arrays.equals(digest, o.digest));
}
@LauncherAPI
public boolean isSame(Path file, boolean digest) throws IOException {
if (size != IOHelper.readAttributes(file).size())
return false;
@ -60,7 +59,7 @@ public boolean isSame(Path file, boolean digest) throws IOException {
return Arrays.equals(this.digest, actualDigest);
}
@LauncherAPI
public boolean isSameDigest(byte[] digest) {
return this.digest == null || digest == null || Arrays.equals(this.digest, digest);
}

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.serialize;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.utils.helper.IOHelper;
import java.io.ByteArrayInputStream;
@ -12,15 +11,15 @@
import java.util.UUID;
public final class HInput implements AutoCloseable {
@LauncherAPI
public final InputStream stream;
@LauncherAPI
public HInput(byte[] bytes) {
stream = new ByteArrayInputStream(bytes);
}
@LauncherAPI
public HInput(InputStream stream) {
this.stream = Objects.requireNonNull(stream, "stream");
}
@ -30,17 +29,17 @@ public void close() throws IOException {
stream.close();
}
@LauncherAPI
public String readASCII(int maxBytes) throws IOException {
return IOHelper.decodeASCII(readByteArray(maxBytes));
}
@LauncherAPI
public BigInteger readBigInteger(int maxBytes) throws IOException {
return new BigInteger(readByteArray(maxBytes));
}
@LauncherAPI
public boolean readBoolean() throws IOException {
int b = readUnsignedByte();
switch (b) {
@ -53,41 +52,41 @@ public boolean readBoolean() throws IOException {
}
}
@LauncherAPI
public byte[] readByteArray(int max) throws IOException {
byte[] bytes = new byte[readLength(max)];
IOHelper.read(stream, bytes);
return bytes;
}
@LauncherAPI
public int readInt() throws IOException {
return (readUnsignedByte() << 24) + (readUnsignedByte() << 16) + (readUnsignedByte() << 8) + readUnsignedByte();
}
@LauncherAPI
public int readLength(int max) throws IOException {
if (max < 0)
return -max;
return IOHelper.verifyLength(readVarInt(), max);
}
@LauncherAPI
public long readLong() throws IOException {
return (long) readInt() << 32 | readInt() & 0xFFFFFFFFL;
}
@LauncherAPI
public short readShort() throws IOException {
return (short) ((readUnsignedByte() << 8) + readUnsignedByte());
}
@LauncherAPI
public String readString(int maxBytes) throws IOException {
return IOHelper.decode(readByteArray(maxBytes));
}
@LauncherAPI
public int readUnsignedByte() throws IOException {
int b = stream.read();
if (b < 0)
@ -95,17 +94,17 @@ public int readUnsignedByte() throws IOException {
return b;
}
@LauncherAPI
public int readUnsignedShort() throws IOException {
return Short.toUnsignedInt(readShort());
}
@LauncherAPI
public UUID readUUID() throws IOException {
return new UUID(readLong(), readLong());
}
@LauncherAPI
public int readVarInt() throws IOException {
int shift = 0;
int result = 0;
@ -119,7 +118,7 @@ public int readVarInt() throws IOException {
throw new IOException("VarInt too big");
}
@LauncherAPI
public long readVarLong() throws IOException {
int shift = 0;
long result = 0;

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.serialize;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.utils.helper.IOHelper;
import java.io.Flushable;
@ -11,10 +10,10 @@
import java.util.UUID;
public final class HOutput implements AutoCloseable, Flushable {
@LauncherAPI
public final OutputStream stream;
@LauncherAPI
public HOutput(OutputStream stream) {
this.stream = Objects.requireNonNull(stream, "stream");
}
@ -29,28 +28,28 @@ public void flush() throws IOException {
stream.flush();
}
@LauncherAPI
public void writeASCII(String s, int maxBytes) throws IOException {
writeByteArray(IOHelper.encodeASCII(s), maxBytes);
}
@LauncherAPI
public void writeBigInteger(BigInteger bi, int max) throws IOException {
writeByteArray(bi.toByteArray(), max);
}
@LauncherAPI
public void writeBoolean(boolean b) throws IOException {
writeUnsignedByte(b ? 0b1 : 0b0);
}
@LauncherAPI
public void writeByteArray(byte[] bytes, int max) throws IOException {
writeLength(bytes.length, max);
stream.write(bytes);
}
@LauncherAPI
public void writeInt(int i) throws IOException {
writeUnsignedByte(i >>> 24 & 0xFF);
writeUnsignedByte(i >>> 16 & 0xFF);
@ -58,42 +57,42 @@ public void writeInt(int i) throws IOException {
writeUnsignedByte(i & 0xFF);
}
@LauncherAPI
public void writeLength(int length, int max) throws IOException {
IOHelper.verifyLength(length, max);
if (max >= 0)
writeVarInt(length);
}
@LauncherAPI
public void writeLong(long l) throws IOException {
writeInt((int) (l >> 32));
writeInt((int) l);
}
@LauncherAPI
public void writeShort(short s) throws IOException {
writeUnsignedByte(s >>> 8 & 0xFF);
writeUnsignedByte(s & 0xFF);
}
@LauncherAPI
public void writeString(String s, int maxBytes) throws IOException {
writeByteArray(IOHelper.encode(s), maxBytes);
}
@LauncherAPI
public void writeUnsignedByte(int b) throws IOException {
stream.write(b);
}
@LauncherAPI
public void writeUUID(UUID uuid) throws IOException {
writeLong(uuid.getMostSignificantBits());
writeLong(uuid.getLeastSignificantBits());
}
@LauncherAPI
public void writeVarInt(int i) throws IOException {
while ((i & ~0x7FL) != 0) {
writeUnsignedByte(i & 0x7F | 0x80);
@ -102,7 +101,7 @@ public void writeVarInt(int i) throws IOException {
writeUnsignedByte(i);
}
@LauncherAPI
public void writeVarLong(long l) throws IOException {
while ((l & ~0x7FL) != 0) {
writeUnsignedByte((int) l & 0x7F | 0x80);

View file

@ -1,12 +1,10 @@
package pro.gravit.launcher.serialize;
import pro.gravit.launcher.LauncherAPI;
public class SerializeLimits {
@LauncherAPI
public static final int MAX_BATCH_SIZE = 128;
@LauncherAPI
public static final byte EXPECTED_BYTE = 0b01010101;
@LauncherAPI
public static final int MAX_DIGEST = 512;
}

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.serialize.signed;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.HOutput;
import pro.gravit.launcher.serialize.stream.StreamObject;
@ -14,7 +13,7 @@ public class DigestBytesHolder extends StreamObject {
protected final byte[] bytes;
private final byte[] digest;
@LauncherAPI
public DigestBytesHolder(byte[] bytes, byte[] digest, SecurityHelper.DigestAlgorithm algorithm) throws SignatureException {
if (Arrays.equals(SecurityHelper.digest(algorithm, bytes), digest))
throw new SignatureException("Invalid digest");
@ -22,23 +21,23 @@ public DigestBytesHolder(byte[] bytes, byte[] digest, SecurityHelper.DigestAlgor
this.digest = digest.clone();
}
@LauncherAPI
public DigestBytesHolder(byte[] bytes, SecurityHelper.DigestAlgorithm algorithm) {
this.bytes = bytes.clone();
this.digest = SecurityHelper.digest(algorithm, bytes);
}
@LauncherAPI
public DigestBytesHolder(HInput input, SecurityHelper.DigestAlgorithm algorithm) throws IOException, SignatureException {
this(input.readByteArray(0), input.readByteArray(-SecurityHelper.RSA_KEY_LENGTH), algorithm);
}
@LauncherAPI
public final byte[] getBytes() {
return bytes.clone();
}
@LauncherAPI
public final byte[] getDigest() {
return digest.clone();
}

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.serialize.stream;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.HOutput;
import pro.gravit.launcher.serialize.stream.EnumSerializer.Itf;
@ -13,24 +12,24 @@
public final class EnumSerializer<E extends Enum<?> & Itf> {
@FunctionalInterface
public interface Itf {
@LauncherAPI
int getNumber();
}
@LauncherAPI
public static void write(HOutput output, Itf itf) throws IOException {
output.writeVarInt(itf.getNumber());
}
private final Map<Integer, E> map = new HashMap<>(16);
@LauncherAPI
public EnumSerializer(Class<E> clazz) {
for (E e : clazz.getEnumConstants())
VerifyHelper.putIfAbsent(map, e.getNumber(), e, "Duplicate number for enum constant " + e.name());
}
@LauncherAPI
public E read(HInput input) throws IOException {
int n = input.readVarInt();
return VerifyHelper.getMapValue(map, n, "Unknown enum number: " + n);

View file

@ -1,6 +1,5 @@
package pro.gravit.launcher.serialize.stream;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.HOutput;
import pro.gravit.utils.helper.IOHelper;
@ -13,11 +12,11 @@ public abstract class StreamObject {
@FunctionalInterface
public interface Adapter<O extends StreamObject> {
@LauncherAPI
O convert(HInput input);
}
@LauncherAPI
public final byte[] write() throws IOException {
try (ByteArrayOutputStream array = IOHelper.newByteArrayOutput()) {
try (HOutput output = new HOutput(array)) {
@ -27,6 +26,6 @@ public final byte[] write() throws IOException {
}
}
@LauncherAPI
public abstract void write(HOutput output) throws IOException;
}

View file

@ -1,19 +1,9 @@
package pro.gravit.utils;
import pro.gravit.launcher.LauncherAPI;
import java.net.URL;
import java.net.URLClassLoader;
public class PublicURLClassLoader extends URLClassLoader {
@LauncherAPI
public static ClassLoader systemclassloader = ClassLoader.getSystemClassLoader();
public String nativePath;
@LauncherAPI
public static ClassLoader getSystemClassLoader() {
return systemclassloader;
}
/**
* Constructs a new URLClassLoader for the specified URLs using the
@ -64,11 +54,6 @@ public PublicURLClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}
@Override
public String findLibrary(String name) {
return nativePath.concat(name);
}
@Override
public void addURL(URL url) {
super.addURL(url);

View file

@ -1,19 +1,17 @@
package pro.gravit.utils;
import pro.gravit.launcher.LauncherAPI;
import java.util.*;
public final class Version {
@LauncherAPI
public final int major;
@LauncherAPI
public final int minor;
@LauncherAPI
public final int patch;
@LauncherAPI
public final int build;
@LauncherAPI
public final Type release;
public static final int MAJOR = 5;
public static final int MINOR = 1;
@ -21,7 +19,7 @@ public final class Version {
public static final int BUILD = 1;
public static final Version.Type RELEASE = Type.DEV;
@LauncherAPI
public Version(int major, int minor, int patch) {
this.major = major;
this.minor = minor;
@ -30,7 +28,7 @@ public Version(int major, int minor, int patch) {
release = Type.UNKNOWN;
}
@LauncherAPI
public Version(int major, int minor, int patch, int build) {
this.major = major;
this.minor = minor;
@ -39,7 +37,7 @@ public Version(int major, int minor, int patch, int build) {
release = Type.UNKNOWN;
}
@LauncherAPI
public Version(int major, int minor, int patch, int build, Type release) {
this.major = major;
this.minor = minor;
@ -53,7 +51,7 @@ public static Version getVersion() {
}
@Override
@LauncherAPI
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@ -64,30 +62,30 @@ public boolean equals(Object o) {
build == that.build;
}
@LauncherAPI
public String getVersionString() {
return String.format("%d.%d.%d", major, minor, patch);
}
@Override
@LauncherAPI
public int hashCode() {
return Objects.hash(major, minor, patch, build);
}
@LauncherAPI
public String getReleaseStatus() {
if (release.equals(Type.UNKNOWN)) return "";
return release.name().toLowerCase(Locale.ENGLISH);
}
@Override
@LauncherAPI
public String toString() {
return String.format("%d.%d.%d-%d %s", major, minor, patch, build, getReleaseStatus());
}
@LauncherAPI
public enum Type {
LTS,
STABLE,

View file

@ -1,7 +1,6 @@
package pro.gravit.utils.helper;
import com.google.gson.*;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.utils.command.CommandException;
import javax.script.ScriptEngine;
@ -16,9 +15,9 @@
import java.util.regex.Pattern;
public final class CommonHelper {
@LauncherAPI
public static final ScriptEngineManager scriptManager = new ScriptEngineManager();
@LauncherAPI
public static final ScriptEngineFactory nashornFactory = getEngineFactories(scriptManager);
private static ScriptEngineFactory getEngineFactories(ScriptEngineManager manager) {
@ -28,19 +27,19 @@ private static ScriptEngineFactory getEngineFactories(ScriptEngineManager manage
return null;
}
@LauncherAPI
public static String low(String s) {
return s.toLowerCase(Locale.US);
}
@LauncherAPI
public static boolean multiMatches(Pattern[] pattern, String from) {
for (Pattern p : pattern)
if (p.matcher(from).matches()) return true;
return false;
}
@LauncherAPI
public static String multiReplace(Pattern[] pattern, String from, String replace) {
Matcher m;
String tmp = null;
@ -51,12 +50,12 @@ public static String multiReplace(Pattern[] pattern, String from, String replace
return tmp != null ? tmp : from;
}
@LauncherAPI
public static ScriptEngine newScriptEngine() {
return nashornFactory.getScriptEngine();
}
@LauncherAPI
public static Thread newThread(String name, boolean daemon, Runnable runnable) {
Thread thread = new Thread(runnable);
thread.setDaemon(daemon);
@ -65,7 +64,7 @@ public static Thread newThread(String name, boolean daemon, Runnable runnable) {
return thread;
}
@LauncherAPI
public static String replace(String source, String... params) {
for (int i = 0; i < params.length; i += 2)
source = source.replace('%' + params[i] + '%', params[i + 1]);
@ -124,7 +123,7 @@ public static String[] parseCommand(CharSequence line) throws CommandException {
return result.toArray(new String[0]);
}
@LauncherAPI
public static GsonBuilder newBuilder() {
return new GsonBuilder().registerTypeHierarchyAdapter(byte[].class,
ByteArrayToBase64TypeAdapter.INSTANCE);

View file

@ -1,7 +1,5 @@
package pro.gravit.utils.helper;
import pro.gravit.launcher.LauncherAPI;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import java.awt.image.BufferedImage;
@ -77,42 +75,42 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOExce
}
// Charset
@LauncherAPI
public static final Charset UNICODE_CHARSET = StandardCharsets.UTF_8;
@LauncherAPI
public static final Charset ASCII_CHARSET = StandardCharsets.US_ASCII;
// Constants
@LauncherAPI
public static final int SOCKET_TIMEOUT = VerifyHelper.verifyInt(
Integer.parseUnsignedInt(System.getProperty("launcher.socketTimeout", Integer.toString(30000))),
VerifyHelper.POSITIVE, "launcher.socketTimeout can't be <= 0");
@LauncherAPI
public static final int HTTP_TIMEOUT = VerifyHelper.verifyInt(
Integer.parseUnsignedInt(System.getProperty("launcher.httpTimeout", Integer.toString(5000))),
VerifyHelper.POSITIVE, "launcher.httpTimeout can't be <= 0");
@LauncherAPI
public static final int BUFFER_SIZE = VerifyHelper.verifyInt(
Integer.parseUnsignedInt(System.getProperty("launcher.bufferSize", Integer.toString(4096))),
VerifyHelper.POSITIVE, "launcher.bufferSize can't be <= 0");
// Platform-dependent
@LauncherAPI
public static final String CROSS_SEPARATOR = "/";
@LauncherAPI
public static final FileSystem FS = FileSystems.getDefault();
@LauncherAPI
public static final String PLATFORM_SEPARATOR = FS.getSeparator();
// Увидел исключение на NetBSD beta добавил
@LauncherAPI
public static final boolean POSIX = FS.supportedFileAttributeViews().contains("posix") || FS.supportedFileAttributeViews().contains("Posix");
// Paths
@LauncherAPI
public static final Path JVM_DIR = Paths.get(System.getProperty("java.home"));
@LauncherAPI
public static final Path HOME_DIR = Paths.get(System.getProperty("user.home"));
@LauncherAPI
public static final Path WORKING_DIR = Paths.get(System.getProperty("user.dir"));
// Open options - as arrays
private static final OpenOption[] READ_OPTIONS = {StandardOpenOption.READ};
@ -131,7 +129,7 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOExce
private static final Pattern PLATFORM_SEPARATOR_PATTERN = Pattern.compile(PLATFORM_SEPARATOR, Pattern.LITERAL);
public static final String USER_AGENT = System.getProperty("launcher.userAgentDefault", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
@LauncherAPI
public static void close(AutoCloseable closeable) {
try {
closeable.close();
@ -140,7 +138,7 @@ public static void close(AutoCloseable closeable) {
}
}
@LauncherAPI
public static void close(InputStream in) {
try {
in.close();
@ -148,7 +146,7 @@ public static void close(InputStream in) {
}
}
@LauncherAPI
public static void close(OutputStream out) {
try {
out.flush();
@ -157,7 +155,7 @@ public static void close(OutputStream out) {
}
}
@LauncherAPI
public static URL convertToURL(String url) {
try {
return new URL(url);
@ -166,70 +164,70 @@ public static URL convertToURL(String url) {
}
}
@LauncherAPI
public static void copy(Path source, Path target) throws IOException {
createParentDirs(target);
Files.copy(source, target, COPY_OPTIONS);
}
@LauncherAPI
public static void createParentDirs(Path path) throws IOException {
Path parent = path.getParent();
if (parent != null && !isDir(parent))
Files.createDirectories(parent);
}
@LauncherAPI
public static String decode(byte[] bytes) {
return new String(bytes, UNICODE_CHARSET);
}
@LauncherAPI
public static String decodeASCII(byte[] bytes) {
return new String(bytes, ASCII_CHARSET);
}
@LauncherAPI
public static void deleteDir(Path dir, boolean self) throws IOException {
walk(dir, new DeleteDirVisitor(dir, self), true);
}
@LauncherAPI
public static byte[] encode(String s) {
return s.getBytes(UNICODE_CHARSET);
}
@LauncherAPI
public static byte[] encodeASCII(String s) {
return s.getBytes(ASCII_CHARSET);
}
@LauncherAPI
public static boolean exists(Path path) {
return Files.exists(path, LINK_OPTIONS);
}
@LauncherAPI
public static Path getCodeSource(Class<?> clazz) {
return Paths.get(toURI(clazz.getProtectionDomain().getCodeSource().getLocation()));
}
@LauncherAPI
public static String getFileName(Path path) {
return path.getFileName().toString();
}
@LauncherAPI
public static String getIP(SocketAddress address) {
return ((InetSocketAddress) address).getAddress().getHostAddress();
}
@LauncherAPI
public static byte[] getResourceBytes(String name) throws IOException {
return read(getResourceURL(name));
}
@LauncherAPI
public static URL getResourceURL(String name) throws NoSuchFileException {
URL url = IOHelper.class.getResource('/' + name);
if (url == null)
@ -237,35 +235,35 @@ public static URL getResourceURL(String name) throws NoSuchFileException {
return url;
}
@LauncherAPI
public static boolean hasExtension(Path file, String extension) {
return getFileName(file).endsWith('.' + extension);
}
@LauncherAPI
public static boolean isDir(Path path) {
return Files.isDirectory(path, LINK_OPTIONS);
}
@LauncherAPI
public static boolean isEmpty(Path dir) throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
return !stream.iterator().hasNext();
}
}
@LauncherAPI
public static boolean isFile(Path path) {
return Files.isRegularFile(path, LINK_OPTIONS);
}
@LauncherAPI
public static boolean isValidFileName(String fileName) {
return !fileName.equals(".") && !fileName.equals("..") &&
fileName.chars().noneMatch(ch -> ch == '/' || ch == '\\') && isValidPath(fileName);
}
@LauncherAPI
public static boolean isValidPath(String path) {
try {
toPath(path);
@ -275,34 +273,34 @@ public static boolean isValidPath(String path) {
}
}
@LauncherAPI
public static boolean isValidTextureBounds(int width, int height, boolean cloak) {
return width % 64 == 0 && (height << 1 == width || !cloak && height == width) && width <= 1024 ||
cloak && width % 22 == 0 && height % 17 == 0 && width / 22 == height / 17;
}
@LauncherAPI
public static void move(Path source, Path target) throws IOException {
createParentDirs(target);
Files.move(source, target, COPY_OPTIONS);
}
@LauncherAPI
public static byte[] newBuffer() {
return new byte[BUFFER_SIZE];
}
@LauncherAPI
public static ByteArrayOutputStream newByteArrayOutput() {
return new ByteArrayOutputStream();
}
@LauncherAPI
public static char[] newCharBuffer() {
return new char[BUFFER_SIZE];
}
@LauncherAPI
public static URLConnection newConnection(URL url) throws IOException {
URLConnection connection = url.openConnection();
if (connection instanceof HttpURLConnection) {
@ -316,7 +314,7 @@ public static URLConnection newConnection(URL url) throws IOException {
return connection;
}
@LauncherAPI
public static HttpURLConnection newConnectionPost(URL url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) newConnection(url);
connection.setDoOutput(true);
@ -324,138 +322,138 @@ public static HttpURLConnection newConnectionPost(URL url) throws IOException {
return connection;
}
@LauncherAPI
public static Deflater newDeflater() {
Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
deflater.setStrategy(Deflater.DEFAULT_STRATEGY);
return deflater;
}
@LauncherAPI
public static Inflater newInflater() {
return new Inflater(true);
}
@LauncherAPI
public static InputStream newInput(Path file) throws IOException {
return Files.newInputStream(file, READ_OPTIONS);
}
@LauncherAPI
public static InputStream newBufferedInput(Path file) throws IOException {
return new BufferedInputStream(Files.newInputStream(file, READ_OPTIONS));
}
@LauncherAPI
public static InputStream newInput(URL url) throws IOException {
return newConnection(url).getInputStream();
}
@LauncherAPI
public static BufferedInputStream newBufferedInput(URL url) throws IOException {
return new BufferedInputStream(newConnection(url).getInputStream());
}
@LauncherAPI
public static OutputStream newOutput(Path file) throws IOException {
return newOutput(file, false);
}
@LauncherAPI
public static OutputStream newBufferedOutput(Path file) throws IOException {
return newBufferedOutput(file, false);
}
@LauncherAPI
public static OutputStream newOutput(Path file, boolean append) throws IOException {
createParentDirs(file);
return Files.newOutputStream(file, append ? APPEND_OPTIONS : WRITE_OPTIONS);
}
@LauncherAPI
public static OutputStream newBufferedOutput(Path file, boolean append) throws IOException {
createParentDirs(file);
return new BufferedOutputStream(Files.newOutputStream(file, append ? APPEND_OPTIONS : WRITE_OPTIONS));
}
@LauncherAPI
public static BufferedReader newReader(InputStream input) {
return newReader(input, UNICODE_CHARSET);
}
@LauncherAPI
public static BufferedReader newReader(InputStream input, Charset charset) {
return new BufferedReader(new InputStreamReader(input, charset));
}
@LauncherAPI
public static BufferedReader newReader(Path file) throws IOException {
return Files.newBufferedReader(file, UNICODE_CHARSET);
}
@LauncherAPI
public static BufferedReader newReader(URL url) throws IOException {
URLConnection connection = newConnection(url);
String charset = connection.getContentEncoding();
return newReader(connection.getInputStream(), charset == null ? UNICODE_CHARSET : Charset.forName(charset));
}
@LauncherAPI
public static Socket newSocket() throws SocketException {
Socket socket = new Socket();
setSocketFlags(socket);
return socket;
}
@LauncherAPI
public static BufferedWriter newWriter(FileDescriptor fd) {
return newWriter(new FileOutputStream(fd));
}
@LauncherAPI
public static BufferedWriter newWriter(OutputStream output) {
return new BufferedWriter(new OutputStreamWriter(output, UNICODE_CHARSET));
}
@LauncherAPI
public static BufferedWriter newWriter(Path file) throws IOException {
return newWriter(file, false);
}
@LauncherAPI
public static BufferedWriter newWriter(Path file, boolean append) throws IOException {
createParentDirs(file);
return Files.newBufferedWriter(file, UNICODE_CHARSET, append ? APPEND_OPTIONS : WRITE_OPTIONS);
}
@LauncherAPI
public static ZipEntry newZipEntry(String name) {
ZipEntry entry = new ZipEntry(name);
entry.setTime(0);
return entry;
}
@LauncherAPI
public static ZipEntry newZipEntry(ZipEntry entry) {
return newZipEntry(entry.getName());
}
@LauncherAPI
public static ZipInputStream newZipInput(InputStream input) {
return new ZipInputStream(input, UNICODE_CHARSET);
}
@LauncherAPI
public static ZipInputStream newZipInput(Path file) throws IOException {
return newZipInput(newInput(file));
}
@LauncherAPI
public static ZipInputStream newZipInput(URL url) throws IOException {
return newZipInput(newInput(url));
}
@LauncherAPI
public static byte[] read(InputStream input) throws IOException {
try (ByteArrayOutputStream output = newByteArrayOutput()) {
transfer(input, output);
@ -463,7 +461,7 @@ public static byte[] read(InputStream input) throws IOException {
}
}
@LauncherAPI
public static void read(InputStream input, byte[] bytes) throws IOException {
int offset = 0;
while (offset < bytes.length) {
@ -474,7 +472,7 @@ public static void read(InputStream input, byte[] bytes) throws IOException {
}
}
@LauncherAPI
public static byte[] read(Path file) throws IOException {
long size = readAttributes(file).size();
if (size > Integer.MAX_VALUE)
@ -490,19 +488,19 @@ public static byte[] read(Path file) throws IOException {
return bytes;
}
@LauncherAPI
public static byte[] read(URL url) throws IOException {
try (InputStream input = newInput(url)) {
return read(input);
}
}
@LauncherAPI
public static BasicFileAttributes readAttributes(Path path) throws IOException {
return Files.readAttributes(path, BasicFileAttributes.class, LINK_OPTIONS);
}
@LauncherAPI
public static BufferedImage readTexture(Object input, boolean cloak) throws IOException {
ImageReader reader = ImageIO.getImageReadersByMIMEType("image/png").next();
try {
@ -521,19 +519,19 @@ public static BufferedImage readTexture(Object input, boolean cloak) throws IOEx
}
}
@LauncherAPI
public static String request(URL url) throws IOException {
return decode(read(url)).trim();
}
@LauncherAPI
public static InetSocketAddress resolve(InetSocketAddress address) {
if (address.isUnresolved())
return new InetSocketAddress(address.getHostString(), address.getPort());
return address;
}
@LauncherAPI
public static Path resolveIncremental(Path dir, String name, String extension) {
Path original = dir.resolve(name + '.' + extension);
if (!exists(original))
@ -551,7 +549,7 @@ public static Path resolveIncremental(Path dir, String name, String extension) {
}
}
@LauncherAPI
public static Path resolveJavaBin(Path javaDir) {
// Get Java binaries path
Path javaBinDir = (javaDir == null ? JVM_DIR : javaDir).resolve("bin");
@ -577,7 +575,7 @@ public static Path resolveJavaBin(Path javaDir) {
throw new RuntimeException("Java binary wasn't found");
}
@LauncherAPI
public static void setSocketFlags(Socket socket) throws SocketException {
// Set socket flags
socket.setKeepAlive(false);
@ -594,34 +592,34 @@ public static void setSocketFlags(Socket socket) throws SocketException {
socket.setPerformancePreferences(1, 0, 2);
}
@LauncherAPI
public static String toAbsPathString(Path path) {
return toAbsPath(path).toFile().getAbsolutePath();
}
@LauncherAPI
public static Path toAbsPath(Path path) {
return path.normalize().toAbsolutePath();
}
@LauncherAPI
public static byte[] toByteArray(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(in.available());
IOHelper.transfer(in, out);
return out.toByteArray();
}
@LauncherAPI
public static Path toPath(String path) {
return Paths.get(CROSS_SEPARATOR_PATTERN.matcher(path).replaceAll(Matcher.quoteReplacement(PLATFORM_SEPARATOR)));
}
@LauncherAPI
public static String toString(Path path) {
return PLATFORM_SEPARATOR_PATTERN.matcher(path.toString()).replaceAll(Matcher.quoteReplacement(CROSS_SEPARATOR));
}
@LauncherAPI
public static URI toURI(URL url) {
try {
return url.toURI();
@ -630,7 +628,7 @@ public static URI toURI(URL url) {
}
}
@LauncherAPI
public static URL toURL(Path path) {
try {
return path.toUri().toURL();
@ -639,14 +637,14 @@ public static URL toURL(Path path) {
}
}
@LauncherAPI
public static void transfer(byte[] write, Path file, boolean append) throws IOException {
try (OutputStream out = newOutput(file, append)) {
out.write(write);
}
}
@LauncherAPI
public static long transfer(InputStream input, OutputStream output) throws IOException {
long transferred = 0;
byte[] buffer = newBuffer();
@ -657,26 +655,26 @@ public static long transfer(InputStream input, OutputStream output) throws IOExc
return transferred;
}
@LauncherAPI
public static long transfer(InputStream input, Path file) throws IOException {
return transfer(input, file, false);
}
@LauncherAPI
public static long transfer(InputStream input, Path file, boolean append) throws IOException {
try (OutputStream output = newOutput(file, append)) {
return transfer(input, output);
}
}
@LauncherAPI
public static void transfer(Path file, OutputStream output) throws IOException {
try (InputStream input = newInput(file)) {
transfer(input, output);
}
}
@LauncherAPI
public static String urlDecode(String s) {
try {
return URLDecoder.decode(s, UNICODE_CHARSET.name());
@ -685,7 +683,7 @@ public static String urlDecode(String s) {
}
}
@LauncherAPI
public static String urlEncode(String s) {
try {
return URLEncoder.encode(s, UNICODE_CHARSET.name());
@ -694,25 +692,25 @@ public static String urlEncode(String s) {
}
}
@LauncherAPI
public static String verifyFileName(String fileName) {
return VerifyHelper.verify(fileName, IOHelper::isValidFileName, String.format("Invalid file name: '%s'", fileName));
}
@LauncherAPI
public static int verifyLength(int length, int max) throws IOException {
if (length < 0 || max < 0 && length != -max || max > 0 && length > max)
throw new IOException("Illegal length: " + length);
return length;
}
@LauncherAPI
public static BufferedImage verifyTexture(BufferedImage skin, boolean cloak) {
return VerifyHelper.verify(skin, i -> isValidTextureBounds(i.getWidth(), i.getHeight(), cloak),
String.format("Invalid texture bounds: %dx%d", skin.getWidth(), skin.getHeight()));
}
@LauncherAPI
public static String verifyURL(String url) {
try {
new URL(url).toURI();
@ -722,12 +720,12 @@ public static String verifyURL(String url) {
}
}
@LauncherAPI
public static void walk(Path dir, FileVisitor<Path> visitor, boolean hidden) throws IOException {
Files.walkFileTree(dir, WALK_OPTIONS, Integer.MAX_VALUE, hidden ? visitor : new SkipHiddenVisitor(visitor));
}
@LauncherAPI
public static void write(Path file, byte[] bytes) throws IOException {
createParentDirs(file);
Files.write(file, bytes, WRITE_OPTIONS);

View file

@ -1,7 +1,5 @@
package pro.gravit.utils.helper;
import pro.gravit.launcher.LauncherAPI;
import java.io.File;
import java.lang.invoke.MethodHandles;
import java.lang.management.ManagementFactory;
@ -16,7 +14,7 @@
import java.util.Map;
public final class JVMHelper {
@LauncherAPI
public enum OS {
MUSTDIE("mustdie"), LINUX("linux"), MACOSX("macosx");
@ -43,16 +41,16 @@ public static OS byName(String name) {
public static final OperatingSystemMXBean OPERATING_SYSTEM_MXBEAN =
ManagementFactory.getOperatingSystemMXBean();
// System properties
@LauncherAPI
public static final OS OS_TYPE = OS.byName(OPERATING_SYSTEM_MXBEAN.getName());
@LauncherAPI
public static final String OS_VERSION = OPERATING_SYSTEM_MXBEAN.getVersion();
@LauncherAPI
public static final int OS_BITS = getCorrectOSArch();
@LauncherAPI
public static final int JVM_BITS = Integer.parseInt(System.getProperty("sun.arch.data.model"));
@LauncherAPI
public static final SecurityManager SECURITY_MANAGER = System.getSecurityManager();
// Public static fields
public static final Runtime RUNTIME = Runtime.getRuntime();
@ -93,7 +91,7 @@ public static Class<?> firstClass(String... names) throws ClassNotFoundException
throw new ClassNotFoundException(Arrays.toString(names));
}
@LauncherAPI
public static void fullGC() {
RUNTIME.gc();
RUNTIME.runFinalization();
@ -146,27 +144,27 @@ private static int getCorrectOSArch() {
return System.getProperty("os.arch").contains("64") ? 64 : 32;
}
@LauncherAPI
public static String getEnvPropertyCaseSensitive(String name) {
return System.getenv().get(name);
}
@LauncherAPI
public static boolean isJVMMatchesSystemArch() {
return JVM_BITS == OS_BITS;
}
@LauncherAPI
public static String jvmProperty(String name, String value) {
return String.format("-D%s=%s", name, value);
}
@LauncherAPI
public static String systemToJvmProperty(String name) {
return String.format("-D%s=%s", name, System.getProperties().getProperty(name));
}
@LauncherAPI
public static void addSystemPropertyToArgs(Collection<String> args, String name) {
String property = System.getProperty(name);
if (property != null)

View file

@ -3,7 +3,6 @@
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.AnsiConsole;
import org.fusesource.jansi.AnsiOutputStream;
import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI;
import java.io.*;
@ -20,15 +19,15 @@
import java.util.function.Supplier;
public final class LogHelper {
@LauncherAPI
public static final String DEBUG_PROPERTY = "launcher.debug";
@LauncherAPI
public static final String DEV_PROPERTY = "launcher.dev";
@LauncherAPI
public static final String STACKTRACE_PROPERTY = "launcher.stacktrace";
@LauncherAPI
public static final String NO_JANSI_PROPERTY = "launcher.noJAnsi";
@LauncherAPI
public static final boolean JANSI;
// Output settings
@ -63,22 +62,22 @@ public enum OutputTypes {
private LogHelper() {
}
@LauncherAPI
public static void addOutput(OutputEnity output) {
OUTPUTS.add(Objects.requireNonNull(output, "output"));
}
@LauncherAPI
public static void addExcCallback(Consumer<Throwable> output) {
EXCEPTIONS_CALLBACKS.add(Objects.requireNonNull(output, "output"));
}
@LauncherAPI
public static void addOutput(Output output, OutputTypes type) {
OUTPUTS.add(new OutputEnity(Objects.requireNonNull(output, "output"), type));
}
@LauncherAPI
public static void addOutput(Path file) throws IOException {
if (JANSI) {
addOutput(new JAnsiOutput(IOHelper.newOutput(file, true)), OutputTypes.JANSI);
@ -87,89 +86,89 @@ public static void addOutput(Path file) throws IOException {
}
}
@LauncherAPI
public static void addOutput(Writer writer) {
addOutput(new WriterOutput(writer), OutputTypes.PLAIN);
}
@LauncherAPI
public static void debug(String message) {
if (isDebugEnabled()) {
log(Level.DEBUG, message, false);
}
}
@LauncherAPI
public static void dev(String message) {
if (isDevEnabled()) {
log(Level.DEV, message, false);
}
}
@LauncherAPI
public static void debug(String format, Object... args) {
debug(String.format(format, args));
}
@LauncherAPI
public static void dev(String format, Object... args) {
if (isDevEnabled()) {
dev(String.format(format, args));
}
}
@LauncherAPI
public static void error(Throwable exc) {
EXCEPTIONS_CALLBACKS.forEach(e -> e.accept(exc));
error(isStacktraceEnabled() ? toString(exc) : exc.toString());
}
@LauncherAPI
public static void error(String message) {
log(Level.ERROR, message, false);
}
@LauncherAPI
public static void error(String format, Object... args) {
error(String.format(format, args));
}
@LauncherAPI
public static void info(String message) {
log(Level.INFO, message, false);
}
@LauncherAPI
public static void info(String format, Object... args) {
info(String.format(format, args));
}
@LauncherAPI
public static boolean isDebugEnabled() {
return DEBUG_ENABLED.get();
}
@LauncherAPI
public static void setDebugEnabled(boolean debugEnabled) {
DEBUG_ENABLED.set(debugEnabled);
}
@LauncherAPI
public static boolean isStacktraceEnabled() {
return STACKTRACE_ENABLED.get();
}
@LauncherAPI
public static boolean isDevEnabled() {
return DEV_ENABLED.get();
}
@LauncherAPI
public static void setStacktraceEnabled(boolean stacktraceEnabled) {
STACKTRACE_ENABLED.set(stacktraceEnabled);
}
@LauncherAPI
public static void setDevEnabled(boolean stacktraceEnabled) {
DEV_ENABLED.set(stacktraceEnabled);
}
@ -178,7 +177,7 @@ public static String getDataTime() {
return DATE_TIME_FORMATTER.format(LocalDateTime.now());
}
@LauncherAPI
public static void log(Level level, String message, boolean sub) {
String dateTime = DATE_TIME_FORMATTER.format(LocalDateTime.now());
String jansiString = null, plainString = null, htmlString = null;
@ -211,12 +210,12 @@ public static void log(Level level, String message, boolean sub) {
}
}
@LauncherAPI
public static void rawLog(Supplier<String> plainStr, Supplier<String> jansiStr) {
rawLog(plainStr, jansiStr, null);
}
@LauncherAPI
public static void rawLog(Supplier<String> plainStr, Supplier<String> jansiStr, Supplier<String> htmlStr) {
String jansiString = null, plainString = null, htmlString = null;
for (OutputEnity output : OUTPUTS) {
@ -248,7 +247,7 @@ public static void rawLog(Supplier<String> plainStr, Supplier<String> jansiStr,
}
}
@LauncherAPI
public static void printVersion(String product) {
String jansiString = null, plainString = null;
for (OutputEnity output : OUTPUTS) {
@ -272,7 +271,7 @@ public static void printVersion(String product) {
}
}
@LauncherAPI
public static void printLicense(String product) {
String jansiString = null, plainString = null;
for (OutputEnity output : OUTPUTS) {
@ -296,61 +295,61 @@ public static void printLicense(String product) {
}
}
@LauncherAPI
public static boolean removeOutput(OutputEnity output) {
return OUTPUTS.remove(output);
}
@LauncherAPI
public static boolean removeStdOutput() {
return removeOutput(STD_OUTPUT);
}
@LauncherAPI
public static void subDebug(String message) {
if (isDebugEnabled()) {
log(Level.DEBUG, message, true);
}
}
@LauncherAPI
public static void subDebug(String format, Object... args) {
subDebug(String.format(format, args));
}
@LauncherAPI
public static void subInfo(String message) {
log(Level.INFO, message, true);
}
@LauncherAPI
public static void subInfo(String format, Object... args) {
subInfo(String.format(format, args));
}
@LauncherAPI
public static void subWarning(String message) {
log(Level.WARNING, message, true);
}
@LauncherAPI
public static void subWarning(String format, Object... args) {
subWarning(String.format(format, args));
}
@LauncherAPI
public static String toString(Throwable exc) {
StringWriter sw = new StringWriter();
exc.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
@LauncherAPI
public static void warning(String message) {
log(Level.WARNING, message, false);
}
@LauncherAPI
public static void warning(String format, Object... args) {
warning(String.format(format, args));
}
@ -425,13 +424,13 @@ private static String formatLog(Level level, String message, String dateTime, bo
}
}
@LauncherAPI
@FunctionalInterface
public interface Output {
void println(String message);
}
@LauncherAPI
public enum Level {
DEV("DEV"), DEBUG("DEBUG"), INFO("INFO"), WARNING("WARN"), ERROR("ERROR");
public final String name;

View file

@ -1,7 +1,5 @@
package pro.gravit.utils.helper;
import pro.gravit.launcher.LauncherAPI;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
@ -266,12 +264,12 @@ public static byte[] randomBytes(Random random, int length) {
return bytes;
}
@LauncherAPI
public static String randomStringToken() {
return randomStringToken(newRandom());
}
@LauncherAPI
public static String randomStringToken(Random random) {
return toHex(randomToken(random));
}

View file

@ -1,7 +1,5 @@
package pro.gravit.utils.helper;
import pro.gravit.launcher.LauncherAPI;
import java.util.Map;
import java.util.Objects;
import java.util.function.DoublePredicate;
@ -11,95 +9,95 @@
import java.util.regex.Pattern;
public final class VerifyHelper {
@LauncherAPI
public static final IntPredicate POSITIVE = i -> i > 0;
@LauncherAPI
public static final IntPredicate NOT_NEGATIVE = i -> i >= 0;
@LauncherAPI
public static final LongPredicate L_POSITIVE = l -> l > 0;
@LauncherAPI
public static final LongPredicate L_NOT_NEGATIVE = l -> l >= 0;
@LauncherAPI
public static final Predicate<String> NOT_EMPTY = s -> !s.isEmpty();
@LauncherAPI
public static final Pattern USERNAME_PATTERN = Pattern.compile(Boolean.parseBoolean(System.getProperty("username.russian", "true")) ? "[a-zA-Zа-яА-Я0-9_.\\-]{1,16}" : "[a-zA-Z0-9-_\\\\.]{1,16}");
private static final Pattern SERVERID_PATTERN = Pattern.compile("-?[0-9a-f]{1,40}");
@LauncherAPI
public static <K, V> V getMapValue(Map<K, V> map, K key, String error) {
return verify(map.get(key), Objects::nonNull, error);
}
@LauncherAPI
public static boolean isValidIDName(String name) {
return !name.isEmpty() && name.length() <= 255 && name.chars().allMatch(VerifyHelper::isValidIDNameChar);
}
@LauncherAPI
public static boolean isValidIDNameChar(int ch) {
return ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9' || ch == '-' || ch == '_';
}
@LauncherAPI
public static boolean isValidServerID(CharSequence serverID) {
return SERVERID_PATTERN.matcher(serverID).matches();
}
@LauncherAPI
public static boolean isValidUsername(CharSequence username) {
return USERNAME_PATTERN.matcher(username).matches();
}
@LauncherAPI
public static <K, V> void putIfAbsent(Map<K, V> map, K key, V value, String error) {
verify(map.putIfAbsent(key, value), Objects::isNull, error);
}
@LauncherAPI
public static IntPredicate range(int min, int max) {
return i -> i >= min && i <= max;
}
@LauncherAPI
public static <T> T verify(T object, Predicate<T> predicate, String error) {
if (predicate.test(object))
return object;
throw new IllegalArgumentException(error);
}
@LauncherAPI
public static double verifyDouble(double d, DoublePredicate predicate, String error) {
if (predicate.test(d))
return d;
throw new IllegalArgumentException(error);
}
@LauncherAPI
public static String verifyIDName(String name) {
return verify(name, VerifyHelper::isValidIDName, String.format("Invalid name: '%s'", name));
}
@LauncherAPI
public static int verifyInt(int i, IntPredicate predicate, String error) {
if (predicate.test(i))
return i;
throw new IllegalArgumentException(error);
}
@LauncherAPI
public static long verifyLong(long l, LongPredicate predicate, String error) {
if (predicate.test(l))
return l;
throw new IllegalArgumentException(error);
}
@LauncherAPI
public static String verifyServerID(String serverID) {
return verify(serverID, VerifyHelper::isValidServerID,
String.format("Invalid server ID: '%s'", serverID));
}
@LauncherAPI
public static String verifyUsername(String username) {
return verify(username, VerifyHelper::isValidUsername, String.format("Invalid username: '%s'", username));
}

@ -1 +1 @@
Subproject commit bf7994eb6358c6440cb84846918afbc118fa3dae
Subproject commit 9ee94152da6ae8e3ea045484f60b2a2246b4e993