IDEA Refractoring

This commit is contained in:
Gravit 2018-09-22 21:33:00 +07:00
parent 78766d0c5c
commit 8580cd4403
145 changed files with 1992 additions and 1860 deletions

View file

@ -166,6 +166,7 @@ public void verify() {
VerifyHelper.verify(getAddress(), VerifyHelper.NOT_EMPTY, "LaunchServer address can't be empty"); VerifyHelper.verify(getAddress(), VerifyHelper.NOT_EMPTY, "LaunchServer address can't be empty");
} }
} }
public static class ExeConf extends ConfigObject { public static class ExeConf extends ConfigObject {
public final boolean enabled; public final boolean enabled;
public String productName; public String productName;
@ -201,6 +202,7 @@ private ExeConf(BlockConfigEntry block) {
: String.format("%s, build %d", Launcher.getVersion().getVersionString(), Launcher.getVersion().build); : String.format("%s, build %d", Launcher.getVersion().getVersionString(), Launcher.getVersion().build);
} }
} }
private final class ProfilesFileVisitor extends SimpleFileVisitor<Path> { private final class ProfilesFileVisitor extends SimpleFileVisitor<Path> {
private final Collection<SignedObjectHolder<ClientProfile>> result; private final Collection<SignedObjectHolder<ClientProfile>> result;
@ -224,6 +226,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
return super.visitFile(file, attrs); return super.visitFile(file, attrs);
} }
} }
public static class SignConf extends ConfigObject { public static class SignConf extends ConfigObject {
public final boolean enabled; public final boolean enabled;
public String algo; public String algo;
@ -233,6 +236,7 @@ public static class SignConf extends ConfigObject {
public boolean hasPass; public boolean hasPass;
public String pass; public String pass;
public String keyalias; public String keyalias;
private SignConf(BlockConfigEntry block, Path coredir) { private SignConf(BlockConfigEntry block, Path coredir) {
super(block); super(block);
enabled = block.getEntryValue("enabled", BooleanConfigEntry.class); enabled = block.getEntryValue("enabled", BooleanConfigEntry.class);
@ -249,6 +253,7 @@ private SignConf(BlockConfigEntry block, Path coredir) {
} }
} }
} }
public static void main(String... args) throws Throwable { public static void main(String... args) throws Throwable {
JVMHelper.verifySystemProperties(LaunchServer.class, true); JVMHelper.verifySystemProperties(LaunchServer.class, true);
LogHelper.addOutput(IOHelper.WORKING_DIR.resolve("LaunchServer.log")); LogHelper.addOutput(IOHelper.WORKING_DIR.resolve("LaunchServer.log"));
@ -267,6 +272,7 @@ public static void main(String... args) throws Throwable {
Instant end = Instant.now(); Instant end = Instant.now();
LogHelper.debug("LaunchServer started in %dms", Duration.between(start, end).toMillis()); LogHelper.debug("LaunchServer started in %dms", Duration.between(start, end).toMillis());
} }
// Constant paths // Constant paths
@LauncherAPI @LauncherAPI
public final Path dir; public final Path dir;
@ -462,11 +468,7 @@ public void close() {
} catch (IOException e) { } catch (IOException e) {
LogHelper.error(e); LogHelper.error(e);
} }
try {
config.hwidHandler.close(); config.hwidHandler.close();
} catch (IOException e) {
LogHelper.error(e);
}
modulesManager.close(); modulesManager.close();
// Print last message before death :( // Print last message before death :(
LogHelper.info("LaunchServer stopped"); LogHelper.info("LaunchServer stopped");

View file

@ -10,24 +10,22 @@
import java.nio.file.Paths; import java.nio.file.Paths;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import ru.gravit.utils.helper.IOHelper; import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.JVMHelper;
import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.LogHelper;
import ru.gravit.utils.helper.SecurityHelper; import ru.gravit.utils.helper.SecurityHelper;
public class ProguardConf { public class ProguardConf {
private static final String charsFirst = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"; private static final String charsFirst = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
private static final String chars = "1aAbBcC2dDeEfF3gGhHiI4jJkKl5mMnNoO6pPqQrR7sStT8uUvV9wWxX0yYzZ"; private static final String chars = "1aAbBcC2dDeEfF3gGhHiI4jJkKl5mMnNoO6pPqQrR7sStT8uUvV9wWxX0yYzZ";
private static String generateString(SecureRandom rand, int il) { private static String generateString(SecureRandom rand, int il) {
StringBuilder sb = new StringBuilder(il); StringBuilder sb = new StringBuilder(il);
sb.append(charsFirst.charAt(rand.nextInt(charsFirst.length()))); sb.append(charsFirst.charAt(rand.nextInt(charsFirst.length())));
for (int i = 0; i < il - 1; i++) sb.append(chars.charAt(rand.nextInt(chars.length()))); for (int i = 0; i < il - 1; i++) sb.append(chars.charAt(rand.nextInt(chars.length())));
return sb.toString(); return sb.toString();
} }
private final LaunchServer srv;
public final Path proguard; public final Path proguard;
public final Path config; public final Path config;
public final Path mappings; public final Path mappings;
@ -35,14 +33,14 @@ private static String generateString(SecureRandom rand, int il) {
public final ArrayList<String> confStrs; public final ArrayList<String> confStrs;
public ProguardConf(LaunchServer srv) { public ProguardConf(LaunchServer srv) {
this.srv = srv; LaunchServer srv1 = srv;
proguard = this.srv.dir.resolve("proguard"); proguard = srv1.dir.resolve("proguard");
config = proguard.resolve("proguard.config"); config = proguard.resolve("proguard.config");
mappings = proguard.resolve("mappings.pro"); mappings = proguard.resolve("mappings.pro");
words = proguard.resolve("random.pro"); words = proguard.resolve("random.pro");
confStrs = new ArrayList<>(); confStrs = new ArrayList<>();
prepare(false); prepare(false);
if (this.srv.config.genMappings) confStrs.add("-printmapping \'" + mappings.toFile().getName() + "\'"); if (srv1.config.genMappings) confStrs.add("-printmapping \'" + mappings.toFile().getName() + "\'");
confStrs.add("-obfuscationdictionary \'" + words.toFile().getName() + "\'"); confStrs.add("-obfuscationdictionary \'" + words.toFile().getName() + "\'");
confStrs.add("-injar \'" + Paths.get(".").toAbsolutePath() + IOHelper.PLATFORM_SEPARATOR + srv.config.binaryName + ".jar\'"); confStrs.add("-injar \'" + Paths.get(".").toAbsolutePath() + IOHelper.PLATFORM_SEPARATOR + srv.config.binaryName + ".jar\'");
confStrs.add("-outjar \'" + Paths.get(".").toAbsolutePath() + IOHelper.PLATFORM_SEPARATOR + srv.config.binaryName + "-obf.jar\'"); confStrs.add("-outjar \'" + Paths.get(".").toAbsolutePath() + IOHelper.PLATFORM_SEPARATOR + srv.config.binaryName + "-obf.jar\'");

View file

@ -23,10 +23,12 @@ public StarterVisitor(Instrumentation inst) {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (file.toFile().getName().endsWith(".jar")) inst.appendToSystemClassLoaderSearch(new JarFile(file.toFile())); if (file.toFile().getName().endsWith(".jar"))
inst.appendToSystemClassLoaderSearch(new JarFile(file.toFile()));
return super.visitFile(file, attrs); return super.visitFile(file, attrs);
} }
} }
public static void premain(String agentArgument, Instrumentation inst) { public static void premain(String agentArgument, Instrumentation inst) {
try { try {
Files.walkFileTree(Paths.get("libraries"), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new StarterVisitor(inst)); Files.walkFileTree(Paths.get("libraries"), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new StarterVisitor(inst));

View file

@ -30,6 +30,7 @@ public boolean equals(Object obj) {
return false; return false;
return value == other.value; return value == other.value;
} }
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
@ -44,6 +45,7 @@ public String toString() {
return String.format("AuthEntry {value=%s, ts=%s}", value, ts); return String.format("AuthEntry {value=%s, ts=%s}", value, ts);
} }
} }
@LauncherAPI @LauncherAPI
public static final long TIMEOUT = 10 * 60 * 1000; //10 минут public static final long TIMEOUT = 10 * 60 * 1000; //10 минут
public final int rateLimit; public final int rateLimit;

View file

@ -45,7 +45,7 @@ public static void registerHandlers() {
registerHandler("binaryFile", BinaryFileAuthHandler::new); registerHandler("binaryFile", BinaryFileAuthHandler::new);
registerHandler("textFile", TextFileAuthHandler::new); registerHandler("textFile", TextFileAuthHandler::new);
registerHandler("mysql", MySQLAuthHandler::new); registerHandler("mysql", MySQLAuthHandler::new);
registerHandler("json",JsonAuthHandler::new); registerHandler("json", JsonAuthHandler::new);
registredHandl = true; registredHandl = true;
} }
} }

View file

@ -32,6 +32,7 @@ public Entry(UUID uuid, String username, String accessToken, String serverID) {
this.serverID = serverID == null ? null : VerifyHelper.verifyServerID(serverID); this.serverID = serverID == null ? null : VerifyHelper.verifyServerID(serverID);
} }
} }
private final Map<UUID, Entry> entryCache = new HashMap<>(1024); private final Map<UUID, Entry> entryCache = new HashMap<>(1024);
private final Map<String, UUID> usernamesCache = new HashMap<>(1024); private final Map<String, UUID> usernamesCache = new HashMap<>(1024);
@ -39,7 +40,8 @@ public Entry(UUID uuid, String username, String accessToken, String serverID) {
@LauncherAPI @LauncherAPI
protected CachedAuthHandler(BlockConfigEntry block) { protected CachedAuthHandler(BlockConfigEntry block) {
super(block); super(block);
if(block.hasEntry("garbage")) if(block.getEntryValue("garbage", BooleanConfigEntry.class)) GarbageManager.registerNeedGC(this); if (block.hasEntry("garbage"))
if (block.getEntryValue("garbage", BooleanConfigEntry.class)) GarbageManager.registerNeedGC(this);
} }
@LauncherAPI @LauncherAPI
@ -111,10 +113,11 @@ public synchronized boolean joinServer(String username, String accessToken, Stri
entry.serverID = serverID; entry.serverID = serverID;
return true; return true;
} }
public synchronized void garbageCollection()
{ public synchronized void garbageCollection() {
entryCache.clear(); entryCache.clear();
} }
@LauncherAPI @LauncherAPI
protected abstract boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException; protected abstract boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException;

View file

@ -103,6 +103,7 @@ public void write(HOutput output) throws IOException {
} }
} }
} }
@LauncherAPI @LauncherAPI
public final Path file; public final Path file;
@LauncherAPI @LauncherAPI

View file

@ -80,11 +80,12 @@ public UUID checkServer(String username, String serverID) throws IOException {
public void close() { public void close() {
} }
@Override @Override
public boolean joinServer(String username, String accessToken, String serverID) throws IOException { public boolean joinServer(String username, String accessToken, String serverID) throws IOException {
JsonObject request = Json.object().add(userKeyName, username).add(serverIDKeyName, serverID).add(accessTokenKeyName, accessToken); JsonObject request = Json.object().add(userKeyName, username).add(serverIDKeyName, serverID).add(accessTokenKeyName, accessToken);
HTTPRequest.jsonRequest(request, urlJoinServer); HTTPRequest.jsonRequest(request, urlJoinServer);
return request.getString(responseOKKeyName,null).equals("OK"); return request.getString(responseOKKeyName, null).equals("OK");
} }
@Override @Override
@ -107,8 +108,8 @@ public String uuidToUsername(UUID uuid) throws IOException {
throw new IOException("Service error"); throw new IOException("Service error");
} }
public JsonObject jsonRequestChecked(JsonObject object,URL url) throws IOException { public JsonObject jsonRequestChecked(JsonObject object, URL url) throws IOException {
JsonValue result = HTTPRequest.jsonRequest(object,url); JsonValue result = HTTPRequest.jsonRequest(object, url);
if (!result.isObject()) if (!result.isObject())
authError("Authentication server response is malformed"); authError("Authentication server response is malformed");

View file

@ -1,6 +1,5 @@
package ru.gravit.launchserver.auth.hwid; package ru.gravit.launchserver.auth.hwid;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;

View file

@ -9,9 +9,11 @@ public class HWID {
public static HWID fromData(HInput in) throws IOException { public static HWID fromData(HInput in) throws IOException {
return gen(in.readLong(), in.readLong(), in.readLong()); return gen(in.readLong(), in.readLong(), in.readLong());
} }
public static HWID gen(long hwid_hdd, long hwid_bios, long hwid_cpu) { public static HWID gen(long hwid_hdd, long hwid_bios, long hwid_cpu) {
return new HWID(hwid_hdd, hwid_bios, hwid_cpu); return new HWID(hwid_hdd, hwid_bios, hwid_cpu);
} }
private long hwid_bios; private long hwid_bios;
private long hwid_hdd; private long hwid_hdd;

View file

@ -29,17 +29,20 @@ public static void registerHandler(String name, Adapter<HWIDHandler> adapter) {
VerifyHelper.putIfAbsent(HW_HANDLERS, name, Objects.requireNonNull(adapter, "adapter"), VerifyHelper.putIfAbsent(HW_HANDLERS, name, Objects.requireNonNull(adapter, "adapter"),
String.format("HWID handler has been already registered: '%s'", name)); String.format("HWID handler has been already registered: '%s'", name));
} }
public static void registerHandlers() { public static void registerHandlers() {
if (!registredHandl) { if (!registredHandl) {
registerHandler("accept", AcceptHWIDHandler::new); registerHandler("accept", AcceptHWIDHandler::new);
registerHandler("mysql",MysqlHWIDHandler::new); registerHandler("mysql", MysqlHWIDHandler::new);
registerHandler("json",JsonHWIDHandler::new); registerHandler("json", JsonHWIDHandler::new);
registredHandl = true; registredHandl = true;
} }
} }
protected HWIDHandler(BlockConfigEntry block) { protected HWIDHandler(BlockConfigEntry block) {
super(block); super(block);
} }
public abstract void ban(List<HWID> hwid) throws HWIDException; public abstract void ban(List<HWID> hwid) throws HWIDException;
public void check(HWID hwid, String username) throws HWIDException { public void check(HWID hwid, String username) throws HWIDException {
@ -50,7 +53,7 @@ public void check(HWID hwid, String username) throws HWIDException {
public abstract void check0(HWID hwid, String username) throws HWIDException; public abstract void check0(HWID hwid, String username) throws HWIDException;
@Override @Override
public abstract void close() throws IOException; public abstract void close();
public abstract List<HWID> getHwid(String username) throws HWIDException; public abstract List<HWID> getHwid(String username) throws HWIDException;

View file

@ -58,16 +58,17 @@ public final class JsonHWIDHandler extends HWIDHandler {
@Override @Override
public void ban(List<HWID> l_hwid) throws HWIDException { public void ban(List<HWID> l_hwid) throws HWIDException {
for(HWID hwid : l_hwid) { for (HWID hwid : l_hwid) {
JsonObject request = Json.object().add(hddKeyName, hwid.getHwid_hdd()).add(cpuKeyName, hwid.getHwid_cpu()).add(biosKeyName, hwid.getHwid_bios()); JsonObject request = Json.object().add(hddKeyName, hwid.getHwid_hdd()).add(cpuKeyName, hwid.getHwid_cpu()).add(biosKeyName, hwid.getHwid_bios());
try { try {
request(request,urlBan); request(request, urlBan);
} catch (IOException e) { } catch (IOException e) {
LogHelper.error(e); LogHelper.error(e);
throw new HWIDException("HWID service error"); throw new HWIDException("HWID service error");
} }
} }
} }
public JsonObject request(JsonObject request, URL url) throws HWIDException, IOException { public JsonObject request(JsonObject request, URL url) throws HWIDException, IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true); connection.setDoInput(true);
@ -97,18 +98,19 @@ public JsonObject request(JsonObject request, URL url) throws HWIDException, IOE
JsonObject response = content.asObject(); JsonObject response = content.asObject();
return response; return response;
} }
@Override @Override
public void check0(HWID hwid, String username) throws HWIDException { public void check0(HWID hwid, String username) throws HWIDException {
JsonObject request = Json.object().add(loginKeyName,username).add(hddKeyName,hwid.getHwid_hdd()).add(cpuKeyName,hwid.getHwid_cpu()).add(biosKeyName,hwid.getHwid_bios()); JsonObject request = Json.object().add(loginKeyName, username).add(hddKeyName, hwid.getHwid_hdd()).add(cpuKeyName, hwid.getHwid_cpu()).add(biosKeyName, hwid.getHwid_bios());
JsonObject response; JsonObject response;
try { try {
response = request(request,url); response = request(request, url);
} catch (IOException e) { } catch (IOException e) {
LogHelper.error(e); LogHelper.error(e);
throw new HWIDException("HWID service error"); throw new HWIDException("HWID service error");
} }
boolean isBanned = response.getBoolean(isBannedKeyName,false); boolean isBanned = response.getBoolean(isBannedKeyName, false);
if(isBanned) throw new HWIDException("You will BANNED!"); if (isBanned) throw new HWIDException("You will BANNED!");
} }
@Override @Override
@ -118,24 +120,23 @@ public void close() {
@Override @Override
public List<HWID> getHwid(String username) throws HWIDException { public List<HWID> getHwid(String username) throws HWIDException {
JsonObject request = Json.object().add(loginKeyName,username); JsonObject request = Json.object().add(loginKeyName, username);
JsonObject responce; JsonObject responce;
try { try {
responce = request(request,urlGet); responce = request(request, urlGet);
} catch (IOException e) { } catch (IOException e) {
LogHelper.error(e); LogHelper.error(e);
throw new HWIDException("HWID service error"); throw new HWIDException("HWID service error");
} }
JsonArray array = responce.get("hwids").asArray(); JsonArray array = responce.get("hwids").asArray();
ArrayList<HWID> hwids = new ArrayList<>(); ArrayList<HWID> hwids = new ArrayList<>();
for(JsonValue i : array) for (JsonValue i : array) {
{ long hdd, cpu, bios;
long hdd,cpu,bios;
JsonObject object = i.asObject(); JsonObject object = i.asObject();
hdd = object.getLong(hddKeyName,0); hdd = object.getLong(hddKeyName, 0);
cpu = object.getLong(cpuKeyName,0); cpu = object.getLong(cpuKeyName, 0);
bios = object.getLong(biosKeyName,0); bios = object.getLong(biosKeyName, 0);
HWID hwid = HWID.gen(hdd,cpu,bios); HWID hwid = HWID.gen(hdd, cpu, bios);
hwids.add(hwid); hwids.add(hwid);
} }
return hwids; return hwids;
@ -143,10 +144,10 @@ public List<HWID> getHwid(String username) throws HWIDException {
@Override @Override
public void unban(List<HWID> l_hwid) throws HWIDException { public void unban(List<HWID> l_hwid) throws HWIDException {
for(HWID hwid : l_hwid) { for (HWID hwid : l_hwid) {
JsonObject request = Json.object().add(hddKeyName, hwid.getHwid_hdd()).add(cpuKeyName, hwid.getHwid_cpu()).add(biosKeyName, hwid.getHwid_bios()); JsonObject request = Json.object().add(hddKeyName, hwid.getHwid_hdd()).add(cpuKeyName, hwid.getHwid_cpu()).add(biosKeyName, hwid.getHwid_bios());
try { try {
request(request,urlUnBan); request(request, urlUnBan);
} catch (IOException e) { } catch (IOException e) {
LogHelper.error(e); LogHelper.error(e);
throw new HWIDException("HWID service error"); throw new HWIDException("HWID service error");

View file

@ -22,7 +22,7 @@ public class MysqlHWIDHandler extends HWIDHandler {
private final String banMessage; private final String banMessage;
private final String isBannedName; private final String isBannedName;
private final String loginName; private final String loginName;
private final String hddName,cpuName,biosName; private final String hddName, cpuName, biosName;
private final String[] queryParams; private final String[] queryParams;
private final String queryUpd; private final String queryUpd;
private final String[] queryParamsUpd; private final String[] queryParamsUpd;
@ -72,7 +72,7 @@ public void check0(HWID hwid, String username) throws HWIDException {
Connection c = mySQLHolder.getConnection(); Connection c = mySQLHolder.getConnection();
PreparedStatement s = c.prepareStatement(query); PreparedStatement s = c.prepareStatement(query);
String[] replaceParams = {"hwid_hdd", String.valueOf(hwid.getHwid_hdd()), "hwid_cpu", String.valueOf(hwid.getHwid_cpu()), "hwid_bios", String.valueOf(hwid.getHwid_bios()),"login",username}; String[] replaceParams = {"hwid_hdd", String.valueOf(hwid.getHwid_hdd()), "hwid_cpu", String.valueOf(hwid.getHwid_cpu()), "hwid_bios", String.valueOf(hwid.getHwid_bios()), "login", username};
for (int i = 0; i < queryParams.length; i++) { for (int i = 0; i < queryParams.length; i++) {
s.setString(i + 1, CommonHelper.replace(queryParams[i], replaceParams)); s.setString(i + 1, CommonHelper.replace(queryParams[i], replaceParams));
} }
@ -82,7 +82,7 @@ public void check0(HWID hwid, String username) throws HWIDException {
try (ResultSet set = s.executeQuery()) { try (ResultSet set = s.executeQuery()) {
boolean isOne = false; boolean isOne = false;
boolean needWrite = true; boolean needWrite = true;
while(set.next()) { while (set.next()) {
isOne = true; isOne = true;
boolean isBanned = set.getBoolean(isBannedName); boolean isBanned = set.getBoolean(isBannedName);
if (isBanned) throw new HWIDException(banMessage); if (isBanned) throw new HWIDException(banMessage);
@ -95,8 +95,7 @@ public void check0(HWID hwid, String username) throws HWIDException {
writeHWID(hwid, username, c); writeHWID(hwid, username, c);
return; return;
} }
if(needWrite) if (needWrite) {
{
writeHWID(hwid, username, c); writeHWID(hwid, username, c);
return; return;
} }
@ -105,9 +104,9 @@ public void check0(HWID hwid, String username) throws HWIDException {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void writeHWID(HWID hwid, String username, Connection c)
{ public void writeHWID(HWID hwid, String username, Connection c) {
LogHelper.debug("Write HWID %s from username %s",hwid.toString(),username); LogHelper.debug("Write HWID %s from username %s", hwid.toString(), username);
try (PreparedStatement a = c.prepareStatement(queryUpd)) { try (PreparedStatement a = c.prepareStatement(queryUpd)) {
//IF //IF
String[] replaceParamsUpd = {"hwid_hdd", String.valueOf(hwid.getHwid_hdd()), "hwid_cpu", String.valueOf(hwid.getHwid_cpu()), "hwid_bios", String.valueOf(hwid.getHwid_bios()), "login", username}; String[] replaceParamsUpd = {"hwid_hdd", String.valueOf(hwid.getHwid_hdd()), "hwid_cpu", String.valueOf(hwid.getHwid_cpu()), "hwid_bios", String.valueOf(hwid.getHwid_bios()), "login", username};
@ -120,9 +119,9 @@ public void writeHWID(HWID hwid, String username, Connection c)
e.printStackTrace(); e.printStackTrace();
} }
} }
public void setIsBanned(HWID hwid,boolean isBanned)
{ public void setIsBanned(HWID hwid, boolean isBanned) {
LogHelper.debug("%s Request HWID: %s",isBanned ? "Ban" : "UnBan",hwid.toString()); LogHelper.debug("%s Request HWID: %s", isBanned ? "Ban" : "UnBan", hwid.toString());
Connection c = null; Connection c = null;
try { try {
c = mySQLHolder.getConnection(); c = mySQLHolder.getConnection();
@ -141,36 +140,35 @@ public void setIsBanned(HWID hwid,boolean isBanned)
e.printStackTrace(); e.printStackTrace();
} }
} }
@Override
public void ban(List<HWID> list) throws HWIDException {
for(HWID hwid : list) @Override
{ public void ban(List<HWID> list) {
setIsBanned(hwid,true);
for (HWID hwid : list) {
setIsBanned(hwid, true);
} }
} }
@Override @Override
public void unban(List<HWID> list) throws HWIDException { public void unban(List<HWID> list) {
for(HWID hwid : list) for (HWID hwid : list) {
{ setIsBanned(hwid, false);
setIsBanned(hwid,false);
} }
} }
@Override @Override
public List<HWID> getHwid(String username) throws HWIDException { public List<HWID> getHwid(String username) {
try { try {
LogHelper.debug("Try find HWID from username %s",username); LogHelper.debug("Try find HWID from username %s", username);
Connection c = mySQLHolder.getConnection(); Connection c = mySQLHolder.getConnection();
PreparedStatement s = c.prepareStatement(querySelect); PreparedStatement s = c.prepareStatement(querySelect);
String[] replaceParams = {"login", username}; String[] replaceParams = {"login", username};
for (int i = 0; i < queryParamsSelect.length; i++) { for (int i = 0; i < queryParamsSelect.length; i++) {
s.setString(i + 1, CommonHelper.replace(queryParamsSelect[i], replaceParams)); s.setString(i + 1, CommonHelper.replace(queryParamsSelect[i], replaceParams));
} }
long hdd,cpu,bios; long hdd, cpu, bios;
try (ResultSet set = s.executeQuery()) { try (ResultSet set = s.executeQuery()) {
if(!set.next()) { if (!set.next()) {
LogHelper.error(new HWIDException("HWID not found")); LogHelper.error(new HWIDException("HWID not found"));
return new ArrayList<>(); return new ArrayList<>();
} }
@ -179,11 +177,12 @@ public List<HWID> getHwid(String username) throws HWIDException {
bios = set.getLong(biosName); bios = set.getLong(biosName);
} }
ArrayList<HWID> list = new ArrayList<>(); ArrayList<HWID> list = new ArrayList<>();
HWID hwid = HWID.gen(hdd,bios,cpu); HWID hwid = HWID.gen(hdd, bios, cpu);
if(hdd == 0 && cpu == 0 && bios == 0) {LogHelper.warning("Null HWID");} if (hdd == 0 && cpu == 0 && bios == 0) {
else { LogHelper.warning("Null HWID");
} else {
list.add(hwid); list.add(hwid);
LogHelper.debug("Username: %s HWID: %s",username,hwid.toString()); LogHelper.debug("Username: %s HWID: %s", username, hwid.toString());
} }
return list; return list;
} catch (SQLException e) { } catch (SQLException e) {

View file

@ -1,12 +1,7 @@
package ru.gravit.launchserver.auth.provider; package ru.gravit.launchserver.auth.provider;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import com.eclipsesource.json.Json; import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonObject; import com.eclipsesource.json.JsonObject;
@ -49,7 +44,7 @@ public final class JsonAuthProvider extends AuthProvider {
@Override @Override
public AuthProviderResult auth(String login, String password, String ip) throws IOException { public AuthProviderResult auth(String login, String password, String ip) throws IOException {
JsonObject request = Json.object().add(userKeyName, login).add(passKeyName, password).add(ipKeyName, ip); JsonObject request = Json.object().add(userKeyName, login).add(passKeyName, password).add(ipKeyName, ip);
JsonValue content = HTTPRequest.jsonRequest(request,url); JsonValue content = HTTPRequest.jsonRequest(request, url);
if (!content.isObject()) if (!content.isObject())
return authError("Authentication server response is malformed"); return authError("Authentication server response is malformed");

View file

@ -17,28 +17,31 @@ public BuildContext(ZipOutputStream output, JAConfigurator config) {
this.output = output; this.output = output;
this.config = config; this.config = config;
} }
public void pushFile(String filename,InputStream inputStream) throws IOException {
public void pushFile(String filename, InputStream inputStream) throws IOException {
ZipEntry zip = IOHelper.newZipEntry(filename); ZipEntry zip = IOHelper.newZipEntry(filename);
output.putNextEntry(zip); output.putNextEntry(zip);
IOHelper.transfer(inputStream,output); IOHelper.transfer(inputStream, output);
} }
public void pushJarFile(JarInputStream input) throws IOException { public void pushJarFile(JarInputStream input) throws IOException {
ZipEntry e = input.getNextEntry(); ZipEntry e = input.getNextEntry();
while (e != null) { while (e != null) {
output.putNextEntry(e); output.putNextEntry(e);
IOHelper.transfer(input,output); IOHelper.transfer(input, output);
e = input.getNextEntry(); e = input.getNextEntry();
} }
} }
public void pushJarFile(JarInputStream input, Set<String> blacklist) throws IOException { public void pushJarFile(JarInputStream input, Set<String> blacklist) throws IOException {
ZipEntry e = input.getNextEntry(); ZipEntry e = input.getNextEntry();
while (e != null) { while (e != null) {
if(blacklist.contains(e.getName())){ if (blacklist.contains(e.getName())) {
e = input.getNextEntry(); e = input.getNextEntry();
continue; continue;
} }
output.putNextEntry(e); output.putNextEntry(e);
IOHelper.transfer(input,output); IOHelper.transfer(input, output);
e = input.getNextEntry(); e = input.getNextEntry();
} }
} }

View file

@ -113,10 +113,11 @@ private void setConfig() {
// Return prepared config // Return prepared config
ConfigPersister.getInstance().setAntConfig(config, null); ConfigPersister.getInstance().setAntConfig(config, null);
} }
private static String VERSION = Launcher.getVersion().getVersionString(); private static String VERSION = Launcher.getVersion().getVersionString();
private static int BUILD = Launcher.getVersion().build; private static int BUILD = Launcher.getVersion().build;
public static String formatVars(String mask)
{ public static String formatVars(String mask) {
return String.format(mask, VERSION, BUILD); return String.format(mask, VERSION, BUILD);
} }
} }

View file

@ -13,6 +13,7 @@ public class JAConfigurator implements AutoCloseable {
StringBuilder body; StringBuilder body;
StringBuilder moduleBody; StringBuilder moduleBody;
int autoincrement; int autoincrement;
public JAConfigurator(Class<?> configclass) throws NotFoundException { public JAConfigurator(Class<?> configclass) throws NotFoundException {
classname = configclass.getName(); classname = configclass.getName();
ctClass = pool.get(classname); ctClass = pool.get(classname);
@ -22,8 +23,8 @@ public JAConfigurator(Class<?> configclass) throws NotFoundException {
moduleBody = new StringBuilder("{ isInitModules = true; "); moduleBody = new StringBuilder("{ isInitModules = true; ");
autoincrement = 0; autoincrement = 0;
} }
public void addModuleClass(String fullName)
{ public void addModuleClass(String fullName) {
moduleBody.append("ru.gravit.launcher.modules.Module mod"); moduleBody.append("ru.gravit.launcher.modules.Module mod");
moduleBody.append(autoincrement); moduleBody.append(autoincrement);
moduleBody.append(" = new "); moduleBody.append(" = new ");
@ -34,10 +35,12 @@ public void addModuleClass(String fullName)
moduleBody.append(" , true );"); moduleBody.append(" , true );");
autoincrement++; autoincrement++;
} }
@Override @Override
public void close() { public void close() {
ctClass.defrost(); ctClass.defrost();
} }
public byte[] getBytecode() throws IOException, CannotCompileException { public byte[] getBytecode() throws IOException, CannotCompileException {
body.append("}"); body.append("}");
moduleBody.append("}"); moduleBody.append("}");
@ -45,31 +48,30 @@ public byte[] getBytecode() throws IOException, CannotCompileException {
initModuleMethod.insertAfter(moduleBody.toString()); initModuleMethod.insertAfter(moduleBody.toString());
return ctClass.toBytecode(); return ctClass.toBytecode();
} }
public String getZipEntryPath()
{ public String getZipEntryPath() {
return classname.replace('.','/').concat(".class"); return classname.replace('.', '/').concat(".class");
} }
public void setAddress(String address)
{ public void setAddress(String address) {
body.append("this.address = \""); body.append("this.address = \"");
body.append(address); body.append(address);
body.append("\";"); body.append("\";");
} }
public void setProjectName(String name)
{ public void setProjectName(String name) {
body.append("this.projectname = \""); body.append("this.projectname = \"");
body.append(name); body.append(name);
body.append("\";"); body.append("\";");
} }
public void setPort(int port) public void setPort(int port) {
{
body.append("this.port = "); body.append("this.port = ");
body.append(port); body.append(port);
body.append(";"); body.append(";");
} }
public ClassPool getPool()
{ public ClassPool getPool() {
return pool; return pool;
} }
} }

View file

@ -22,6 +22,7 @@ protected LauncherBinary(LaunchServer server, Path binaryFile) {
this.binaryFile = binaryFile; this.binaryFile = binaryFile;
syncBinaryFile = binaryFile; syncBinaryFile = binaryFile;
} }
@LauncherAPI @LauncherAPI
protected LauncherBinary(LaunchServer server, Path binaryFile, Path syncBinaryFile) { protected LauncherBinary(LaunchServer server, Path binaryFile, Path syncBinaryFile) {
this.server = server; this.server = server;

View file

@ -59,7 +59,9 @@
* </pre> * </pre>
*/ */
public class SignerJar implements AutoCloseable { public class SignerJar implements AutoCloseable {
/** Helper output stream that also sends the data to the given {@link com.google.common.hash.Hasher}. */ /**
* Helper output stream that also sends the data to the given {@link com.google.common.hash.Hasher}.
*/
private static class HashingOutputStream extends OutputStream { private static class HashingOutputStream extends OutputStream {
private final OutputStream out; private final OutputStream out;
private final MessageDigest hasher; private final MessageDigest hasher;
@ -97,6 +99,7 @@ public void write(int b) throws IOException {
hasher.update((byte) b); hasher.update((byte) b);
} }
} }
private static final String MANIFEST_FN = "META-INF/MANIFEST.MF"; private static final String MANIFEST_FN = "META-INF/MANIFEST.MF";
private static final String SIG_FN = "META-INF/SIGNUMO.SF"; private static final String SIG_FN = "META-INF/SIGNUMO.SF";
@ -104,22 +107,24 @@ public void write(int b) throws IOException {
private static final String hashFunctionName = "SHA-256"; private static final String hashFunctionName = "SHA-256";
public static final KeyStore getStore(Path file, String storepass, String algo) throws IOException { public static KeyStore getStore(Path file, String storepass, String algo) throws IOException {
try { try {
KeyStore st = KeyStore.getInstance(algo); KeyStore st = KeyStore.getInstance(algo);
st.load(IOHelper.newInput(file), storepass != null ? storepass.toCharArray() : null); st.load(IOHelper.newInput(file), storepass != null ? storepass.toCharArray() : null);
return st; return st;
} catch (NoSuchAlgorithmException | CertificateException| KeyStoreException e) { } catch (NoSuchAlgorithmException | CertificateException | KeyStoreException e) {
throw new IOException(e); throw new IOException(e);
} }
} }
private final static MessageDigest hasher() {
private static MessageDigest hasher() {
try { try {
return MessageDigest.getInstance(hashFunctionName); return MessageDigest.getInstance(hashFunctionName);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
return null; return null;
} }
} }
private final ZipOutputStream zos; private final ZipOutputStream zos;
private final KeyStore keyStore; private final KeyStore keyStore;
@ -153,6 +158,7 @@ public SignerJar(OutputStream out, KeyStore keyStore, String keyAlias, String ke
fileDigests = new LinkedHashMap<>(); fileDigests = new LinkedHashMap<>();
sectionDigests = new LinkedHashMap<>(); sectionDigests = new LinkedHashMap<>();
} }
/** /**
* Adds a file to the JAR. The file is immediately added to the zipped output stream. This method cannot be called once * Adds a file to the JAR. The file is immediately added to the zipped output stream. This method cannot be called once
* the stream is closed. * the stream is closed.
@ -252,7 +258,9 @@ public void close() throws IOException {
zos.close(); zos.close();
} }
/** Creates the beast that can actually sign the data. */ /**
* Creates the beast that can actually sign the data.
*/
private CMSSignedDataGenerator createSignedDataGenerator() throws Exception { private CMSSignedDataGenerator createSignedDataGenerator() throws Exception {
Security.addProvider(new BouncyCastleProvider()); Security.addProvider(new BouncyCastleProvider());
@ -288,7 +296,9 @@ public ZipOutputStream getZos() {
return zos; return zos;
} }
/** Helper for {@link #writeManifest()} that creates the digest of one entry. */ /**
* Helper for {@link #writeManifest()} that creates the digest of one entry.
*/
private String hashEntrySection(String name, Attributes attributes) throws IOException { private String hashEntrySection(String name, Attributes attributes) throws IOException {
Manifest manifest = new Manifest(); Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
@ -304,7 +314,9 @@ private String hashEntrySection(String name, Attributes attributes) throws IOExc
return Base64.getEncoder().encodeToString(hasher().digest(ob)); return Base64.getEncoder().encodeToString(hasher().digest(ob));
} }
/** Helper for {@link #writeManifest()} that creates the digest of the main section. */ /**
* Helper for {@link #writeManifest()} that creates the digest of the main section.
*/
private String hashMainSection(Attributes attributes) throws IOException { private String hashMainSection(Attributes attributes) throws IOException {
Manifest manifest = new Manifest(); Manifest manifest = new Manifest();
manifest.getMainAttributes().putAll(attributes); manifest.getMainAttributes().putAll(attributes);
@ -314,22 +326,29 @@ private String hashMainSection(Attributes attributes) throws IOException {
public String toString() { public String toString() {
return "NullOutputStream"; return "NullOutputStream";
} }
/** Discards the specified byte array. */ /** Discards the specified byte array. */
@Override public void write(byte[] b) { @Override
public void write(byte[] b) {
} }
/** Discards the specified byte array. */ /** Discards the specified byte array. */
@Override public void write(byte[] b, int off, int len) { @Override
public void write(byte[] b, int off, int len) {
} }
/** Discards the specified byte. */ /** Discards the specified byte. */
@Override public void write(int b) { @Override
public void write(int b) {
} }
}, hasher); }, hasher);
manifest.write(o); manifest.write(o);
return Base64.getEncoder().encodeToString(hasher.digest()); return Base64.getEncoder().encodeToString(hasher.digest());
} }
/** Returns the CMS signed data. */ /**
* Returns the CMS signed data.
*/
private byte[] signSigFile(byte[] sigContents) throws Exception { private byte[] signSigFile(byte[] sigContents) throws Exception {
CMSSignedDataGenerator gen = createSignedDataGenerator(); CMSSignedDataGenerator gen = createSignedDataGenerator();
CMSTypedData cmsData = new CMSProcessableByteArray(sigContents); CMSTypedData cmsData = new CMSProcessableByteArray(sigContents);

View file

@ -23,7 +23,7 @@ public String getUsageDescription() {
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
verifyArgs(args,1); verifyArgs(args, 1);
List<HWID> target = server.config.hwidHandler.getHwid(args[0]); List<HWID> target = server.config.hwidHandler.getHwid(args[0]);
server.config.hwidHandler.ban(target); server.config.hwidHandler.ban(target);
} }

View file

@ -23,7 +23,7 @@ public String getUsageDescription() {
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
verifyArgs(args,1); verifyArgs(args, 1);
List<HWID> target = server.config.hwidHandler.getHwid(args[0]); List<HWID> target = server.config.hwidHandler.getHwid(args[0]);
server.config.hwidHandler.unban(target); server.config.hwidHandler.unban(target);
} }

View file

@ -3,16 +3,14 @@
import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.command.Command; import ru.gravit.launchserver.command.Command;
import ru.gravit.launchserver.socket.NettyServerSocketHandler; import ru.gravit.launchserver.socket.NettyServerSocketHandler;
import ru.gravit.utils.HttpDownloader;
import ru.gravit.utils.helper.LogHelper;
import java.net.URL;
public class TestCommand extends Command { public class TestCommand extends Command {
public TestCommand(LaunchServer server) { public TestCommand(LaunchServer server) {
super(server); super(server);
} }
NettyServerSocketHandler handler; NettyServerSocketHandler handler;
@Override @Override
public String getArgsDescription() { public String getArgsDescription() {
return null; return null;
@ -25,11 +23,10 @@ public String getUsageDescription() {
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
verifyArgs(args,1); verifyArgs(args, 1);
if(handler == null) if (handler == null)
handler = new NettyServerSocketHandler(server); handler = new NettyServerSocketHandler(server);
if(args[0].equals("start")) if (args[0].equals("start")) {
{
handler.run(); handler.run();
} }
} }

View file

@ -101,7 +101,7 @@ protected CommandHandler(LaunchServer server) {
registerCommand("logConnections", new LogConnectionsCommand(server)); registerCommand("logConnections", new LogConnectionsCommand(server));
registerCommand("loadModule", new LoadModuleCommand(server)); registerCommand("loadModule", new LoadModuleCommand(server));
registerCommand("modules", new ModulesCommand(server)); registerCommand("modules", new ModulesCommand(server));
registerCommand("test",new TestCommand(server)); registerCommand("test", new TestCommand(server));
// Register sync commands // Register sync commands
registerCommand("indexAsset", new IndexAssetCommand(server)); registerCommand("indexAsset", new IndexAssetCommand(server));

View file

@ -48,6 +48,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
return super.visitFile(file, attrs); return super.visitFile(file, attrs);
} }
} }
public static final String INDEXES_DIR = "indexes"; public static final String INDEXES_DIR = "indexes";
public static final String OBJECTS_DIR = "objects"; public static final String OBJECTS_DIR = "objects";

View file

@ -19,7 +19,7 @@ public String getUsageDescription() {
} }
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) {
server.modulesManager.printModules(); server.modulesManager.printModules();
} }
} }

View file

@ -17,6 +17,7 @@ public final class LaunchServerPluginBridge implements Runnable, AutoCloseable {
* Err text. * Err text.
*/ */
public static final String nonInitText = "Лаунчсервер не был полностью загружен"; public static final String nonInitText = "Лаунчсервер не был полностью загружен";
static { static {
//SecurityHelper.verifyCertificates(LaunchServer.class); //SecurityHelper.verifyCertificates(LaunchServer.class);
JVMHelper.verifySystemProperties(LaunchServer.class, false); JVMHelper.verifySystemProperties(LaunchServer.class, false);

View file

@ -12,20 +12,20 @@
public class BuildHookManager { public class BuildHookManager {
@FunctionalInterface @FunctionalInterface
public interface PostBuildHook public interface PostBuildHook {
{
void build(BuildContext context); void build(BuildContext context);
} }
@FunctionalInterface @FunctionalInterface
public interface PreBuildHook public interface PreBuildHook {
{
void build(BuildContext context); void build(BuildContext context);
} }
@FunctionalInterface @FunctionalInterface
public interface Transformer public interface Transformer {
{
byte[] transform(byte[] input, CharSequence classname); byte[] transform(byte[] input, CharSequence classname);
} }
private boolean BUILDRUNTIME; private boolean BUILDRUNTIME;
private final Set<PostBuildHook> POST_HOOKS; private final Set<PostBuildHook> POST_HOOKS;
private final Set<PreBuildHook> PRE_HOOKS; private final Set<PreBuildHook> PRE_HOOKS;
@ -33,6 +33,7 @@ public interface Transformer
private final Set<String> CLASS_BLACKLIST; private final Set<String> CLASS_BLACKLIST;
private final Set<String> MODULE_CLASS; private final Set<String> MODULE_CLASS;
private final Map<String, byte[]> INCLUDE_CLASS; private final Map<String, byte[]> INCLUDE_CLASS;
public BuildHookManager() { public BuildHookManager() {
POST_HOOKS = new HashSet<>(4); POST_HOOKS = new HashSet<>(4);
PRE_HOOKS = new HashSet<>(4); PRE_HOOKS = new HashSet<>(4);
@ -47,61 +48,65 @@ public BuildHookManager() {
registerIgnoredClass("META-INF/NOTICE"); registerIgnoredClass("META-INF/NOTICE");
registerClientModuleClass(TestClientModule.class.getName()); registerClientModuleClass(TestClientModule.class.getName());
} }
public void autoRegisterIgnoredClass(String clazz)
{ public void autoRegisterIgnoredClass(String clazz) {
CLASS_BLACKLIST.add(clazz.replace('.','/').concat(".class")); CLASS_BLACKLIST.add(clazz.replace('.', '/').concat(".class"));
} }
public boolean buildRuntime() { public boolean buildRuntime() {
return BUILDRUNTIME; return BUILDRUNTIME;
} }
public byte[] classTransform(byte[] clazz, CharSequence classname)
{ public byte[] classTransform(byte[] clazz, CharSequence classname) {
byte[] result = clazz; byte[] result = clazz;
for(Transformer transformer : CLASS_TRANSFORMER) result = transformer.transform(result,classname); for (Transformer transformer : CLASS_TRANSFORMER) result = transformer.transform(result, classname);
return result; return result;
} }
public void registerIncludeClass(String classname, byte[] classdata) { public void registerIncludeClass(String classname, byte[] classdata) {
INCLUDE_CLASS.put(classname, classdata); INCLUDE_CLASS.put(classname, classdata);
} }
public Map<String, byte[]> getIncludeClass() { public Map<String, byte[]> getIncludeClass() {
return INCLUDE_CLASS; return INCLUDE_CLASS;
} }
public boolean isContainsBlacklist(String clazz)
{ public boolean isContainsBlacklist(String clazz) {
return CLASS_BLACKLIST.contains(clazz); return CLASS_BLACKLIST.contains(clazz);
} }
public void postHook(BuildContext context)
{ public void postHook(BuildContext context) {
for(PostBuildHook hook : POST_HOOKS) hook.build(context); for (PostBuildHook hook : POST_HOOKS) hook.build(context);
} }
public void preHook(BuildContext context)
{ public void preHook(BuildContext context) {
for(PreBuildHook hook : PRE_HOOKS) hook.build(context); for (PreBuildHook hook : PRE_HOOKS) hook.build(context);
} }
public void registerAllClientModuleClass(JAConfigurator cfg)
{ public void registerAllClientModuleClass(JAConfigurator cfg) {
for(String clazz : MODULE_CLASS) cfg.addModuleClass(clazz); for (String clazz : MODULE_CLASS) cfg.addModuleClass(clazz);
} }
public void registerClassTransformer(Transformer transformer)
{ public void registerClassTransformer(Transformer transformer) {
CLASS_TRANSFORMER.add(transformer); CLASS_TRANSFORMER.add(transformer);
} }
public void registerClientModuleClass(String clazz)
{ public void registerClientModuleClass(String clazz) {
MODULE_CLASS.add(clazz); MODULE_CLASS.add(clazz);
} }
public void registerIgnoredClass(String clazz)
{ public void registerIgnoredClass(String clazz) {
CLASS_BLACKLIST.add(clazz); CLASS_BLACKLIST.add(clazz);
} }
public void registerPostHook(PostBuildHook hook)
{ public void registerPostHook(PostBuildHook hook) {
POST_HOOKS.add(hook); POST_HOOKS.add(hook);
} }
public void registerPreHook(PreBuildHook hook)
{ public void registerPreHook(PreBuildHook hook) {
PRE_HOOKS.add(hook); PRE_HOOKS.add(hook);
} }
public void setBuildRuntime(boolean runtime) { public void setBuildRuntime(boolean runtime) {
BUILDRUNTIME = runtime; BUILDRUNTIME = runtime;
} }

View file

@ -15,6 +15,7 @@ public ModulesManager(LaunchServer lsrv) {
classloader = new PublicURLClassLoader(new URL[0], ClassLoader.getSystemClassLoader()); classloader = new PublicURLClassLoader(new URL[0], ClassLoader.getSystemClassLoader());
context = new LaunchServerModuleContext(lsrv, classloader); context = new LaunchServerModuleContext(lsrv, classloader);
} }
private void registerCoreModule() { private void registerCoreModule() {
load(new CoreModule()); load(new CoreModule());
} }

View file

@ -8,11 +8,12 @@
public class LaunchServerModuleContext implements ModuleContext { public class LaunchServerModuleContext implements ModuleContext {
public final LaunchServer launchServer; public final LaunchServer launchServer;
public final PublicURLClassLoader classloader; public final PublicURLClassLoader classloader;
public LaunchServerModuleContext(LaunchServer server, PublicURLClassLoader classloader)
{ public LaunchServerModuleContext(LaunchServer server, PublicURLClassLoader classloader) {
launchServer = server; launchServer = server;
this.classloader = classloader; this.classloader = classloader;
} }
@Override @Override
public Type getType() { public Type getType() {
return Type.LAUNCHSERVER; return Type.LAUNCHSERVER;

View file

@ -17,7 +17,7 @@ public String getName() {
@Override @Override
public Version getVersion() { public Version getVersion() {
return new Version(1,0,0,0, Version.Type.UNKNOWN); return new Version(1, 0, 0, 0, Version.Type.UNKNOWN);
} }
@Override @Override

View file

@ -28,13 +28,17 @@ public interface Factory<R> {
@LauncherAPI @LauncherAPI
Response newResponse(LaunchServer server, long id, HInput input, HOutput output, String ip); Response newResponse(LaunchServer server, long id, HInput input, HOutput output, String ip);
} }
private static final Map<Integer, Factory<?>> RESPONSES = new ConcurrentHashMap<>(8); private static final Map<Integer, Factory<?>> RESPONSES = new ConcurrentHashMap<>(8);
public static Response getResponse(int type, LaunchServer server, long session, HInput input, HOutput output, String ip) { public static Response getResponse(int type, LaunchServer server, long session, HInput input, HOutput output, String ip) {
return RESPONSES.get(type).newResponse(server, session, input, output, ip); return RESPONSES.get(type).newResponse(server, session, input, output, ip);
} }
public static void registerResponse(int type, Factory<?> factory) { public static void registerResponse(int type, Factory<?> factory) {
RESPONSES.put(type, factory); RESPONSES.put(type, factory);
} }
public static void registerResponses() { public static void registerResponses() {
registerResponse(RequestType.PING.getNumber(), PingResponse::new); registerResponse(RequestType.PING.getNumber(), PingResponse::new);
registerResponse(RequestType.AUTH.getNumber(), AuthResponse::new); registerResponse(RequestType.AUTH.getNumber(), AuthResponse::new);
@ -50,6 +54,7 @@ public static void registerResponses() {
registerResponse(RequestType.UPDATE.getNumber(), UpdateResponse::new); registerResponse(RequestType.UPDATE.getNumber(), UpdateResponse::new);
registerResponse(RequestType.PROFILES.getNumber(), ProfilesResponse::new); registerResponse(RequestType.PROFILES.getNumber(), ProfilesResponse::new);
} }
@LauncherAPI @LauncherAPI
public static void requestError(String message) throws RequestException { public static void requestError(String message) throws RequestException {
throw new RequestException(message); throw new RequestException(message);

View file

@ -68,9 +68,9 @@ public void reply() throws Exception {
return; return;
} }
Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles(); Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles();
for(SignedObjectHolder<ClientProfile> p : profiles) for (SignedObjectHolder<ClientProfile> p : profiles)
if(p.object.getTitle().equals(client)) if (p.object.getTitle().equals(client))
if(!p.object.isWhitelistContains(login)) if (!p.object.isWhitelistContains(login))
throw new AuthException(server.config.whitelistRejectString); throw new AuthException(server.config.whitelistRejectString);
server.config.hwidHandler.check(HWID.gen(hwid_hdd, hwid_bios, hwid_cpu), result.username); server.config.hwidHandler.check(HWID.gen(hwid_hdd, hwid_bios, hwid_cpu), result.username);
} catch (AuthException | HWIDException e) { } catch (AuthException | HWIDException e) {

View file

@ -25,7 +25,7 @@ public void reply() throws IOException {
Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles(); Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles();
output.writeLength(profiles.size(), 0); output.writeLength(profiles.size(), 0);
for (SignedObjectHolder<ClientProfile> profile : profiles) { for (SignedObjectHolder<ClientProfile> profile : profiles) {
LogHelper.debug("Writted profile: %s",profile.object.getTitle()); LogHelper.debug("Writted profile: %s", profile.object.getTitle());
profile.write(output); profile.write(output);
} }
} }

View file

@ -4,6 +4,7 @@ public class Client {
public long session; public long session;
public long timestamp; public long timestamp;
public Client(long session) { public Client(long session) {
this.session = session; this.session = session;
timestamp = System.currentTimeMillis(); timestamp = System.currentTimeMillis();

View file

@ -15,9 +15,6 @@
import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler; import io.netty.handler.logging.LoggingHandler;
import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherAPI;
import ru.gravit.launcher.hasher.HashedEntry;
import ru.gravit.launcher.serialize.HInput;
import ru.gravit.launcher.serialize.HOutput;
import ru.gravit.launcher.ssl.LauncherKeyStore; import ru.gravit.launcher.ssl.LauncherKeyStore;
import ru.gravit.launcher.ssl.LauncherTrustManager; import ru.gravit.launcher.ssl.LauncherTrustManager;
import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.LaunchServer;
@ -55,8 +52,6 @@ public final class NettyServerSocketHandler implements Runnable, AutoCloseable {
@LauncherAPI @LauncherAPI
public volatile boolean logConnections = Boolean.getBoolean("launcher.logConnections"); public volatile boolean logConnections = Boolean.getBoolean("launcher.logConnections");
// Instance
private final LaunchServer server;
private final AtomicReference<ServerSocket> serverSocket = new AtomicReference<>(); private final AtomicReference<ServerSocket> serverSocket = new AtomicReference<>();
private final ExecutorService threadPool = Executors.newCachedThreadPool(THREAD_FACTORY); private final ExecutorService threadPool = Executors.newCachedThreadPool(THREAD_FACTORY);
@ -64,12 +59,11 @@ public final class NettyServerSocketHandler implements Runnable, AutoCloseable {
private final Map<String, Response.Factory> customResponses = new ConcurrentHashMap<>(2); private final Map<String, Response.Factory> customResponses = new ConcurrentHashMap<>(2);
private final AtomicLong idCounter = new AtomicLong(0L); private final AtomicLong idCounter = new AtomicLong(0L);
private Set<Socket> sockets; private Set<Socket> sockets;
private Selector selector;
private ServerSocketChannel serverChannel;
private volatile Listener listener; private volatile Listener listener;
public NettyServerSocketHandler(LaunchServer server) { public NettyServerSocketHandler(LaunchServer server) {
this.server = server; // Instance
LaunchServer server1 = server;
} }
@Override @Override
@ -86,10 +80,10 @@ public void close() {
} }
public SSLContext SSLContextInit() throws NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, KeyManagementException, IOException, CertificateException { public SSLContext SSLContextInit() throws NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, KeyManagementException, IOException, CertificateException {
TrustManager[] trustAllCerts = new TrustManager[] { TrustManager[] trustAllCerts = new TrustManager[]{
new LauncherTrustManager() new LauncherTrustManager()
}; };
KeyStore ks = LauncherKeyStore.getKeyStore("keystore","PSP1000"); KeyStore ks = LauncherKeyStore.getKeyStore("keystore", "PSP1000");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
.getDefaultAlgorithm()); .getDefaultAlgorithm());
@ -120,8 +114,8 @@ public void run() {
//System.setProperty( "javax.net.ssl.keyStore","keystore"); //System.setProperty( "javax.net.ssl.keyStore","keystore");
//System.setProperty( "javax.net.ssl.keyStorePassword","PSP1000"); //System.setProperty( "javax.net.ssl.keyStorePassword","PSP1000");
try { try {
selector = Selector.open(); Selector selector = Selector.open();
serverChannel = ServerSocketChannel.open(); ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false); serverChannel.configureBlocking(false);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -138,7 +132,7 @@ public void run() {
.handler(new LoggingHandler(LogLevel.DEBUG)) .handler(new LoggingHandler(LogLevel.DEBUG))
.childHandler(new ChannelInitializer<NioSocketChannel>() { .childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override @Override
public void initChannel(NioSocketChannel ch) throws Exception { public void initChannel(NioSocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline(); ChannelPipeline pipeline = ch.pipeline();
//p.addLast(new LoggingHandler(LogLevel.INFO)); //p.addLast(new LoggingHandler(LogLevel.INFO));
System.out.println("P!"); System.out.println("P!");

View file

@ -26,6 +26,7 @@ public Handshake(int type, long session) {
this.session = session; this.session = session;
} }
} }
private final LaunchServer server; private final LaunchServer server;
private final Socket socket; private final Socket socket;
@ -48,12 +49,10 @@ private Handshake readHandshake(HInput input, HOutput output) throws IOException
if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY - 1) { // Previous launcher protocol if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY - 1) { // Previous launcher protocol
session = 0; session = 0;
legacy = true; legacy = true;
} } else if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY - 2) { // Previous launcher protocol
else if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY - 2) { // Previous launcher protocol
session = 0; session = 0;
legacy = true; legacy = true;
} } else if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY) {
else if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY){
} else } else
throw new IOException("Invalid Handshake"); throw new IOException("Invalid Handshake");
@ -68,7 +67,7 @@ else if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY){
throw new IOException(String.format("#%d Key modulus mismatch", session)); throw new IOException(String.format("#%d Key modulus mismatch", session));
} }
// Read request type // Read request type
Integer type = input.readVarInt(); int type = input.readVarInt();
if (!server.serverSocketHandler.onHandshake(session, type)) { if (!server.serverSocketHandler.onHandshake(session, type)) {
output.writeBoolean(false); output.writeBoolean(false);
return null; return null;

View file

@ -28,6 +28,7 @@ public interface Listener {
@LauncherAPI @LauncherAPI
boolean onHandshake(long session, Integer type); boolean onHandshake(long session, Integer type);
} }
private static final ThreadFactory THREAD_FACTORY = r -> CommonHelper.newThread("Network Thread", true, r); private static final ThreadFactory THREAD_FACTORY = r -> CommonHelper.newThread("Network Thread", true, r);
@LauncherAPI @LauncherAPI

View file

@ -13,11 +13,13 @@
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> { public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
@Override @Override
public void channelActive(ChannelHandlerContext ctx) { public void channelActive(ChannelHandlerContext ctx) {
LogHelper.debug("New client %s", IOHelper.getIP(ctx.channel().remoteAddress())); LogHelper.debug("New client %s", IOHelper.getIP(ctx.channel().remoteAddress()));
channels.add(ctx.channel()); channels.add(ctx.channel());
} }
@Override @Override
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception { protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception {
// ping and pong frames already handled // ping and pong frames already handled
@ -26,6 +28,6 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) thr
long handshake = input.readLong(); long handshake = input.readLong();
long connection_flags = input.readLong(); long connection_flags = input.readLong();
long type = input.readInt(); long type = input.readInt();
LogHelper.debug("MessageHead: handshake %dl, flags %dl, type %d", handshake,connection_flags,type); LogHelper.debug("MessageHead: handshake %dl, flags %dl, type %d", handshake, connection_flags, type);
} }
} }

View file

@ -23,7 +23,7 @@ public WebSocketIndexPageHandler(String websocketPath) {
} }
@Override @Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception { protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) {
// Handle a bad request. // Handle a bad request.
if (!req.decoderResult().isSuccess()) { if (!req.decoderResult().isSuccess()) {
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST)); sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST));

View file

@ -24,6 +24,7 @@ private static Texture getTexture(String url, boolean cloak) throws IOException
return null; // Simply not found return null; // Simply not found
} }
} }
private static String getTextureURL(String url, UUID uuid, String username, String client) { private static String getTextureURL(String url, UUID uuid, String username, String client) {
return CommonHelper.replace(url, "username", IOHelper.urlEncode(username), return CommonHelper.replace(url, "username", IOHelper.urlEncode(username),
"uuid", IOHelper.urlEncode(uuid.toString()), "hash", IOHelper.urlEncode(Launcher.toHash(uuid)), "uuid", IOHelper.urlEncode(uuid.toString()), "hash", IOHelper.urlEncode(Launcher.toHash(uuid)),

View file

@ -10,9 +10,11 @@ public enum Type {
CAPE, CAPE,
ELYTRA ELYTRA
} }
public static final Set<Type> PROFILE_TEXTURE_TYPES = Collections.unmodifiableSet(EnumSet.allOf(Type.class)); public static final Set<Type> PROFILE_TEXTURE_TYPES = Collections.unmodifiableSet(EnumSet.allOf(Type.class));
public static final int PROFILE_TEXTURE_COUNT = PROFILE_TEXTURE_TYPES.size(); public static final int PROFILE_TEXTURE_COUNT = PROFILE_TEXTURE_TYPES.size();
private static String baseName(String url) { private static String baseName(String url) {
String name = url.substring(url.lastIndexOf('/') + 1); String name = url.substring(url.lastIndexOf('/') + 1);

View file

@ -24,6 +24,7 @@ public static CompatProfile fromPlayerProfile(PlayerProfile profile) {
profile.cloak == null ? null : SecurityHelper.toHex(profile.cloak.digest) profile.cloak == null ? null : SecurityHelper.toHex(profile.cloak.digest)
); );
} }
// Instance // Instance
public final UUID uuid; public final UUID uuid;
public final String uuidHash, username; public final String uuidHash, username;

View file

@ -171,9 +171,11 @@ public GameProfile hasJoinedServer(GameProfile profile, String serverID) throws
public GameProfile hasJoinedServer(GameProfile profile, String serverID, InetAddress address) throws AuthenticationUnavailableException { public GameProfile hasJoinedServer(GameProfile profile, String serverID, InetAddress address) throws AuthenticationUnavailableException {
return hasJoinedServer(profile, serverID); return hasJoinedServer(profile, serverID);
} }
public YggdrasilAuthenticationService getAuthenticationService() { public YggdrasilAuthenticationService getAuthenticationService() {
return (YggdrasilAuthenticationService)super.getAuthenticationService(); return (YggdrasilAuthenticationService) super.getAuthenticationService();
} }
@Override @Override
public void joinServer(GameProfile profile, String accessToken, String serverID) throws AuthenticationException { public void joinServer(GameProfile profile, String accessToken, String serverID) throws AuthenticationException {
if (!ClientLauncher.isLaunched()) if (!ClientLauncher.isLaunched())

View file

@ -40,6 +40,7 @@ public void run() {
} }
} }
} }
public static final String NAME = Launcher.getConfig().projectname; public static final String NAME = Launcher.getConfig().projectname;
public static String avn32 = null, avn64 = null; public static String avn32 = null, avn64 = null;
public static Path wrap32 = null, wrap64 = null; public static Path wrap32 = null, wrap64 = null;
@ -107,8 +108,8 @@ public static void start(Path path1) throws IOException {
handle(path.resolve("Avanguard64.dll"), "Avanguard64.dll"), handle(path.resolve("Avanguard64.dll"), "Avanguard64.dll"),
handle(path.resolve(NAME + "32.exe"), "wrapper32.exe"), handle(path.resolve(NAME + "32.exe"), "wrapper32.exe"),
handle(path.resolve(NAME + "64.exe"), "wrapper64.exe")); handle(path.resolve(NAME + "64.exe"), "wrapper64.exe"));
HashedDir guard = new HashedDir(path,null,true,false); HashedDir guard = new HashedDir(path, null, true, false);
try(DirWatcher dirWatcher = new DirWatcher(path, guard, null, false)){ try (DirWatcher dirWatcher = new DirWatcher(path, guard, null, false)) {
CommonHelper.newThread("Guard Directory Watcher", true, dirWatcher).start(); CommonHelper.newThread("Guard Directory Watcher", true, dirWatcher).start();
} }
} }

View file

@ -161,6 +161,7 @@ public static void main(String... args) throws Throwable {
Instant end = Instant.now(); Instant end = Instant.now();
LogHelper.debug("Launcher started in %dms", Duration.between(start, end).toMillis()); LogHelper.debug("Launcher started in %dms", Duration.between(start, end).toMillis());
} }
// Instance // Instance
private final AtomicBoolean started = new AtomicBoolean(false); private final AtomicBoolean started = new AtomicBoolean(false);
@ -175,7 +176,7 @@ public Object loadScript(String path) throws IOException, ScriptException {
URL url = Launcher.getResourceURL(path); URL url = Launcher.getResourceURL(path);
LogHelper.debug("Loading script: '%s'", url); LogHelper.debug("Loading script: '%s'", url);
try (BufferedReader reader = IOHelper.newReader(url)) { try (BufferedReader reader = IOHelper.newReader(url)) {
return engine.eval(reader,engine.getBindings(ScriptContext.ENGINE_SCOPE)); return engine.eval(reader, engine.getBindings(ScriptContext.ENGINE_SCOPE));
} }
} }

View file

@ -66,6 +66,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
return super.visitFile(file, attrs); return super.visitFile(file, attrs);
} }
} }
public static final class Params extends StreamObject { public static final class Params extends StreamObject {
// Client paths // Client paths
@LauncherAPI @LauncherAPI
@ -147,6 +148,7 @@ public void write(HOutput output) throws IOException {
output.writeVarInt(height); output.writeVarInt(height);
} }
} }
private static final String[] EMPTY_ARRAY = new String[0]; private static final String[] EMPTY_ARRAY = new String[0];
private static final String MAGICAL_INTEL_OPTION = "-XX:HeapDumpPath=ThisTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump"; private static final String MAGICAL_INTEL_OPTION = "-XX:HeapDumpPath=ThisTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump";
private static final boolean isUsingWrapper = true; private static final boolean isUsingWrapper = true;
@ -249,6 +251,7 @@ private static void addClientLegacyArgs(Collection<String> args, ClientProfile p
Collections.addAll(args, "--gameDir", params.clientDir.toString()); Collections.addAll(args, "--gameDir", params.clientDir.toString());
Collections.addAll(args, "--assetsDir", params.assetDir.toString()); Collections.addAll(args, "--assetsDir", params.assetDir.toString());
} }
@LauncherAPI @LauncherAPI
public static void checkJVMBitsAndVersion() { public static void checkJVMBitsAndVersion() {
if (JVMHelper.JVM_BITS != JVMHelper.OS_BITS) { if (JVMHelper.JVM_BITS != JVMHelper.OS_BITS) {
@ -264,6 +267,7 @@ public static void checkJVMBitsAndVersion() {
JOptionPane.showMessageDialog(null, error); JOptionPane.showMessageDialog(null, error);
} }
} }
@LauncherAPI @LauncherAPI
public static boolean isLaunched() { public static boolean isLaunched() {
return LAUNCHED.get(); return LAUNCHED.get();
@ -304,7 +308,7 @@ public static Process launch(
// Write params file (instead of CLI; Mustdie32 API can't handle command line > 32767 chars) // Write params file (instead of CLI; Mustdie32 API can't handle command line > 32767 chars)
LogHelper.debug("Writing ClientLauncher params"); LogHelper.debug("Writing ClientLauncher params");
Path paramsFile = Files.createTempFile("ClientLauncherParams", ".bin"); Path paramsFile = Files.createTempFile("ClientLauncherParams", ".bin");
CommonHelper.newThread("Client params writter",false,() -> CommonHelper.newThread("Client params writter", false, () ->
{ {
try { try {
try (ServerSocket socket = new ServerSocket()) { try (ServerSocket socket = new ServerSocket()) {
@ -338,8 +342,9 @@ public static Process launch(
List<String> args = new LinkedList<>(); List<String> args = new LinkedList<>();
boolean wrapper = isUsingWrapper(); boolean wrapper = isUsingWrapper();
Path javaBin; Path javaBin;
if (wrapper) javaBin = JVMHelper.JVM_BITS == 64 ? AvanguardStarter.wrap64: AvanguardStarter.wrap32; if (wrapper) javaBin = JVMHelper.JVM_BITS == 64 ? AvanguardStarter.wrap64 : AvanguardStarter.wrap32;
else javaBin = Paths.get(System.getProperty("java.home") + IOHelper.PLATFORM_SEPARATOR + "bin" + IOHelper.PLATFORM_SEPARATOR + "java"); else
javaBin = Paths.get(System.getProperty("java.home") + IOHelper.PLATFORM_SEPARATOR + "bin" + IOHelper.PLATFORM_SEPARATOR + "java");
args.add(javaBin.toString()); args.add(javaBin.toString());
args.add(MAGICAL_INTEL_OPTION); args.add(MAGICAL_INTEL_OPTION);
if (params.ram > 0 && params.ram <= JVMHelper.RAM) { if (params.ram > 0 && params.ram <= JVMHelper.RAM) {
@ -366,7 +371,7 @@ public static Process launch(
classPathString.append(File.pathSeparatorChar).append(path.toString()); classPathString.append(File.pathSeparatorChar).append(path.toString());
Collections.addAll(args, profile.object.getJvmArgs()); Collections.addAll(args, profile.object.getJvmArgs());
Collections.addAll(args, "-Djava.library.path=".concat(params.clientDir.resolve(NATIVES_DIR).toString())); // Add Native Path Collections.addAll(args, "-Djava.library.path=".concat(params.clientDir.resolve(NATIVES_DIR).toString())); // Add Native Path
Collections.addAll(args,"-javaagent:".concat(pathLauncher)); Collections.addAll(args, "-javaagent:".concat(pathLauncher));
//Collections.addAll(args, "-classpath", classPathString.toString()); //Collections.addAll(args, "-classpath", classPathString.toString());
//if(wrapper) //if(wrapper)
//Collections.addAll(args, "-Djava.class.path=".concat(classPathString.toString())); // Add Class Path //Collections.addAll(args, "-Djava.class.path=".concat(classPathString.toString())); // Add Class Path
@ -379,7 +384,7 @@ public static Process launch(
// Build client process // Build client process
LogHelper.debug("Launching client instance"); LogHelper.debug("Launching client instance");
ProcessBuilder builder = new ProcessBuilder(args); ProcessBuilder builder = new ProcessBuilder(args);
if(wrapper) if (wrapper)
builder.environment().put("JAVA_HOME", System.getProperty("java.home")); builder.environment().put("JAVA_HOME", System.getProperty("java.home"));
//else //else
//builder.environment().put("CLASSPATH", classPathString.toString()); //builder.environment().put("CLASSPATH", classPathString.toString());
@ -427,8 +432,7 @@ public static void main(String... args) throws Throwable {
clientHDir = new SignedObjectHolder<>(input, publicKey, HashedDir::new); clientHDir = new SignedObjectHolder<>(input, publicKey, HashedDir::new);
} }
} }
} catch (IOException ex) } catch (IOException ex) {
{
LogHelper.error(ex); LogHelper.error(ex);
try (HInput input = new HInput(IOHelper.newInput(paramsFile))) { try (HInput input = new HInput(IOHelper.newInput(paramsFile))) {
params = new Params(input); params = new Params(input);

View file

@ -7,10 +7,11 @@
public class ClientModuleContext implements ModuleContext { public class ClientModuleContext implements ModuleContext {
public final LauncherEngine engine; public final LauncherEngine engine;
ClientModuleContext(LauncherEngine engine)
{ ClientModuleContext(LauncherEngine engine) {
this.engine = engine; this.engine = engine;
} }
@Override @Override
public Type getType() { public Type getType() {
return Type.CLIENT; return Type.CLIENT;

View file

@ -7,8 +7,7 @@
import ru.gravit.launcher.modules.SimpleModuleManager; import ru.gravit.launcher.modules.SimpleModuleManager;
public class ClientModuleManager extends SimpleModuleManager { public class ClientModuleManager extends SimpleModuleManager {
public ClientModuleManager(LauncherEngine engine) public ClientModuleManager(LauncherEngine engine) {
{
context = new ClientModuleContext(engine); context = new ClientModuleContext(engine);
modules = new ArrayList<>(); modules = new ArrayList<>();
} }

View file

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

View file

@ -43,12 +43,14 @@ public boolean isOverfilled() {
return onlinePlayers >= maxPlayers; return onlinePlayers >= maxPlayers;
} }
} }
// Constants // Constants
private static final String LEGACY_PING_HOST_MAGIC = "§1"; private static final String LEGACY_PING_HOST_MAGIC = "§1";
private static final String LEGACY_PING_HOST_CHANNEL = "MC|PingHost"; private static final String LEGACY_PING_HOST_CHANNEL = "MC|PingHost";
private static final Pattern LEGACY_PING_HOST_DELIMETER = Pattern.compile("\0", Pattern.LITERAL); private static final Pattern LEGACY_PING_HOST_DELIMETER = Pattern.compile("\0", Pattern.LITERAL);
private static final int PACKET_LENGTH = 65535; private static final int PACKET_LENGTH = 65535;
private static String readUTF16String(HInput input) throws IOException { private static String readUTF16String(HInput input) throws IOException {
int length = input.readUnsignedShort() << 1; int length = input.readUnsignedShort() << 1;
byte[] encoded = input.readByteArray(-length); byte[] encoded = input.readByteArray(-length);
@ -59,6 +61,7 @@ private static void writeUTF16String(HOutput output, String s) throws IOExceptio
output.writeShort((short) s.length()); output.writeShort((short) s.length());
output.stream.write(s.getBytes(StandardCharsets.UTF_16BE)); output.stream.write(s.getBytes(StandardCharsets.UTF_16BE));
} }
// Instance // Instance
private final InetSocketAddress address; private final InetSocketAddress address;
private final ClientProfile.Version version; private final ClientProfile.Version version;

View file

@ -75,6 +75,7 @@ public StyleableProperty<Number> getStyleableProperty(ProgressCircleIndicator n)
}; };
public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
static { static {
final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData()); final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData());
styleables.add(INNER_CIRCLE_RADIUS); styleables.add(INNER_CIRCLE_RADIUS);
@ -83,9 +84,6 @@ public StyleableProperty<Number> getStyleableProperty(ProgressCircleIndicator n)
} }
@LauncherAPI @LauncherAPI
/**
* @return The CssMetaData associated with this class, which may include the CssMetaData of its super classes.
*/
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
return StyleableProperties.STYLEABLES; return StyleableProperties.STYLEABLES;
} }

View file

@ -82,6 +82,7 @@ public StyleableProperty<Number> getStyleableProperty(RingProgressIndicator n) {
}; };
public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
static { static {
final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData()); final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData());
styleables.addAll(getClassCssMetaData()); styleables.addAll(getClassCssMetaData());

View file

@ -17,7 +17,6 @@
* Skin of the ring progress indicator where an arc grows and by the progress value up to 100% where the arc becomes a ring. * Skin of the ring progress indicator where an arc grows and by the progress value up to 100% where the arc becomes a ring.
* *
* @author Andrea Vacondio * @author Andrea Vacondio
*
*/ */
@LauncherAPI @LauncherAPI
public class RingProgressIndicatorSkin implements Skin<RingProgressIndicator> { public class RingProgressIndicatorSkin implements Skin<RingProgressIndicator> {
@ -29,6 +28,7 @@ public class RingProgressIndicatorSkin implements Skin<RingProgressIndicator> {
private final StackPane container = new StackPane(); private final StackPane container = new StackPane();
private final Arc fillerArc = new Arc(); private final Arc fillerArc = new Arc();
private final RotateTransition transition = new RotateTransition(Duration.millis(2000), fillerArc); private final RotateTransition transition = new RotateTransition(Duration.millis(2000), fillerArc);
@LauncherAPI @LauncherAPI
public RingProgressIndicatorSkin(final RingProgressIndicator indicator) { public RingProgressIndicatorSkin(final RingProgressIndicator indicator) {
this.indicator = indicator; this.indicator = indicator;
@ -108,16 +108,19 @@ private void initIndeterminate(boolean newVal) {
transition.stop(); transition.stop();
} }
} }
@LauncherAPI @LauncherAPI
@Override @Override
public RingProgressIndicator getSkinnable() { public RingProgressIndicator getSkinnable() {
return indicator; return indicator;
} }
@LauncherAPI @LauncherAPI
@Override @Override
public Node getNode() { public Node getNode() {
return container; return container;
} }
@LauncherAPI @LauncherAPI
@Override @Override
public void dispose() { public void dispose() {

View file

@ -7,7 +7,6 @@
import com.sun.javafx.collections.NonIterableChange; import com.sun.javafx.collections.NonIterableChange;
import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList; import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList;
import javafx.beans.InvalidationListener;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
@ -104,6 +103,7 @@ public int size() {
} }
}); });
} }
@LauncherAPI @LauncherAPI
@Override @Override
public void check(int index) { public void check(int index) {
@ -114,23 +114,27 @@ public void check(int index) {
checkedIndicesList.callObservers( checkedIndicesList.callObservers(
new NonIterableChange.SimpleAddChange<>(changeIndex, changeIndex + 1, checkedIndicesList)); new NonIterableChange.SimpleAddChange<>(changeIndex, changeIndex + 1, checkedIndicesList));
} }
@Override @Override
public void check(T item) { public void check(T item) {
int index = getItemIndex(item); int index = getItemIndex(item);
check(index); check(index);
} }
@LauncherAPI @LauncherAPI
@Override @Override
public void checkAll() { public void checkAll() {
for (int i = 0; i < getItemCount(); i++) for (int i = 0; i < getItemCount(); i++)
check(i); check(i);
} }
@LauncherAPI @LauncherAPI
@Override @Override
public void checkIndices(int... indices) { public void checkIndices(int... indices) {
for (int indice : indices) for (int indice : indices)
check(indice); check(indice);
} }
@LauncherAPI @LauncherAPI
@Override @Override
public void clearCheck(int index) { public void clearCheck(int index) {
@ -142,57 +146,69 @@ public void clearCheck(int index) {
checkedIndicesList.callObservers( checkedIndicesList.callObservers(
new NonIterableChange.SimpleRemovedChange<>(changeIndex, changeIndex, index, checkedIndicesList)); new NonIterableChange.SimpleRemovedChange<>(changeIndex, changeIndex, index, checkedIndicesList));
} }
@LauncherAPI @LauncherAPI
@Override @Override
public void clearCheck(T item) { public void clearCheck(T item) {
int index = getItemIndex(item); int index = getItemIndex(item);
clearCheck(index); clearCheck(index);
} }
@LauncherAPI @LauncherAPI
@Override @Override
public void clearChecks() { public void clearChecks() {
for (int index = 0; index < checkedIndices.length(); index++) for (int index = 0; index < checkedIndices.length(); index++)
clearCheck(index); clearCheck(index);
} }
@LauncherAPI @LauncherAPI
@Override @Override
public ObservableList<Integer> getCheckedIndices() { public ObservableList<Integer> getCheckedIndices() {
return checkedIndicesList; return checkedIndicesList;
} }
@LauncherAPI @LauncherAPI
@Override @Override
public ObservableList<T> getCheckedItems() { public ObservableList<T> getCheckedItems() {
return checkedItemsList; return checkedItemsList;
} }
@LauncherAPI @LauncherAPI
@Override @Override
public abstract T getItem(int index); public abstract T getItem(int index);
@LauncherAPI @LauncherAPI
BooleanProperty getItemBooleanProperty(T item) { BooleanProperty getItemBooleanProperty(T item) {
return itemBooleanMap.get(item); return itemBooleanMap.get(item);
} }
@LauncherAPI @LauncherAPI
@Override @Override
public abstract int getItemCount(); public abstract int getItemCount();
@LauncherAPI @LauncherAPI
@Override @Override
public abstract int getItemIndex(T item); public abstract int getItemIndex(T item);
@LauncherAPI @LauncherAPI
@Override @Override
public boolean isChecked(int index) { public boolean isChecked(int index) {
return checkedIndices.get(index); return checkedIndices.get(index);
} }
@LauncherAPI @LauncherAPI
@Override @Override
public boolean isChecked(T item) { public boolean isChecked(T item) {
int index = getItemIndex(item); int index = getItemIndex(item);
return isChecked(index); return isChecked(index);
} }
@LauncherAPI @LauncherAPI
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return checkedIndices.isEmpty(); return checkedIndices.isEmpty();
} }
@LauncherAPI @LauncherAPI
@Override @Override
public void toggleCheckState(int index) { public void toggleCheckState(int index) {
@ -208,6 +224,7 @@ public void toggleCheckState(T item) {
int index = getItemIndex(item); int index = getItemIndex(item);
toggleCheckState(index); toggleCheckState(index);
} }
@LauncherAPI @LauncherAPI
protected void updateMap() { protected void updateMap() {
itemBooleanMap.clear(); itemBooleanMap.clear();

View file

@ -50,6 +50,7 @@ public int getItemIndex(T item) {
return items.indexOf(item); return items.indexOf(item);
} }
} }
private final ObservableList<T> items; private final ObservableList<T> items;
private final Map<T, BooleanProperty> itemBooleanMap; private final Map<T, BooleanProperty> itemBooleanMap;

View file

@ -25,8 +25,6 @@ public class CheckComboBoxSkin<T> extends BehaviorSkinBase<CheckComboBox<T>, Beh
private final ListCell<T> buttonCell; private final ListCell<T> buttonCell;
private final CheckComboBox<T> control; private final CheckComboBox<T> control;
private final ObservableList<T> items;
private final ReadOnlyUnbackedObservableList<Integer> selectedIndices;
private final ReadOnlyUnbackedObservableList<T> selectedItems; private final ReadOnlyUnbackedObservableList<T> selectedItems;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -34,9 +32,9 @@ public CheckComboBoxSkin(final CheckComboBox<T> control) {
super(control, new BehaviorBase<>(control, Collections.emptyList())); super(control, new BehaviorBase<>(control, Collections.emptyList()));
this.control = control; this.control = control;
this.items = control.getItems(); ObservableList<T> items = control.getItems();
selectedIndices = (ReadOnlyUnbackedObservableList<Integer>) control.getCheckModel().getCheckedIndices(); ReadOnlyUnbackedObservableList<Integer> selectedIndices = (ReadOnlyUnbackedObservableList<Integer>) control.getCheckModel().getCheckedIndices();
selectedItems = (ReadOnlyUnbackedObservableList<T>) control.getCheckModel().getCheckedItems(); selectedItems = (ReadOnlyUnbackedObservableList<T>) control.getCheckModel().getCheckedItems();
comboBox = new ComboBox<T>(items) { comboBox = new ComboBox<T>(items) {
@ -143,8 +141,7 @@ protected boolean isHideOnClickEnabled() {
return false; return false;
} }
}; };
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked") final ListView<T> listView = (ListView<T>) comboBoxListViewSkin.getPopupContent();
final ListView<T> listView = (ListView<T>) comboBoxListViewSkin.getPopupContent();
listView.setOnKeyPressed(e -> { listView.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.SPACE) { if (e.getCode() == KeyCode.SPACE) {
T item = listView.getSelectionModel().getSelectedItem(); T item = listView.getSelectionModel().getSelectedItem();

View file

@ -14,10 +14,12 @@
public abstract class Request<R> { public abstract class Request<R> {
private static final long session = SecurityHelper.secureRandom.nextLong(); private static final long session = SecurityHelper.secureRandom.nextLong();
@LauncherAPI @LauncherAPI
public static void requestError(String message) throws RequestException { public static void requestError(String message) throws RequestException {
throw new RequestException(message); throw new RequestException(message);
} }
@LauncherAPI @LauncherAPI
protected final LauncherConfig config; protected final LauncherConfig config;

View file

@ -29,6 +29,7 @@ private Result(PlayerProfile pp, String accessToken) {
this.accessToken = accessToken; this.accessToken = accessToken;
} }
} }
private final String login; private final String login;
private final byte[] encryptedPassword; private final byte[] encryptedPassword;

View file

@ -46,6 +46,7 @@ public byte[] getSign() {
return sign.clone(); return sign.clone();
} }
} }
@LauncherAPI @LauncherAPI
public static final Path BINARY_PATH = IOHelper.getCodeSource(Launcher.class); public static final Path BINARY_PATH = IOHelper.getCodeSource(Launcher.class);

View file

@ -38,6 +38,7 @@ public ProfilesRequest(LauncherConfig config) {
public Integer getType() { public Integer getType() {
return RequestType.PROFILES.getNumber(); return RequestType.PROFILES.getNumber();
} }
@Override @Override
protected Result requestDo(HInput input, HOutput output) throws Exception { protected Result requestDo(HInput input, HOutput output) throws Exception {
output.writeBoolean(true); output.writeBoolean(true);

View file

@ -41,6 +41,7 @@ public static final class State {
public interface Callback { public interface Callback {
void call(State state); void call(State state);
} }
@LauncherAPI @LauncherAPI
public final long fileDownloaded; public final long fileDownloaded;
@LauncherAPI @LauncherAPI
@ -166,6 +167,7 @@ public double getTotalSizeMiB() {
return getTotalSizeKiB() / 1024.0D; return getTotalSizeKiB() / 1024.0D;
} }
} }
private static void fillActionsQueue(Queue<UpdateAction> queue, HashedDir mismatch) { private static void fillActionsQueue(Queue<UpdateAction> queue, HashedDir mismatch) {
for (Entry<String, HashedEntry> mapEntry : mismatch.map().entrySet()) { for (Entry<String, HashedEntry> mapEntry : mismatch.map().entrySet()) {
String name = mapEntry.getKey(); String name = mapEntry.getKey();
@ -185,6 +187,7 @@ private static void fillActionsQueue(Queue<UpdateAction> queue, HashedDir mismat
} }
} }
} }
// Instance // Instance
private final String dirName; private final String dirName;
private final Path dir; private final Path dir;

View file

@ -18,6 +18,7 @@
public class ServerWrapper { public class ServerWrapper {
public static ModulesManager modulesManager; public static ModulesManager modulesManager;
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
ServerWrapper wrapper = new ServerWrapper(); ServerWrapper wrapper = new ServerWrapper();
modulesManager = new ModulesManager(wrapper); modulesManager = new ModulesManager(wrapper);
@ -26,12 +27,11 @@ public static void main(String[] args) throws Throwable {
LauncherConfig cfg = new LauncherConfig(new HInput(IOHelper.newInput(IOHelper.getResourceURL(Launcher.CONFIG_FILE)))); LauncherConfig cfg = new LauncherConfig(new HInput(IOHelper.newInput(IOHelper.getResourceURL(Launcher.CONFIG_FILE))));
modulesManager.preInitModules(); modulesManager.preInitModules();
ProfilesRequest.Result result = new ProfilesRequest(cfg).request(); ProfilesRequest.Result result = new ProfilesRequest(cfg).request();
for(SignedObjectHolder<ClientProfile> p : result.profiles) for (SignedObjectHolder<ClientProfile> p : result.profiles) {
{ LogHelper.debug("Get profile: %s", p.object.getTitle());
LogHelper.debug("Get profile: %s",p.object.getTitle()); if (p.object.getTitle().equals(ClientLauncher.title)) {
if(p.object.getTitle().equals(ClientLauncher.title)) {
wrapper.profile = p.object; wrapper.profile = p.object;
LogHelper.debug("Found profile: %s",ClientLauncher.title); LogHelper.debug("Found profile: %s", ClientLauncher.title);
break; break;
} }
} }
@ -40,9 +40,10 @@ public static void main(String[] args) throws Throwable {
Class<?> mainClass = Class.forName(classname); Class<?> mainClass = Class.forName(classname);
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)); MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
String[] real_args = new String[args.length - 1]; String[] real_args = new String[args.length - 1];
System.arraycopy(args,1,real_args,0,args.length - 1); System.arraycopy(args, 1, real_args, 0, args.length - 1);
modulesManager.postInitModules(); modulesManager.postInitModules();
mainMethod.invoke(real_args); mainMethod.invoke(real_args);
} }
public ClientProfile profile; public ClientProfile profile;
} }

View file

@ -1,19 +1,19 @@
public static UUID toUUID(String username) { public static UUID toUUID(String username){
ByteBuffer buffer = ByteBuffer.wrap(Arrays.copyOf(username.getBytes(StandardCharsets.US_ASCII), 16)); ByteBuffer buffer=ByteBuffer.wrap(Arrays.copyOf(username.getBytes(StandardCharsets.US_ASCII),16));
return new UUID(buffer.getLong(), buffer.getLong()); // MOST, LEAST return new UUID(buffer.getLong(),buffer.getLong()); // MOST, LEAST
} }
public static String toUsername(UUID uuid) { public static String toUsername(UUID uuid){
byte[] bytes = ByteBuffer.allocate(16). byte[]bytes=ByteBuffer.allocate(16).
putLong(uuid.getMostSignificantBits()). putLong(uuid.getMostSignificantBits()).
putLong(uuid.getLeastSignificantBits()).array(); putLong(uuid.getLeastSignificantBits()).array();
// Find username end // Find username end
int length = 0; int length=0;
while(length < bytes.length && bytes[length] != 0) { while(length<bytes.length&&bytes[length]!=0){
length++; length++;
} }
// Decode and verify // Decode and verify
return VerifyHelper.verifyUsername(new String(bytes, 0, length, StandardCharsets.US_ASCII)); return VerifyHelper.verifyUsername(new String(bytes,0,length,StandardCharsets.US_ASCII));
} }

View file

@ -5,12 +5,13 @@ public class AutogenConfig {
public String address; public String address;
public int port; public int port;
private boolean isInitModules; private boolean isInitModules;
AutogenConfig() { AutogenConfig() {
} }
@SuppressWarnings("UnnecessaryReturnStatement") @SuppressWarnings("UnnecessaryReturnStatement")
public void initModules() public void initModules() {
{ if (isInitModules) return;
if(isInitModules) return;
} }
} }

View file

@ -24,6 +24,7 @@ static int readBuildNumber() {
return 0; // Maybe dev env? return 0; // Maybe dev env?
} }
} }
private static final AtomicReference<LauncherConfig> CONFIG = new AtomicReference<>(); private static final AtomicReference<LauncherConfig> CONFIG = new AtomicReference<>();
@LauncherAPI @LauncherAPI
public static ModulesManagerInterface modulesManager = null; public static ModulesManagerInterface modulesManager = null;
@ -85,6 +86,6 @@ public static String toHash(UUID uuid) {
} }
public static Version getVersion() { public static Version getVersion() {
return new Version(MAJOR,MINOR,PATCH,BUILD,RELEASE); return new Version(MAJOR, MINOR, PATCH, BUILD, RELEASE);
} }
} }

View file

@ -13,17 +13,18 @@
@LauncherAPI @LauncherAPI
public class LauncherAgent { public class LauncherAgent {
private static final boolean enabled = false; private static final boolean enabled = false;
private static boolean isAgentStarted=false; private static boolean isAgentStarted = false;
public static Instrumentation inst; public static Instrumentation inst;
public static void addJVMClassPath(String path) throws IOException { public static void addJVMClassPath(String path) throws IOException {
LogHelper.debug("Launcher Agent addJVMClassPath"); LogHelper.debug("Launcher Agent addJVMClassPath");
inst.appendToSystemClassLoaderSearch(new JarFile(path)); inst.appendToSystemClassLoaderSearch(new JarFile(path));
} }
public boolean isAgentStarted()
{ public boolean isAgentStarted() {
return isAgentStarted; return isAgentStarted;
} }
public static long getObjSize(Object obj) { public static long getObjSize(Object obj) {
return inst.getObjectSize(obj); return inst.getObjectSize(obj);
} }
@ -33,7 +34,7 @@ public static void premain(String agentArgument, Instrumentation instrumentation
inst = instrumentation; inst = instrumentation;
isAgentStarted = true; isAgentStarted = true;
if(ClassFile.MAJOR_VERSION > ClassFile.JAVA_8 || enabled) { if (ClassFile.MAJOR_VERSION > ClassFile.JAVA_8 || enabled) {
inst.addTransformer(new SystemClassLoaderTransformer()); inst.addTransformer(new SystemClassLoaderTransformer());
Class<?>[] classes = inst.getAllLoadedClasses(); // Получаем список уже загруженных классов, которые могут быть изменены. Классы, которые ещё не загружены, будут изменены при загрузке Class<?>[] classes = inst.getAllLoadedClasses(); // Получаем список уже загруженных классов, которые могут быть изменены. Классы, которые ещё не загружены, будут изменены при загрузке
ArrayList<Class<?>> classList = new ArrayList<>(); ArrayList<Class<?>> classList = new ArrayList<>();

View file

@ -23,11 +23,12 @@ public final class LauncherConfig extends StreamObject {
@LauncherAPI @LauncherAPI
public static final String ADDRESS_OVERRIDE = System.getProperty(ADDRESS_OVERRIDE_PROPERTY, null); public static final String ADDRESS_OVERRIDE = System.getProperty(ADDRESS_OVERRIDE_PROPERTY, null);
private static final AutogenConfig config = new AutogenConfig(); private static final AutogenConfig config = new AutogenConfig();
@LauncherAPI @LauncherAPI
public static AutogenConfig getAutogenConfig() public static AutogenConfig getAutogenConfig() {
{
return config; return config;
} }
// Instance // Instance
@LauncherAPI @LauncherAPI
public final InetSocketAddress address; public final InetSocketAddress address;
@ -38,6 +39,7 @@ public static AutogenConfig getAutogenConfig()
@LauncherAPI @LauncherAPI
public final Map<String, byte[]> runtime; public final Map<String, byte[]> runtime;
@LauncherAPI @LauncherAPI
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException { public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
String localAddress = config.address; String localAddress = config.address;
@ -60,14 +62,16 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException
if (ADDRESS_OVERRIDE != null) if (ADDRESS_OVERRIDE != null)
LogHelper.warning("Address override is enabled: '%s'", ADDRESS_OVERRIDE); LogHelper.warning("Address override is enabled: '%s'", ADDRESS_OVERRIDE);
} }
@LauncherAPI @LauncherAPI
@SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter") @SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter")
public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<String, byte[]> runtime,String projectname) { public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<String, byte[]> runtime, String projectname) {
this.address = InetSocketAddress.createUnresolved(address, port); this.address = InetSocketAddress.createUnresolved(address, port);
this.publicKey = Objects.requireNonNull(publicKey, "publicKey"); this.publicKey = Objects.requireNonNull(publicKey, "publicKey");
this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime)); this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime));
this.projectname = projectname; this.projectname = projectname;
} }
@LauncherAPI @LauncherAPI
@SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter") @SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter")
public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<String, byte[]> runtime) { public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<String, byte[]> runtime) {

View file

@ -63,15 +63,18 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
private static final Kind<?>[] KINDS = { private static final Kind<?>[] KINDS = {
StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE
}; };
private static void handleError(Throwable e) { private static void handleError(Throwable e) {
LogHelper.error(e); LogHelper.error(e);
} }
private static Deque<String> toPath(Iterable<Path> path) { private static Deque<String> toPath(Iterable<Path> path) {
Deque<String> result = new LinkedList<>(); Deque<String> result = new LinkedList<>();
for (Path pe : path) for (Path pe : path)
result.add(pe.toString()); result.add(pe.toString());
return result; return result;
} }
// Instance // Instance
private final Path dir; private final Path dir;
private final HashedDir hdir; private final HashedDir hdir;

View file

@ -18,6 +18,7 @@ private static boolean anyMatch(String[] entries, Collection<String> path) {
// } // }
//} //}
} }
// Instance // Instance
private final String[] update; private final String[] update;
private final String[] verify; private final String[] verify;

View file

@ -13,6 +13,7 @@ public abstract class HashedEntry extends StreamObject {
public enum Type implements Itf { public enum Type implements Itf {
DIR(1), FILE(2); DIR(1), FILE(2);
private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class); private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class);
public static Type read(HInput input) throws IOException { public static Type read(HInput input) throws IOException {
return SERIALIZER.read(input); return SERIALIZER.read(input);
} }

View file

@ -16,6 +16,7 @@ public Entry(NeedGarbageCollection invoke, long timer) {
this.timer = timer; this.timer = timer;
} }
} }
private static final Timer timer = new Timer("GarbageTimer"); private static final Timer timer = new Timer("GarbageTimer");
private static final ArrayList<Entry> NEED_GARBARE_COLLECTION = new ArrayList<>(); private static final ArrayList<Entry> NEED_GARBARE_COLLECTION = new ArrayList<>();

View file

@ -9,6 +9,7 @@ public interface Module extends AutoCloseable {
Version getVersion(); Version getVersion();
int getPriority(); int getPriority();
void init(ModuleContext context); void init(ModuleContext context);
void postInit(ModuleContext context); void postInit(ModuleContext context);

View file

@ -2,8 +2,10 @@
public interface ModuleContext { public interface ModuleContext {
enum Type { enum Type {
SERVER,CLIENT,LAUNCHSERVER SERVER, CLIENT, LAUNCHSERVER
} }
Type getType(); Type getType();
ModulesManagerInterface getModulesManager(); ModulesManagerInterface getModulesManager();
} }

View file

@ -3,14 +3,23 @@
import java.net.URL; import java.net.URL;
public interface ModulesManagerInterface { public interface ModulesManagerInterface {
void initModules() throws Exception; void initModules();
void load(Module module) throws Exception;
void load(Module module, boolean preload) throws Exception; void load(Module module);
void load(Module module, boolean preload);
void loadModule(URL jarpath, boolean preload) throws Exception; void loadModule(URL jarpath, boolean preload) throws Exception;
void loadModule(URL jarpath, String classname, boolean preload) throws Exception; void loadModule(URL jarpath, String classname, boolean preload) throws Exception;
void postInitModules() throws Exception;
void preInitModules() throws Exception; void postInitModules();
void printModules() throws Exception;
void preInitModules();
void printModules();
void sort(); void sort();
void registerModule(Module module,boolean preload) throws Exception;
void registerModule(Module module, boolean preload);
} }

View file

@ -14,7 +14,7 @@
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.jar.Manifest; import java.util.jar.Manifest;
public class SimpleModuleManager implements ModulesManagerInterface,AutoCloseable { public class SimpleModuleManager implements ModulesManagerInterface, AutoCloseable {
protected final class ModulesVisitor extends SimpleFileVisitor<Path> { protected final class ModulesVisitor extends SimpleFileVisitor<Path> {
private ModulesVisitor() { private ModulesVisitor() {
} }
@ -35,6 +35,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
return super.visitFile(file, attrs); return super.visitFile(file, attrs);
} }
} }
public ArrayList<Module> modules; public ArrayList<Module> modules;
public PublicURLClassLoader classloader; public PublicURLClassLoader classloader;
protected ModuleContext context; protected ModuleContext context;
@ -48,9 +49,8 @@ public void autoload(Path dir) throws IOException {
LogHelper.info("Loaded %d modules", modules.size()); LogHelper.info("Loaded %d modules", modules.size());
} }
public void sort() public void sort() {
{ modules.sort((m1, m2) -> {
modules.sort((m1,m2) -> {
int p1 = m1.getPriority(); int p1 = m1.getPriority();
int p2 = m2.getPriority(); int p2 = m2.getPriority();
return Integer.compare(p2, p1); return Integer.compare(p2, p1);
@ -110,8 +110,8 @@ public void loadModule(URL jarpath, String classname, boolean preload) throws Cl
Module module = (Module) moduleclass.newInstance(); Module module = (Module) moduleclass.newInstance();
modules.add(module); modules.add(module);
module.preInit(context); module.preInit(context);
if(!preload) module.init(context); if (!preload) module.init(context);
LogHelper.info("Module %s version: %s loaded",module.getName(),module.getVersion()); LogHelper.info("Module %s version: %s loaded", module.getName(), module.getVersion());
} }
@Override @Override
@ -142,9 +142,8 @@ public void printModules() {
@Override @Override
@LauncherAPI @LauncherAPI
public void registerModule(Module module,boolean preload) public void registerModule(Module module, boolean preload) {
{
load(module, preload); load(module, preload);
LogHelper.info("Module %s version: %s registered",module.getName(),module.getVersion()); LogHelper.info("Module %s version: %s registered", module.getName(), module.getVersion());
} }
} }

View file

@ -6,7 +6,7 @@
public class TestClientModule implements Module { public class TestClientModule implements Module {
@Override @Override
public void close() throws Exception { public void close() {
} }

View file

@ -32,12 +32,14 @@ public enum Version {
MC113("1.13", 393), MC113("1.13", 393),
MC1131("1.13.1", 401); MC1131("1.13.1", 401);
private static final Map<String, Version> VERSIONS; private static final Map<String, Version> VERSIONS;
static { static {
Version[] versionsValues = values(); Version[] versionsValues = values();
VERSIONS = new HashMap<>(versionsValues.length); VERSIONS = new HashMap<>(versionsValues.length);
for (Version version : versionsValues) for (Version version : versionsValues)
VERSIONS.put(version.name, version); VERSIONS.put(version.name, version);
} }
public static Version byName(String name) { public static Version byName(String name) {
return VerifyHelper.getMapValue(VERSIONS, name, String.format("Unknown client version: '%s'", name)); return VerifyHelper.getMapValue(VERSIONS, name, String.format("Unknown client version: '%s'", name));
} }
@ -56,6 +58,7 @@ public String toString() {
return "Minecraft " + name; return "Minecraft " + name;
} }
} }
@LauncherAPI @LauncherAPI
public static final StreamObject.Adapter<ClientProfile> RO_ADAPTER = input -> new ClientProfile(input, true); public static final StreamObject.Adapter<ClientProfile> RO_ADAPTER = input -> new ClientProfile(input, true);
@ -157,6 +160,7 @@ public FileNameMatcher getClientUpdateMatcher() {
public String[] getJvmArgs() { public String[] getJvmArgs() {
return jvmArgs.stream(StringConfigEntry.class).toArray(String[]::new); return jvmArgs.stream(StringConfigEntry.class).toArray(String[]::new);
} }
@LauncherAPI @LauncherAPI
public String getMainClass() { public String getMainClass() {
return mainClass.getValue(); return mainClass.getValue();
@ -198,9 +202,8 @@ public boolean isUpdateFastCheck() {
} }
@LauncherAPI @LauncherAPI
public boolean isWhitelistContains(String username) public boolean isWhitelistContains(String username) {
{ if (!useWhitelist.getValue()) return true;
if(!useWhitelist.getValue()) return true;
return whitelist.stream(StringConfigEntry.class).anyMatch(e -> e.equals(username)); return whitelist.stream(StringConfigEntry.class).anyMatch(e -> e.equals(username));
} }

View file

@ -16,10 +16,12 @@ public final class PlayerProfile extends StreamObject {
public static PlayerProfile newOfflineProfile(String username) { public static PlayerProfile newOfflineProfile(String username) {
return new PlayerProfile(offlineUUID(username), username, null, null); return new PlayerProfile(offlineUUID(username), username, null, null);
} }
@LauncherAPI @LauncherAPI
public static UUID offlineUUID(String username) { public static UUID offlineUUID(String username) {
return UUID.nameUUIDFromBytes(IOHelper.encodeASCII("OfflinePlayer:" + username)); return UUID.nameUUIDFromBytes(IOHelper.encodeASCII("OfflinePlayer:" + username));
} }
@LauncherAPI @LauncherAPI
public final UUID uuid; public final UUID uuid;

View file

@ -14,6 +14,7 @@ public enum RequestType implements EnumSerializer.Itf {
PROFILES(10), PROFILES(10),
CUSTOM(255); // Custom requests CUSTOM(255); // Custom requests
private static final EnumSerializer<RequestType> SERIALIZER = new EnumSerializer<>(RequestType.class); private static final EnumSerializer<RequestType> SERIALIZER = new EnumSerializer<>(RequestType.class);
@LauncherAPI @LauncherAPI
public static RequestType read(HInput input) throws IOException { public static RequestType read(HInput input) throws IOException {
return SERIALIZER.read(input); return SERIALIZER.read(input);

View file

@ -13,6 +13,7 @@ public final class UpdateAction extends StreamObject {
public enum Type implements EnumSerializer.Itf { public enum Type implements EnumSerializer.Itf {
CD(1), CD_BACK(2), GET(3), FINISH(255); CD(1), CD_BACK(2), GET(3), FINISH(255);
private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class); private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class);
public static Type read(HInput input) throws IOException { public static Type read(HInput input) throws IOException {
return SERIALIZER.read(input); return SERIALIZER.read(input);
} }
@ -28,6 +29,7 @@ public int getNumber() {
return n; return n;
} }
} }
public static final UpdateAction CD_BACK = new UpdateAction(Type.CD_BACK, null, null); public static final UpdateAction CD_BACK = new UpdateAction(Type.CD_BACK, null, null);
public static final UpdateAction FINISH = new UpdateAction(Type.FINISH, null, null); public static final UpdateAction FINISH = new UpdateAction(Type.FINISH, null, null);

View file

@ -22,6 +22,7 @@ public final class TextConfigReader {
public static BlockConfigEntry read(Reader reader, boolean ro) throws IOException { public static BlockConfigEntry read(Reader reader, boolean ro) throws IOException {
return new TextConfigReader(reader, ro).readBlock(0); return new TextConfigReader(reader, ro).readBlock(0);
} }
private final LineNumberReader reader; private final LineNumberReader reader;
private final boolean ro; private final boolean ro;
private String skipped; private String skipped;

View file

@ -19,6 +19,7 @@ public final class TextConfigWriter {
public static void write(BlockConfigEntry block, Writer writer, boolean comments) throws IOException { public static void write(BlockConfigEntry block, Writer writer, boolean comments) throws IOException {
new TextConfigWriter(writer, comments).writeBlock(block, false); new TextConfigWriter(writer, comments).writeBlock(block, false);
} }
private final Writer writer; private final Writer writer;
private final boolean comments; private final boolean comments;

View file

@ -15,6 +15,7 @@ public abstract class ConfigEntry<V> extends StreamObject {
public enum Type implements Itf { public enum Type implements Itf {
BLOCK(1), BOOLEAN(2), INTEGER(3), STRING(4), LIST(5); BLOCK(1), BOOLEAN(2), INTEGER(3), STRING(4), LIST(5);
private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class); private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class);
public static Type read(HInput input) throws IOException { public static Type read(HInput input) throws IOException {
return SERIALIZER.read(input); return SERIALIZER.read(input);
} }
@ -30,6 +31,7 @@ public int getNumber() {
return n; return n;
} }
} }
protected static ConfigEntry<?> readEntry(HInput input, boolean ro) throws IOException { protected static ConfigEntry<?> readEntry(HInput input, boolean ro) throws IOException {
Type type = Type.read(input); Type type = Type.read(input);
switch (type) { switch (type) {
@ -47,6 +49,7 @@ protected static ConfigEntry<?> readEntry(HInput input, boolean ro) throws IOExc
throw new AssertionError("Unsupported config entry type: " + type.name()); throw new AssertionError("Unsupported config entry type: " + type.name());
} }
} }
protected static void writeEntry(ConfigEntry<?> entry, HOutput output) throws IOException { protected static void writeEntry(ConfigEntry<?> entry, HOutput output) throws IOException {
EnumSerializer.write(output, entry.getType()); EnumSerializer.write(output, entry.getType());
entry.write(output); entry.write(output);

View file

@ -9,15 +9,10 @@
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
public class LauncherKeyStore { public class LauncherKeyStore {
public static KeyStore getKeyStore(String keystore,String password) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { public static KeyStore getKeyStore(String keystore, String password) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
KeyStore ks = KeyStore.getInstance("JKS"); KeyStore ks = KeyStore.getInstance("JKS");
InputStream ksIs = new FileInputStream(keystore); try (InputStream ksIs = new FileInputStream(keystore)) {
try {
ks.load(ksIs, password.toCharArray()); ks.load(ksIs, password.toCharArray());
} finally {
if (ksIs != null) {
ksIs.close();
}
} }
return ks; return ks;
} }

View file

@ -9,8 +9,9 @@ public class LauncherSSLContext {
public SSLServerSocketFactory ssf; public SSLServerSocketFactory ssf;
public SSLSocketFactory sf; public SSLSocketFactory sf;
private SSLContext sc; private SSLContext sc;
public LauncherSSLContext(KeyStore ks,String keypassword) throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, UnrecoverableKeyException, KeyManagementException {
TrustManager[] trustAllCerts = new TrustManager[] { public LauncherSSLContext(KeyStore ks, String keypassword) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException {
TrustManager[] trustAllCerts = new TrustManager[]{
new LauncherTrustManager() new LauncherTrustManager()
}; };
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
@ -21,8 +22,9 @@ public LauncherSSLContext(KeyStore ks,String keypassword) throws NoSuchAlgorithm
ssf = sc.getServerSocketFactory(); ssf = sc.getServerSocketFactory();
sf = sc.getSocketFactory(); sf = sc.getSocketFactory();
} }
public LauncherSSLContext() throws NoSuchAlgorithmException, KeyManagementException { public LauncherSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
TrustManager[] trustAllCerts = new TrustManager[] { TrustManager[] trustAllCerts = new TrustManager[]{
new LauncherTrustManager() new LauncherTrustManager()
}; };
SSLContext sc = SSLContext.getInstance("TLSv1.2"); SSLContext sc = SSLContext.getInstance("TLSv1.2");

View file

@ -15,13 +15,13 @@
public class SystemClassLoaderTransformer implements ClassFileTransformer { public class SystemClassLoaderTransformer implements ClassFileTransformer {
@Override @Override
public byte[] transform(ClassLoader classLoader, String classname, Class<?> aClass, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException { public byte[] transform(ClassLoader classLoader, String classname, Class<?> aClass, ProtectionDomain protectionDomain, byte[] bytes) {
if(classname.startsWith("ru/gravit/launcher/")) return bytes; if (classname.startsWith("ru/gravit/launcher/")) return bytes;
if(classname.startsWith("java/")) return bytes; if (classname.startsWith("java/")) return bytes;
if(classname.startsWith("sun/")) return bytes; if (classname.startsWith("sun/")) return bytes;
if(classname.startsWith("com/sun/")) return bytes; if (classname.startsWith("com/sun/")) return bytes;
if(classname.startsWith("javax/")) return bytes; if (classname.startsWith("javax/")) return bytes;
if(classname.startsWith("jdk/")) return bytes; if (classname.startsWith("jdk/")) return bytes;
try { try {
ClassPool pool = ClassPool.getDefault(); ClassPool pool = ClassPool.getDefault();
pool.appendClassPath(new LoaderClassPath(PublicURLClassLoader.systemclassloader)); pool.appendClassPath(new LoaderClassPath(PublicURLClassLoader.systemclassloader));
@ -34,15 +34,15 @@ public byte[] transform(ClassLoader classLoader, String classname, Class<?> aCla
cc.redirectMethodCall(m11, m21); // Указываем что на что нам нужно заменить cc.redirectMethodCall(m11, m21); // Указываем что на что нам нужно заменить
CtClass cl = pool.makeClass(new ByteArrayInputStream(bytes), false); // Загружаем класс, переданный для трансформации CtClass cl = pool.makeClass(new ByteArrayInputStream(bytes), false); // Загружаем класс, переданный для трансформации
if(cl.isFrozen()) return null; if (cl.isFrozen()) return null;
CtConstructor[] constructors = cl.getConstructors(); // Находим все конструкторы класса CtConstructor[] constructors = cl.getConstructors(); // Находим все конструкторы класса
for(CtConstructor constructor : constructors) for (CtConstructor constructor : constructors)
constructor.instrument(cc); // Заменяем вызовы constructor.instrument(cc); // Заменяем вызовы
CtMethod[] methods = cl.getDeclaredMethods(); // Находим все методы класса CtMethod[] methods = cl.getDeclaredMethods(); // Находим все методы класса
for(CtMethod method : methods) for (CtMethod method : methods)
method.instrument(cc); // Заменяем вызовы method.instrument(cc); // Заменяем вызовы
return cl.toBytecode(); return cl.toBytecode();
} catch (Exception ex) { } catch (Exception ignored) {
} }
return bytes; return bytes;

View file

@ -33,8 +33,8 @@ public HttpDownloader(URL url, String file) {
thread = downloader; thread = downloader;
downloader.start(); downloader.start();
} }
public synchronized String getFilename()
{ public synchronized String getFilename() {
return filename; return filename;
} }
@ -47,10 +47,10 @@ public void downloadFile(URL url, String file) throws IOException {
int writed_local = 0; int writed_local = 0;
while ((count = in.read(data, 0, BUFER_SIZE)) != -1) { while ((count = in.read(data, 0, BUFER_SIZE)) != -1) {
fout.write(data, 0, count); fout.write(data, 0, count);
writed_local+=count; writed_local += count;
if(System.currentTimeMillis() - timestamp > INTERVAL) { if (System.currentTimeMillis() - timestamp > INTERVAL) {
writed.set(writed_local); writed.set(writed_local);
LogHelper.debug("Downloaded %d",writed_local); LogHelper.debug("Downloaded %d", writed_local);
} }
} }
writed.set(writed_local); writed.set(writed_local);

View file

@ -4,14 +4,13 @@
import java.net.URLClassLoader; import java.net.URLClassLoader;
import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherAPI;
import ru.gravit.utils.helper.LogHelper;
public class PublicURLClassLoader extends URLClassLoader { public class PublicURLClassLoader extends URLClassLoader {
@LauncherAPI @LauncherAPI
public static ClassLoader systemclassloader = ClassLoader.getSystemClassLoader(); public static ClassLoader systemclassloader = ClassLoader.getSystemClassLoader();
@LauncherAPI @LauncherAPI
public static ClassLoader getSystemClassLoader() public static ClassLoader getSystemClassLoader() {
{
return systemclassloader; return systemclassloader;
} }
@ -38,6 +37,7 @@ public static ClassLoader getSystemClassLoader()
public PublicURLClassLoader(URL[] urls) { public PublicURLClassLoader(URL[] urls) {
super(urls); super(urls);
} }
/** /**
* Constructs a new URLClassLoader for the given URLs. The URLs will be * Constructs a new URLClassLoader for the given URLs. The URLs will be
* searched in the order specified for classes and resources after first * searched in the order specified for classes and resources after first
@ -62,6 +62,7 @@ public PublicURLClassLoader(URL[] urls) {
public PublicURLClassLoader(URL[] urls, ClassLoader parent) { public PublicURLClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent); super(urls, parent);
} }
@Override @Override
public void addURL(URL url) { public void addURL(URL url) {
super.addURL(url); super.addURL(url);

View file

@ -15,6 +15,7 @@ public class Version {
public final int build; public final int build;
@LauncherAPI @LauncherAPI
public final Type release; public final Type release;
@LauncherAPI @LauncherAPI
public Version(int major, int minor, int patch) { public Version(int major, int minor, int patch) {
this.major = major; this.major = major;
@ -23,6 +24,7 @@ public Version(int major, int minor, int patch) {
build = 0; build = 0;
release = Type.UNKNOWN; release = Type.UNKNOWN;
} }
@LauncherAPI @LauncherAPI
public Version(int major, int minor, int patch, int build) { public Version(int major, int minor, int patch, int build) {
this.major = major; this.major = major;
@ -31,6 +33,7 @@ public Version(int major, int minor, int patch, int build) {
this.build = build; this.build = build;
release = Type.UNKNOWN; release = Type.UNKNOWN;
} }
@LauncherAPI @LauncherAPI
public Version(int major, int minor, int patch, int build, Type release) { public Version(int major, int minor, int patch, int build, Type release) {
this.major = major; this.major = major;
@ -51,6 +54,7 @@ public boolean equals(Object o) {
patch == that.patch && patch == that.patch &&
build == that.build; build == that.build;
} }
@LauncherAPI @LauncherAPI
public String getVersionString() { public String getVersionString() {
return String.format("%d.%d.%d", major, minor, patch); return String.format("%d.%d.%d", major, minor, patch);
@ -61,46 +65,47 @@ public String getVersionString() {
public int hashCode() { public int hashCode() {
return Objects.hash(major, minor, patch, build); return Objects.hash(major, minor, patch, build);
} }
@LauncherAPI @LauncherAPI
public String getReleaseStatus() public String getReleaseStatus() {
{
String result; String result;
switch (release) { switch (release) {
case LTS: case LTS:
result="lts"; result = "lts";
break; break;
case STABLE: case STABLE:
result="stable"; result = "stable";
break; break;
case BETA: case BETA:
result="beta"; result = "beta";
break; break;
case ALPHA: case ALPHA:
result="alpha"; result = "alpha";
break; break;
case DEV: case DEV:
result="dev"; result = "dev";
break; break;
case EXPERIMENTAL: case EXPERIMENTAL:
result="experimental"; result = "experimental";
break; break;
case UNKNOWN: case UNKNOWN:
result=""; result = "";
break; break;
default: default:
result=""; result = "";
break; break;
} }
return result; return result;
} }
@Override @Override
@LauncherAPI @LauncherAPI
public String toString() { public String toString() {
return String.format("%d.%d.%d-%d %s", major, minor, patch, build,getReleaseStatus()); return String.format("%d.%d.%d-%d %s", major, minor, patch, build, getReleaseStatus());
} }
@LauncherAPI @LauncherAPI
public enum Type public enum Type {
{
LTS, LTS,
STABLE, STABLE,
BETA, BETA,

View file

@ -84,6 +84,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
return super.visitFile(file, attrs); return super.visitFile(file, attrs);
} }
} }
private static final class SkipHiddenVisitor implements FileVisitor<Path> { private static final class SkipHiddenVisitor implements FileVisitor<Path> {
private final FileVisitor<Path> visitor; private final FileVisitor<Path> visitor;

View file

@ -20,6 +20,7 @@ public final class JVMHelper {
@LauncherAPI @LauncherAPI
public enum OS { public enum OS {
MUSTDIE("mustdie"), LINUX("linux"), MACOSX("macosx"); MUSTDIE("mustdie"), LINUX("linux"), MACOSX("macosx");
public static OS byName(String name) { public static OS byName(String name) {
if (name.startsWith("Windows")) if (name.startsWith("Windows"))
return MUSTDIE; return MUSTDIE;
@ -36,6 +37,7 @@ public static OS byName(String name) {
this.name = name; this.name = name;
} }
} }
// MXBeans exports // MXBeans exports
@LauncherAPI @LauncherAPI
public static final RuntimeMXBean RUNTIME_MXBEAN = ManagementFactory.getRuntimeMXBean(); public static final RuntimeMXBean RUNTIME_MXBEAN = ManagementFactory.getRuntimeMXBean();

View file

@ -26,8 +26,10 @@
public final class LogHelper { public final class LogHelper {
@LauncherAPI @LauncherAPI
public static final String DEBUG_PROPERTY = "launcher.debug"; public static final String DEBUG_PROPERTY = "launcher.debug";
@LauncherAPI public static final String NO_JANSI_PROPERTY = "launcher.noJAnsi"; @LauncherAPI
@LauncherAPI public static final boolean JANSI; public static final String NO_JANSI_PROPERTY = "launcher.noJAnsi";
@LauncherAPI
public static final boolean JANSI;
// Output settings // Output settings
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss", Locale.US); private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss", Locale.US);
@ -53,7 +55,7 @@ public static void addOutput(Path file) throws IOException {
} }
@LauncherAPI @LauncherAPI
public static void addOutput(Writer writer) throws IOException { public static void addOutput(Writer writer) {
addOutput(new WriterOutput(writer)); addOutput(new WriterOutput(writer));
} }
@ -303,7 +305,7 @@ public String toString() {
} }
private static final class JAnsiOutput extends WriterOutput { private static final class JAnsiOutput extends WriterOutput {
private JAnsiOutput(OutputStream output) throws IOException { private JAnsiOutput(OutputStream output) {
super(IOHelper.newWriter(new AnsiOutputStream(output))); super(IOHelper.newWriter(new AnsiOutputStream(output)));
} }
} }

View file

@ -41,9 +41,11 @@ public enum DigestAlgorithm {
for (DigestAlgorithm algorithm : algorithmsValues) for (DigestAlgorithm algorithm : algorithmsValues)
ALGORITHMS.put(algorithm.name, algorithm); ALGORITHMS.put(algorithm.name, algorithm);
} }
public static DigestAlgorithm byName(String name) { public static DigestAlgorithm byName(String name) {
return VerifyHelper.getMapValue(ALGORITHMS, name, String.format("Unknown digest algorithm: '%s'", name)); return VerifyHelper.getMapValue(ALGORITHMS, name, String.format("Unknown digest algorithm: '%s'", name));
} }
// Instance // Instance
public final String name; public final String name;
@ -71,6 +73,7 @@ public byte[] verify(byte[] digest) {
return digest; return digest;
} }
} }
// Algorithm constants // Algorithm constants
@LauncherAPI @LauncherAPI
public static final String RSA_ALGO = "RSA"; public static final String RSA_ALGO = "RSA";