mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-22 16:41:46 +03:00
IDEA Refractoring
This commit is contained in:
parent
78766d0c5c
commit
8580cd4403
145 changed files with 1992 additions and 1860 deletions
|
@ -166,6 +166,7 @@ public void verify() {
|
|||
VerifyHelper.verify(getAddress(), VerifyHelper.NOT_EMPTY, "LaunchServer address can't be empty");
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExeConf extends ConfigObject {
|
||||
public final boolean enabled;
|
||||
public String productName;
|
||||
|
@ -201,6 +202,7 @@ private ExeConf(BlockConfigEntry block) {
|
|||
: String.format("%s, build %d", Launcher.getVersion().getVersionString(), Launcher.getVersion().build);
|
||||
}
|
||||
}
|
||||
|
||||
private final class ProfilesFileVisitor extends SimpleFileVisitor<Path> {
|
||||
private final Collection<SignedObjectHolder<ClientProfile>> result;
|
||||
|
||||
|
@ -224,6 +226,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
|||
return super.visitFile(file, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SignConf extends ConfigObject {
|
||||
public final boolean enabled;
|
||||
public String algo;
|
||||
|
@ -233,6 +236,7 @@ public static class SignConf extends ConfigObject {
|
|||
public boolean hasPass;
|
||||
public String pass;
|
||||
public String keyalias;
|
||||
|
||||
private SignConf(BlockConfigEntry block, Path coredir) {
|
||||
super(block);
|
||||
enabled = block.getEntryValue("enabled", BooleanConfigEntry.class);
|
||||
|
@ -249,6 +253,7 @@ private SignConf(BlockConfigEntry block, Path coredir) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Throwable {
|
||||
JVMHelper.verifySystemProperties(LaunchServer.class, true);
|
||||
LogHelper.addOutput(IOHelper.WORKING_DIR.resolve("LaunchServer.log"));
|
||||
|
@ -267,6 +272,7 @@ public static void main(String... args) throws Throwable {
|
|||
Instant end = Instant.now();
|
||||
LogHelper.debug("LaunchServer started in %dms", Duration.between(start, end).toMillis());
|
||||
}
|
||||
|
||||
// Constant paths
|
||||
@LauncherAPI
|
||||
public final Path dir;
|
||||
|
@ -462,11 +468,7 @@ public void close() {
|
|||
} catch (IOException e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
try {
|
||||
config.hwidHandler.close();
|
||||
} catch (IOException e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
modulesManager.close();
|
||||
// Print last message before death :(
|
||||
LogHelper.info("LaunchServer stopped");
|
||||
|
|
|
@ -10,24 +10,22 @@
|
|||
import java.nio.file.Paths;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.JVMHelper;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
import ru.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
public class ProguardConf {
|
||||
private static final String charsFirst = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
|
||||
private static final String chars = "1aAbBcC2dDeEfF3gGhHiI4jJkKl5mMnNoO6pPqQrR7sStT8uUvV9wWxX0yYzZ";
|
||||
|
||||
private static String generateString(SecureRandom rand, int il) {
|
||||
StringBuilder sb = new StringBuilder(il);
|
||||
sb.append(charsFirst.charAt(rand.nextInt(charsFirst.length())));
|
||||
for (int i = 0; i < il - 1; i++) sb.append(chars.charAt(rand.nextInt(chars.length())));
|
||||
return sb.toString();
|
||||
}
|
||||
private final LaunchServer srv;
|
||||
|
||||
public final Path proguard;
|
||||
public final Path config;
|
||||
public final Path mappings;
|
||||
|
@ -35,14 +33,14 @@ private static String generateString(SecureRandom rand, int il) {
|
|||
public final ArrayList<String> confStrs;
|
||||
|
||||
public ProguardConf(LaunchServer srv) {
|
||||
this.srv = srv;
|
||||
proguard = this.srv.dir.resolve("proguard");
|
||||
LaunchServer srv1 = srv;
|
||||
proguard = srv1.dir.resolve("proguard");
|
||||
config = proguard.resolve("proguard.config");
|
||||
mappings = proguard.resolve("mappings.pro");
|
||||
words = proguard.resolve("random.pro");
|
||||
confStrs = new ArrayList<>();
|
||||
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("-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\'");
|
||||
|
|
|
@ -23,10 +23,12 @@ public StarterVisitor(Instrumentation inst) {
|
|||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public static void premain(String agentArgument, Instrumentation inst) {
|
||||
try {
|
||||
Files.walkFileTree(Paths.get("libraries"), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new StarterVisitor(inst));
|
||||
|
|
|
@ -30,6 +30,7 @@ public boolean equals(Object obj) {
|
|||
return false;
|
||||
return value == other.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
|
@ -44,6 +45,7 @@ public String toString() {
|
|||
return String.format("AuthEntry {value=%s, ts=%s}", value, ts);
|
||||
}
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public static final long TIMEOUT = 10 * 60 * 1000; //10 минут
|
||||
public final int rateLimit;
|
||||
|
|
|
@ -45,7 +45,7 @@ public static void registerHandlers() {
|
|||
registerHandler("binaryFile", BinaryFileAuthHandler::new);
|
||||
registerHandler("textFile", TextFileAuthHandler::new);
|
||||
registerHandler("mysql", MySQLAuthHandler::new);
|
||||
registerHandler("json",JsonAuthHandler::new);
|
||||
registerHandler("json", JsonAuthHandler::new);
|
||||
registredHandl = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ public Entry(UUID uuid, String username, String accessToken, String serverID) {
|
|||
this.serverID = serverID == null ? null : VerifyHelper.verifyServerID(serverID);
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<UUID, Entry> entryCache = 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
|
||||
protected CachedAuthHandler(BlockConfigEntry 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
|
||||
|
@ -111,10 +113,11 @@ public synchronized boolean joinServer(String username, String accessToken, Stri
|
|||
entry.serverID = serverID;
|
||||
return true;
|
||||
}
|
||||
public synchronized void garbageCollection()
|
||||
{
|
||||
|
||||
public synchronized void garbageCollection() {
|
||||
entryCache.clear();
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
protected abstract boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException;
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ public void write(HOutput output) throws IOException {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public final Path file;
|
||||
@LauncherAPI
|
||||
|
|
|
@ -80,11 +80,12 @@ public UUID checkServer(String username, String serverID) throws IOException {
|
|||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean joinServer(String username, String accessToken, String serverID) throws IOException {
|
||||
JsonObject request = Json.object().add(userKeyName, username).add(serverIDKeyName, serverID).add(accessTokenKeyName, accessToken);
|
||||
HTTPRequest.jsonRequest(request, urlJoinServer);
|
||||
return request.getString(responseOKKeyName,null).equals("OK");
|
||||
return request.getString(responseOKKeyName, null).equals("OK");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -107,8 +108,8 @@ public String uuidToUsername(UUID uuid) throws IOException {
|
|||
throw new IOException("Service error");
|
||||
}
|
||||
|
||||
public JsonObject jsonRequestChecked(JsonObject object,URL url) throws IOException {
|
||||
JsonValue result = HTTPRequest.jsonRequest(object,url);
|
||||
public JsonObject jsonRequestChecked(JsonObject object, URL url) throws IOException {
|
||||
JsonValue result = HTTPRequest.jsonRequest(object, url);
|
||||
if (!result.isObject())
|
||||
authError("Authentication server response is malformed");
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package ru.gravit.launchserver.auth.hwid;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
|
|
@ -9,9 +9,11 @@ public class HWID {
|
|||
public static HWID fromData(HInput in) throws IOException {
|
||||
return gen(in.readLong(), in.readLong(), in.readLong());
|
||||
}
|
||||
|
||||
public static HWID gen(long hwid_hdd, long hwid_bios, long hwid_cpu) {
|
||||
return new HWID(hwid_hdd, hwid_bios, hwid_cpu);
|
||||
}
|
||||
|
||||
private long hwid_bios;
|
||||
|
||||
private long hwid_hdd;
|
||||
|
|
|
@ -29,17 +29,20 @@ public static void registerHandler(String name, Adapter<HWIDHandler> adapter) {
|
|||
VerifyHelper.putIfAbsent(HW_HANDLERS, name, Objects.requireNonNull(adapter, "adapter"),
|
||||
String.format("HWID handler has been already registered: '%s'", name));
|
||||
}
|
||||
|
||||
public static void registerHandlers() {
|
||||
if (!registredHandl) {
|
||||
registerHandler("accept", AcceptHWIDHandler::new);
|
||||
registerHandler("mysql",MysqlHWIDHandler::new);
|
||||
registerHandler("json",JsonHWIDHandler::new);
|
||||
registerHandler("mysql", MysqlHWIDHandler::new);
|
||||
registerHandler("json", JsonHWIDHandler::new);
|
||||
registredHandl = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected HWIDHandler(BlockConfigEntry block) {
|
||||
super(block);
|
||||
}
|
||||
|
||||
public abstract void ban(List<HWID> hwid) 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;
|
||||
|
||||
@Override
|
||||
public abstract void close() throws IOException;
|
||||
public abstract void close();
|
||||
|
||||
public abstract List<HWID> getHwid(String username) throws HWIDException;
|
||||
|
||||
|
|
|
@ -58,16 +58,17 @@ public final class JsonHWIDHandler extends HWIDHandler {
|
|||
|
||||
@Override
|
||||
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());
|
||||
try {
|
||||
request(request,urlBan);
|
||||
request(request, urlBan);
|
||||
} catch (IOException e) {
|
||||
LogHelper.error(e);
|
||||
throw new HWIDException("HWID service error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject request(JsonObject request, URL url) throws HWIDException, IOException {
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setDoInput(true);
|
||||
|
@ -97,18 +98,19 @@ public JsonObject request(JsonObject request, URL url) throws HWIDException, IOE
|
|||
JsonObject response = content.asObject();
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
try {
|
||||
response = request(request,url);
|
||||
response = request(request, url);
|
||||
} catch (IOException e) {
|
||||
LogHelper.error(e);
|
||||
throw new HWIDException("HWID service error");
|
||||
}
|
||||
boolean isBanned = response.getBoolean(isBannedKeyName,false);
|
||||
if(isBanned) throw new HWIDException("You will BANNED!");
|
||||
boolean isBanned = response.getBoolean(isBannedKeyName, false);
|
||||
if (isBanned) throw new HWIDException("You will BANNED!");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -118,24 +120,23 @@ public void close() {
|
|||
|
||||
@Override
|
||||
public List<HWID> getHwid(String username) throws HWIDException {
|
||||
JsonObject request = Json.object().add(loginKeyName,username);
|
||||
JsonObject request = Json.object().add(loginKeyName, username);
|
||||
JsonObject responce;
|
||||
try {
|
||||
responce = request(request,urlGet);
|
||||
responce = request(request, urlGet);
|
||||
} catch (IOException e) {
|
||||
LogHelper.error(e);
|
||||
throw new HWIDException("HWID service error");
|
||||
}
|
||||
JsonArray array = responce.get("hwids").asArray();
|
||||
ArrayList<HWID> hwids = new ArrayList<>();
|
||||
for(JsonValue i : array)
|
||||
{
|
||||
long hdd,cpu,bios;
|
||||
for (JsonValue i : array) {
|
||||
long hdd, cpu, bios;
|
||||
JsonObject object = i.asObject();
|
||||
hdd = object.getLong(hddKeyName,0);
|
||||
cpu = object.getLong(cpuKeyName,0);
|
||||
bios = object.getLong(biosKeyName,0);
|
||||
HWID hwid = HWID.gen(hdd,cpu,bios);
|
||||
hdd = object.getLong(hddKeyName, 0);
|
||||
cpu = object.getLong(cpuKeyName, 0);
|
||||
bios = object.getLong(biosKeyName, 0);
|
||||
HWID hwid = HWID.gen(hdd, cpu, bios);
|
||||
hwids.add(hwid);
|
||||
}
|
||||
return hwids;
|
||||
|
@ -143,10 +144,10 @@ public List<HWID> getHwid(String username) throws HWIDException {
|
|||
|
||||
@Override
|
||||
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());
|
||||
try {
|
||||
request(request,urlUnBan);
|
||||
request(request, urlUnBan);
|
||||
} catch (IOException e) {
|
||||
LogHelper.error(e);
|
||||
throw new HWIDException("HWID service error");
|
||||
|
|
|
@ -22,7 +22,7 @@ public class MysqlHWIDHandler extends HWIDHandler {
|
|||
private final String banMessage;
|
||||
private final String isBannedName;
|
||||
private final String loginName;
|
||||
private final String hddName,cpuName,biosName;
|
||||
private final String hddName, cpuName, biosName;
|
||||
private final String[] queryParams;
|
||||
private final String queryUpd;
|
||||
private final String[] queryParamsUpd;
|
||||
|
@ -72,7 +72,7 @@ public void check0(HWID hwid, String username) throws HWIDException {
|
|||
Connection c = mySQLHolder.getConnection();
|
||||
|
||||
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++) {
|
||||
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()) {
|
||||
boolean isOne = false;
|
||||
boolean needWrite = true;
|
||||
while(set.next()) {
|
||||
while (set.next()) {
|
||||
isOne = true;
|
||||
boolean isBanned = set.getBoolean(isBannedName);
|
||||
if (isBanned) throw new HWIDException(banMessage);
|
||||
|
@ -95,8 +95,7 @@ public void check0(HWID hwid, String username) throws HWIDException {
|
|||
writeHWID(hwid, username, c);
|
||||
return;
|
||||
}
|
||||
if(needWrite)
|
||||
{
|
||||
if (needWrite) {
|
||||
writeHWID(hwid, username, c);
|
||||
return;
|
||||
}
|
||||
|
@ -105,9 +104,9 @@ public void check0(HWID hwid, String username) throws HWIDException {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void writeHWID(HWID hwid, String username, Connection c)
|
||||
{
|
||||
LogHelper.debug("Write HWID %s from username %s",hwid.toString(),username);
|
||||
|
||||
public void writeHWID(HWID hwid, String username, Connection c) {
|
||||
LogHelper.debug("Write HWID %s from username %s", hwid.toString(), username);
|
||||
try (PreparedStatement a = c.prepareStatement(queryUpd)) {
|
||||
//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};
|
||||
|
@ -120,9 +119,9 @@ public void writeHWID(HWID hwid, String username, Connection c)
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void setIsBanned(HWID hwid,boolean isBanned)
|
||||
{
|
||||
LogHelper.debug("%s Request HWID: %s",isBanned ? "Ban" : "UnBan",hwid.toString());
|
||||
|
||||
public void setIsBanned(HWID hwid, boolean isBanned) {
|
||||
LogHelper.debug("%s Request HWID: %s", isBanned ? "Ban" : "UnBan", hwid.toString());
|
||||
Connection c = null;
|
||||
try {
|
||||
c = mySQLHolder.getConnection();
|
||||
|
@ -141,36 +140,35 @@ public void setIsBanned(HWID hwid,boolean isBanned)
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void ban(List<HWID> list) throws HWIDException {
|
||||
|
||||
for(HWID hwid : list)
|
||||
{
|
||||
setIsBanned(hwid,true);
|
||||
@Override
|
||||
public void ban(List<HWID> list) {
|
||||
|
||||
for (HWID hwid : list) {
|
||||
setIsBanned(hwid, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unban(List<HWID> list) throws HWIDException {
|
||||
for(HWID hwid : list)
|
||||
{
|
||||
setIsBanned(hwid,false);
|
||||
public void unban(List<HWID> list) {
|
||||
for (HWID hwid : list) {
|
||||
setIsBanned(hwid, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HWID> getHwid(String username) throws HWIDException {
|
||||
public List<HWID> getHwid(String username) {
|
||||
try {
|
||||
LogHelper.debug("Try find HWID from username %s",username);
|
||||
LogHelper.debug("Try find HWID from username %s", username);
|
||||
Connection c = mySQLHolder.getConnection();
|
||||
PreparedStatement s = c.prepareStatement(querySelect);
|
||||
String[] replaceParams = {"login", username};
|
||||
for (int i = 0; i < queryParamsSelect.length; i++) {
|
||||
s.setString(i + 1, CommonHelper.replace(queryParamsSelect[i], replaceParams));
|
||||
}
|
||||
long hdd,cpu,bios;
|
||||
long hdd, cpu, bios;
|
||||
try (ResultSet set = s.executeQuery()) {
|
||||
if(!set.next()) {
|
||||
if (!set.next()) {
|
||||
LogHelper.error(new HWIDException("HWID not found"));
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
@ -179,11 +177,12 @@ public List<HWID> getHwid(String username) throws HWIDException {
|
|||
bios = set.getLong(biosName);
|
||||
}
|
||||
ArrayList<HWID> list = new ArrayList<>();
|
||||
HWID hwid = HWID.gen(hdd,bios,cpu);
|
||||
if(hdd == 0 && cpu == 0 && bios == 0) {LogHelper.warning("Null HWID");}
|
||||
else {
|
||||
HWID hwid = HWID.gen(hdd, bios, cpu);
|
||||
if (hdd == 0 && cpu == 0 && bios == 0) {
|
||||
LogHelper.warning("Null HWID");
|
||||
} else {
|
||||
list.add(hwid);
|
||||
LogHelper.debug("Username: %s HWID: %s",username,hwid.toString());
|
||||
LogHelper.debug("Username: %s HWID: %s", username, hwid.toString());
|
||||
}
|
||||
return list;
|
||||
} catch (SQLException e) {
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
package ru.gravit.launchserver.auth.provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonObject;
|
||||
|
@ -49,7 +44,7 @@ public final class JsonAuthProvider extends AuthProvider {
|
|||
@Override
|
||||
public AuthProviderResult auth(String login, String password, String ip) throws IOException {
|
||||
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())
|
||||
return authError("Authentication server response is malformed");
|
||||
|
||||
|
|
|
@ -17,28 +17,31 @@ public BuildContext(ZipOutputStream output, JAConfigurator config) {
|
|||
this.output = output;
|
||||
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);
|
||||
output.putNextEntry(zip);
|
||||
IOHelper.transfer(inputStream,output);
|
||||
IOHelper.transfer(inputStream, output);
|
||||
}
|
||||
|
||||
public void pushJarFile(JarInputStream input) throws IOException {
|
||||
ZipEntry e = input.getNextEntry();
|
||||
while (e != null) {
|
||||
output.putNextEntry(e);
|
||||
IOHelper.transfer(input,output);
|
||||
IOHelper.transfer(input, output);
|
||||
e = input.getNextEntry();
|
||||
}
|
||||
}
|
||||
|
||||
public void pushJarFile(JarInputStream input, Set<String> blacklist) throws IOException {
|
||||
ZipEntry e = input.getNextEntry();
|
||||
while (e != null) {
|
||||
if(blacklist.contains(e.getName())){
|
||||
if (blacklist.contains(e.getName())) {
|
||||
e = input.getNextEntry();
|
||||
continue;
|
||||
}
|
||||
output.putNextEntry(e);
|
||||
IOHelper.transfer(input,output);
|
||||
IOHelper.transfer(input, output);
|
||||
e = input.getNextEntry();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,10 +113,11 @@ private void setConfig() {
|
|||
// Return prepared config
|
||||
ConfigPersister.getInstance().setAntConfig(config, null);
|
||||
}
|
||||
|
||||
private static String VERSION = Launcher.getVersion().getVersionString();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ public class JAConfigurator implements AutoCloseable {
|
|||
StringBuilder body;
|
||||
StringBuilder moduleBody;
|
||||
int autoincrement;
|
||||
|
||||
public JAConfigurator(Class<?> configclass) throws NotFoundException {
|
||||
classname = configclass.getName();
|
||||
ctClass = pool.get(classname);
|
||||
|
@ -22,8 +23,8 @@ public JAConfigurator(Class<?> configclass) throws NotFoundException {
|
|||
moduleBody = new StringBuilder("{ isInitModules = true; ");
|
||||
autoincrement = 0;
|
||||
}
|
||||
public void addModuleClass(String fullName)
|
||||
{
|
||||
|
||||
public void addModuleClass(String fullName) {
|
||||
moduleBody.append("ru.gravit.launcher.modules.Module mod");
|
||||
moduleBody.append(autoincrement);
|
||||
moduleBody.append(" = new ");
|
||||
|
@ -34,10 +35,12 @@ public void addModuleClass(String fullName)
|
|||
moduleBody.append(" , true );");
|
||||
autoincrement++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
ctClass.defrost();
|
||||
}
|
||||
|
||||
public byte[] getBytecode() throws IOException, CannotCompileException {
|
||||
body.append("}");
|
||||
moduleBody.append("}");
|
||||
|
@ -45,31 +48,30 @@ public byte[] getBytecode() throws IOException, CannotCompileException {
|
|||
initModuleMethod.insertAfter(moduleBody.toString());
|
||||
return ctClass.toBytecode();
|
||||
}
|
||||
public String getZipEntryPath()
|
||||
{
|
||||
return classname.replace('.','/').concat(".class");
|
||||
|
||||
public String getZipEntryPath() {
|
||||
return classname.replace('.', '/').concat(".class");
|
||||
}
|
||||
public void setAddress(String address)
|
||||
{
|
||||
|
||||
public void setAddress(String address) {
|
||||
body.append("this.address = \"");
|
||||
body.append(address);
|
||||
body.append("\";");
|
||||
}
|
||||
public void setProjectName(String name)
|
||||
{
|
||||
|
||||
public void setProjectName(String name) {
|
||||
body.append("this.projectname = \"");
|
||||
body.append(name);
|
||||
body.append("\";");
|
||||
}
|
||||
|
||||
public void setPort(int port)
|
||||
{
|
||||
public void setPort(int port) {
|
||||
body.append("this.port = ");
|
||||
body.append(port);
|
||||
body.append(";");
|
||||
}
|
||||
public ClassPool getPool()
|
||||
{
|
||||
|
||||
public ClassPool getPool() {
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ protected LauncherBinary(LaunchServer server, Path binaryFile) {
|
|||
this.binaryFile = binaryFile;
|
||||
syncBinaryFile = binaryFile;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
protected LauncherBinary(LaunchServer server, Path binaryFile, Path syncBinaryFile) {
|
||||
this.server = server;
|
||||
|
|
|
@ -59,7 +59,9 @@
|
|||
* </pre>
|
||||
*/
|
||||
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 final OutputStream out;
|
||||
private final MessageDigest hasher;
|
||||
|
@ -97,6 +99,7 @@ public void write(int b) throws IOException {
|
|||
hasher.update((byte) b);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String MANIFEST_FN = "META-INF/MANIFEST.MF";
|
||||
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";
|
||||
|
||||
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 {
|
||||
KeyStore st = KeyStore.getInstance(algo);
|
||||
st.load(IOHelper.newInput(file), storepass != null ? storepass.toCharArray() : null);
|
||||
return st;
|
||||
} catch (NoSuchAlgorithmException | CertificateException| KeyStoreException e) {
|
||||
} catch (NoSuchAlgorithmException | CertificateException | KeyStoreException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
private final static MessageDigest hasher() {
|
||||
|
||||
private static MessageDigest hasher() {
|
||||
try {
|
||||
return MessageDigest.getInstance(hashFunctionName);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final ZipOutputStream zos;
|
||||
|
||||
private final KeyStore keyStore;
|
||||
|
@ -153,6 +158,7 @@ public SignerJar(OutputStream out, KeyStore keyStore, String keyAlias, String ke
|
|||
fileDigests = 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
|
||||
* the stream is closed.
|
||||
|
@ -252,7 +258,9 @@ public void close() throws IOException {
|
|||
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 {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
|
@ -288,7 +296,9 @@ public ZipOutputStream getZos() {
|
|||
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 {
|
||||
Manifest manifest = new Manifest();
|
||||
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));
|
||||
}
|
||||
|
||||
/** 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 {
|
||||
Manifest manifest = new Manifest();
|
||||
manifest.getMainAttributes().putAll(attributes);
|
||||
|
@ -314,22 +326,29 @@ private String hashMainSection(Attributes attributes) throws IOException {
|
|||
public String toString() {
|
||||
return "NullOutputStream";
|
||||
}
|
||||
|
||||
/** Discards the specified byte array. */
|
||||
@Override public void write(byte[] b) {
|
||||
@Override
|
||||
public void write(byte[] b) {
|
||||
}
|
||||
|
||||
/** 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. */
|
||||
@Override public void write(int b) {
|
||||
@Override
|
||||
public void write(int b) {
|
||||
}
|
||||
}, hasher);
|
||||
manifest.write(o);
|
||||
return Base64.getEncoder().encodeToString(hasher.digest());
|
||||
}
|
||||
|
||||
/** Returns the CMS signed data. */
|
||||
/**
|
||||
* Returns the CMS signed data.
|
||||
*/
|
||||
private byte[] signSigFile(byte[] sigContents) throws Exception {
|
||||
CMSSignedDataGenerator gen = createSignedDataGenerator();
|
||||
CMSTypedData cmsData = new CMSProcessableByteArray(sigContents);
|
||||
|
|
|
@ -23,7 +23,7 @@ public String getUsageDescription() {
|
|||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args,1);
|
||||
verifyArgs(args, 1);
|
||||
List<HWID> target = server.config.hwidHandler.getHwid(args[0]);
|
||||
server.config.hwidHandler.ban(target);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public String getUsageDescription() {
|
|||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args,1);
|
||||
verifyArgs(args, 1);
|
||||
List<HWID> target = server.config.hwidHandler.getHwid(args[0]);
|
||||
server.config.hwidHandler.unban(target);
|
||||
}
|
||||
|
|
|
@ -3,16 +3,14 @@
|
|||
import ru.gravit.launchserver.LaunchServer;
|
||||
import ru.gravit.launchserver.command.Command;
|
||||
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 TestCommand(LaunchServer server) {
|
||||
super(server);
|
||||
}
|
||||
|
||||
NettyServerSocketHandler handler;
|
||||
|
||||
@Override
|
||||
public String getArgsDescription() {
|
||||
return null;
|
||||
|
@ -25,11 +23,10 @@ public String getUsageDescription() {
|
|||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args,1);
|
||||
if(handler == null)
|
||||
verifyArgs(args, 1);
|
||||
if (handler == null)
|
||||
handler = new NettyServerSocketHandler(server);
|
||||
if(args[0].equals("start"))
|
||||
{
|
||||
if (args[0].equals("start")) {
|
||||
handler.run();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ protected CommandHandler(LaunchServer server) {
|
|||
registerCommand("logConnections", new LogConnectionsCommand(server));
|
||||
registerCommand("loadModule", new LoadModuleCommand(server));
|
||||
registerCommand("modules", new ModulesCommand(server));
|
||||
registerCommand("test",new TestCommand(server));
|
||||
registerCommand("test", new TestCommand(server));
|
||||
|
||||
// Register sync commands
|
||||
registerCommand("indexAsset", new IndexAssetCommand(server));
|
||||
|
|
|
@ -48,6 +48,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
|||
return super.visitFile(file, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
public static final String INDEXES_DIR = "indexes";
|
||||
public static final String OBJECTS_DIR = "objects";
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ public String getUsageDescription() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
public void invoke(String... args) {
|
||||
server.modulesManager.printModules();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ public final class LaunchServerPluginBridge implements Runnable, AutoCloseable {
|
|||
* Err text.
|
||||
*/
|
||||
public static final String nonInitText = "Лаунчсервер не был полностью загружен";
|
||||
|
||||
static {
|
||||
//SecurityHelper.verifyCertificates(LaunchServer.class);
|
||||
JVMHelper.verifySystemProperties(LaunchServer.class, false);
|
||||
|
|
|
@ -12,20 +12,20 @@
|
|||
|
||||
public class BuildHookManager {
|
||||
@FunctionalInterface
|
||||
public interface PostBuildHook
|
||||
{
|
||||
public interface PostBuildHook {
|
||||
void build(BuildContext context);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PreBuildHook
|
||||
{
|
||||
public interface PreBuildHook {
|
||||
void build(BuildContext context);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Transformer
|
||||
{
|
||||
public interface Transformer {
|
||||
byte[] transform(byte[] input, CharSequence classname);
|
||||
}
|
||||
|
||||
private boolean BUILDRUNTIME;
|
||||
private final Set<PostBuildHook> POST_HOOKS;
|
||||
private final Set<PreBuildHook> PRE_HOOKS;
|
||||
|
@ -33,6 +33,7 @@ public interface Transformer
|
|||
private final Set<String> CLASS_BLACKLIST;
|
||||
private final Set<String> MODULE_CLASS;
|
||||
private final Map<String, byte[]> INCLUDE_CLASS;
|
||||
|
||||
public BuildHookManager() {
|
||||
POST_HOOKS = new HashSet<>(4);
|
||||
PRE_HOOKS = new HashSet<>(4);
|
||||
|
@ -47,61 +48,65 @@ public BuildHookManager() {
|
|||
registerIgnoredClass("META-INF/NOTICE");
|
||||
registerClientModuleClass(TestClientModule.class.getName());
|
||||
}
|
||||
public void autoRegisterIgnoredClass(String clazz)
|
||||
{
|
||||
CLASS_BLACKLIST.add(clazz.replace('.','/').concat(".class"));
|
||||
|
||||
public void autoRegisterIgnoredClass(String clazz) {
|
||||
CLASS_BLACKLIST.add(clazz.replace('.', '/').concat(".class"));
|
||||
}
|
||||
|
||||
public boolean buildRuntime() {
|
||||
return BUILDRUNTIME;
|
||||
}
|
||||
public byte[] classTransform(byte[] clazz, CharSequence classname)
|
||||
{
|
||||
|
||||
public byte[] classTransform(byte[] clazz, CharSequence classname) {
|
||||
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;
|
||||
}
|
||||
|
||||
public void registerIncludeClass(String classname, byte[] classdata) {
|
||||
INCLUDE_CLASS.put(classname, classdata);
|
||||
}
|
||||
|
||||
public Map<String, byte[]> getIncludeClass() {
|
||||
return INCLUDE_CLASS;
|
||||
}
|
||||
public boolean isContainsBlacklist(String clazz)
|
||||
{
|
||||
|
||||
public boolean isContainsBlacklist(String clazz) {
|
||||
return CLASS_BLACKLIST.contains(clazz);
|
||||
}
|
||||
public void postHook(BuildContext context)
|
||||
{
|
||||
for(PostBuildHook hook : POST_HOOKS) hook.build(context);
|
||||
|
||||
public void postHook(BuildContext context) {
|
||||
for (PostBuildHook hook : POST_HOOKS) hook.build(context);
|
||||
}
|
||||
public void preHook(BuildContext context)
|
||||
{
|
||||
for(PreBuildHook hook : PRE_HOOKS) hook.build(context);
|
||||
|
||||
public void preHook(BuildContext context) {
|
||||
for (PreBuildHook hook : PRE_HOOKS) hook.build(context);
|
||||
}
|
||||
public void registerAllClientModuleClass(JAConfigurator cfg)
|
||||
{
|
||||
for(String clazz : MODULE_CLASS) cfg.addModuleClass(clazz);
|
||||
|
||||
public void registerAllClientModuleClass(JAConfigurator cfg) {
|
||||
for (String clazz : MODULE_CLASS) cfg.addModuleClass(clazz);
|
||||
}
|
||||
public void registerClassTransformer(Transformer transformer)
|
||||
{
|
||||
|
||||
public void registerClassTransformer(Transformer transformer) {
|
||||
CLASS_TRANSFORMER.add(transformer);
|
||||
}
|
||||
public void registerClientModuleClass(String clazz)
|
||||
{
|
||||
|
||||
public void registerClientModuleClass(String clazz) {
|
||||
MODULE_CLASS.add(clazz);
|
||||
}
|
||||
public void registerIgnoredClass(String clazz)
|
||||
{
|
||||
|
||||
public void registerIgnoredClass(String clazz) {
|
||||
CLASS_BLACKLIST.add(clazz);
|
||||
}
|
||||
public void registerPostHook(PostBuildHook hook)
|
||||
{
|
||||
|
||||
public void registerPostHook(PostBuildHook hook) {
|
||||
POST_HOOKS.add(hook);
|
||||
}
|
||||
public void registerPreHook(PreBuildHook hook)
|
||||
{
|
||||
|
||||
public void registerPreHook(PreBuildHook hook) {
|
||||
PRE_HOOKS.add(hook);
|
||||
}
|
||||
|
||||
public void setBuildRuntime(boolean runtime) {
|
||||
BUILDRUNTIME = runtime;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ public ModulesManager(LaunchServer lsrv) {
|
|||
classloader = new PublicURLClassLoader(new URL[0], ClassLoader.getSystemClassLoader());
|
||||
context = new LaunchServerModuleContext(lsrv, classloader);
|
||||
}
|
||||
|
||||
private void registerCoreModule() {
|
||||
load(new CoreModule());
|
||||
}
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
public class LaunchServerModuleContext implements ModuleContext {
|
||||
public final LaunchServer launchServer;
|
||||
public final PublicURLClassLoader classloader;
|
||||
public LaunchServerModuleContext(LaunchServer server, PublicURLClassLoader classloader)
|
||||
{
|
||||
|
||||
public LaunchServerModuleContext(LaunchServer server, PublicURLClassLoader classloader) {
|
||||
launchServer = server;
|
||||
this.classloader = classloader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.LAUNCHSERVER;
|
||||
|
|
|
@ -17,7 +17,7 @@ public String getName() {
|
|||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return new Version(1,0,0,0, Version.Type.UNKNOWN);
|
||||
return new Version(1, 0, 0, 0, Version.Type.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,13 +28,17 @@ public interface Factory<R> {
|
|||
@LauncherAPI
|
||||
Response newResponse(LaunchServer server, long id, HInput input, HOutput output, String ip);
|
||||
}
|
||||
|
||||
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) {
|
||||
return RESPONSES.get(type).newResponse(server, session, input, output, ip);
|
||||
}
|
||||
|
||||
public static void registerResponse(int type, Factory<?> factory) {
|
||||
RESPONSES.put(type, factory);
|
||||
}
|
||||
|
||||
public static void registerResponses() {
|
||||
registerResponse(RequestType.PING.getNumber(), PingResponse::new);
|
||||
registerResponse(RequestType.AUTH.getNumber(), AuthResponse::new);
|
||||
|
@ -50,6 +54,7 @@ public static void registerResponses() {
|
|||
registerResponse(RequestType.UPDATE.getNumber(), UpdateResponse::new);
|
||||
registerResponse(RequestType.PROFILES.getNumber(), ProfilesResponse::new);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public static void requestError(String message) throws RequestException {
|
||||
throw new RequestException(message);
|
||||
|
|
|
@ -68,9 +68,9 @@ public void reply() throws Exception {
|
|||
return;
|
||||
}
|
||||
Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles();
|
||||
for(SignedObjectHolder<ClientProfile> p : profiles)
|
||||
if(p.object.getTitle().equals(client))
|
||||
if(!p.object.isWhitelistContains(login))
|
||||
for (SignedObjectHolder<ClientProfile> p : profiles)
|
||||
if (p.object.getTitle().equals(client))
|
||||
if (!p.object.isWhitelistContains(login))
|
||||
throw new AuthException(server.config.whitelistRejectString);
|
||||
server.config.hwidHandler.check(HWID.gen(hwid_hdd, hwid_bios, hwid_cpu), result.username);
|
||||
} catch (AuthException | HWIDException e) {
|
||||
|
|
|
@ -25,7 +25,7 @@ public void reply() throws IOException {
|
|||
Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles();
|
||||
output.writeLength(profiles.size(), 0);
|
||||
for (SignedObjectHolder<ClientProfile> profile : profiles) {
|
||||
LogHelper.debug("Writted profile: %s",profile.object.getTitle());
|
||||
LogHelper.debug("Writted profile: %s", profile.object.getTitle());
|
||||
profile.write(output);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ public class Client {
|
|||
public long session;
|
||||
|
||||
public long timestamp;
|
||||
|
||||
public Client(long session) {
|
||||
this.session = session;
|
||||
timestamp = System.currentTimeMillis();
|
||||
|
|
|
@ -15,9 +15,6 @@
|
|||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
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.LauncherTrustManager;
|
||||
import ru.gravit.launchserver.LaunchServer;
|
||||
|
@ -55,8 +52,6 @@ public final class NettyServerSocketHandler implements Runnable, AutoCloseable {
|
|||
@LauncherAPI
|
||||
public volatile boolean logConnections = Boolean.getBoolean("launcher.logConnections");
|
||||
|
||||
// Instance
|
||||
private final LaunchServer server;
|
||||
private final AtomicReference<ServerSocket> serverSocket = new AtomicReference<>();
|
||||
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 AtomicLong idCounter = new AtomicLong(0L);
|
||||
private Set<Socket> sockets;
|
||||
private Selector selector;
|
||||
private ServerSocketChannel serverChannel;
|
||||
private volatile Listener listener;
|
||||
|
||||
public NettyServerSocketHandler(LaunchServer server) {
|
||||
this.server = server;
|
||||
// Instance
|
||||
LaunchServer server1 = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -86,10 +80,10 @@ public void close() {
|
|||
}
|
||||
|
||||
public SSLContext SSLContextInit() throws NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, KeyManagementException, IOException, CertificateException {
|
||||
TrustManager[] trustAllCerts = new TrustManager[] {
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new LauncherTrustManager()
|
||||
};
|
||||
KeyStore ks = LauncherKeyStore.getKeyStore("keystore","PSP1000");
|
||||
KeyStore ks = LauncherKeyStore.getKeyStore("keystore", "PSP1000");
|
||||
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
|
||||
.getDefaultAlgorithm());
|
||||
|
@ -120,8 +114,8 @@ public void run() {
|
|||
//System.setProperty( "javax.net.ssl.keyStore","keystore");
|
||||
//System.setProperty( "javax.net.ssl.keyStorePassword","PSP1000");
|
||||
try {
|
||||
selector = Selector.open();
|
||||
serverChannel = ServerSocketChannel.open();
|
||||
Selector selector = Selector.open();
|
||||
ServerSocketChannel serverChannel = ServerSocketChannel.open();
|
||||
serverChannel.configureBlocking(false);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -138,7 +132,7 @@ public void run() {
|
|||
.handler(new LoggingHandler(LogLevel.DEBUG))
|
||||
.childHandler(new ChannelInitializer<NioSocketChannel>() {
|
||||
@Override
|
||||
public void initChannel(NioSocketChannel ch) throws Exception {
|
||||
public void initChannel(NioSocketChannel ch) {
|
||||
ChannelPipeline pipeline = ch.pipeline();
|
||||
//p.addLast(new LoggingHandler(LogLevel.INFO));
|
||||
System.out.println("P!");
|
||||
|
|
|
@ -26,6 +26,7 @@ public Handshake(int type, long session) {
|
|||
this.session = session;
|
||||
}
|
||||
}
|
||||
|
||||
private final LaunchServer server;
|
||||
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
|
||||
session = 0;
|
||||
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;
|
||||
legacy = true;
|
||||
}
|
||||
else if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY){
|
||||
} else if (magicNumber == Launcher.PROTOCOL_MAGIC_LEGACY) {
|
||||
|
||||
} else
|
||||
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));
|
||||
}
|
||||
// Read request type
|
||||
Integer type = input.readVarInt();
|
||||
int type = input.readVarInt();
|
||||
if (!server.serverSocketHandler.onHandshake(session, type)) {
|
||||
output.writeBoolean(false);
|
||||
return null;
|
||||
|
|
|
@ -28,6 +28,7 @@ public interface Listener {
|
|||
@LauncherAPI
|
||||
boolean onHandshake(long session, Integer type);
|
||||
}
|
||||
|
||||
private static final ThreadFactory THREAD_FACTORY = r -> CommonHelper.newThread("Network Thread", true, r);
|
||||
|
||||
@LauncherAPI
|
||||
|
|
|
@ -13,11 +13,13 @@
|
|||
|
||||
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
|
||||
static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) {
|
||||
LogHelper.debug("New client %s", IOHelper.getIP(ctx.channel().remoteAddress()));
|
||||
channels.add(ctx.channel());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception {
|
||||
// ping and pong frames already handled
|
||||
|
@ -26,6 +28,6 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) thr
|
|||
long handshake = input.readLong();
|
||||
long connection_flags = input.readLong();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public WebSocketIndexPageHandler(String websocketPath) {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
|
||||
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) {
|
||||
// Handle a bad request.
|
||||
if (!req.decoderResult().isSuccess()) {
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST));
|
||||
|
|
|
@ -24,6 +24,7 @@ private static Texture getTexture(String url, boolean cloak) throws IOException
|
|||
return null; // Simply not found
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTextureURL(String url, UUID uuid, String username, String client) {
|
||||
return CommonHelper.replace(url, "username", IOHelper.urlEncode(username),
|
||||
"uuid", IOHelper.urlEncode(uuid.toString()), "hash", IOHelper.urlEncode(Launcher.toHash(uuid)),
|
||||
|
|
|
@ -10,9 +10,11 @@ public enum Type {
|
|||
CAPE,
|
||||
ELYTRA
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
private static String baseName(String url) {
|
||||
String name = url.substring(url.lastIndexOf('/') + 1);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ public static CompatProfile fromPlayerProfile(PlayerProfile profile) {
|
|||
profile.cloak == null ? null : SecurityHelper.toHex(profile.cloak.digest)
|
||||
);
|
||||
}
|
||||
|
||||
// Instance
|
||||
public final UUID uuid;
|
||||
public final String uuidHash, username;
|
||||
|
|
|
@ -171,9 +171,11 @@ public GameProfile hasJoinedServer(GameProfile profile, String serverID) throws
|
|||
public GameProfile hasJoinedServer(GameProfile profile, String serverID, InetAddress address) throws AuthenticationUnavailableException {
|
||||
return hasJoinedServer(profile, serverID);
|
||||
}
|
||||
|
||||
public YggdrasilAuthenticationService getAuthenticationService() {
|
||||
return (YggdrasilAuthenticationService)super.getAuthenticationService();
|
||||
return (YggdrasilAuthenticationService) super.getAuthenticationService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void joinServer(GameProfile profile, String accessToken, String serverID) throws AuthenticationException {
|
||||
if (!ClientLauncher.isLaunched())
|
||||
|
|
|
@ -40,6 +40,7 @@ public void run() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final String NAME = Launcher.getConfig().projectname;
|
||||
public static String avn32 = null, avn64 = 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(NAME + "32.exe"), "wrapper32.exe"),
|
||||
handle(path.resolve(NAME + "64.exe"), "wrapper64.exe"));
|
||||
HashedDir guard = new HashedDir(path,null,true,false);
|
||||
try(DirWatcher dirWatcher = new DirWatcher(path, guard, null, false)){
|
||||
HashedDir guard = new HashedDir(path, null, true, false);
|
||||
try (DirWatcher dirWatcher = new DirWatcher(path, guard, null, false)) {
|
||||
CommonHelper.newThread("Guard Directory Watcher", true, dirWatcher).start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,6 +161,7 @@ public static void main(String... args) throws Throwable {
|
|||
Instant end = Instant.now();
|
||||
LogHelper.debug("Launcher started in %dms", Duration.between(start, end).toMillis());
|
||||
}
|
||||
|
||||
// Instance
|
||||
private final AtomicBoolean started = new AtomicBoolean(false);
|
||||
|
||||
|
@ -175,7 +176,7 @@ public Object loadScript(String path) throws IOException, ScriptException {
|
|||
URL url = Launcher.getResourceURL(path);
|
||||
LogHelper.debug("Loading script: '%s'", 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
|||
return super.visitFile(file, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Params extends StreamObject {
|
||||
// Client paths
|
||||
@LauncherAPI
|
||||
|
@ -147,6 +148,7 @@ public void write(HOutput output) throws IOException {
|
|||
output.writeVarInt(height);
|
||||
}
|
||||
}
|
||||
|
||||
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 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, "--assetsDir", params.assetDir.toString());
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public static void checkJVMBitsAndVersion() {
|
||||
if (JVMHelper.JVM_BITS != JVMHelper.OS_BITS) {
|
||||
|
@ -264,6 +267,7 @@ public static void checkJVMBitsAndVersion() {
|
|||
JOptionPane.showMessageDialog(null, error);
|
||||
}
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public static boolean isLaunched() {
|
||||
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)
|
||||
LogHelper.debug("Writing ClientLauncher params");
|
||||
Path paramsFile = Files.createTempFile("ClientLauncherParams", ".bin");
|
||||
CommonHelper.newThread("Client params writter",false,() ->
|
||||
CommonHelper.newThread("Client params writter", false, () ->
|
||||
{
|
||||
try {
|
||||
try (ServerSocket socket = new ServerSocket()) {
|
||||
|
@ -338,8 +342,9 @@ public static Process launch(
|
|||
List<String> args = new LinkedList<>();
|
||||
boolean wrapper = isUsingWrapper();
|
||||
Path javaBin;
|
||||
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");
|
||||
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");
|
||||
args.add(javaBin.toString());
|
||||
args.add(MAGICAL_INTEL_OPTION);
|
||||
if (params.ram > 0 && params.ram <= JVMHelper.RAM) {
|
||||
|
@ -366,7 +371,7 @@ public static Process launch(
|
|||
classPathString.append(File.pathSeparatorChar).append(path.toString());
|
||||
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,"-javaagent:".concat(pathLauncher));
|
||||
Collections.addAll(args, "-javaagent:".concat(pathLauncher));
|
||||
//Collections.addAll(args, "-classpath", classPathString.toString());
|
||||
//if(wrapper)
|
||||
//Collections.addAll(args, "-Djava.class.path=".concat(classPathString.toString())); // Add Class Path
|
||||
|
@ -379,7 +384,7 @@ public static Process launch(
|
|||
// Build client process
|
||||
LogHelper.debug("Launching client instance");
|
||||
ProcessBuilder builder = new ProcessBuilder(args);
|
||||
if(wrapper)
|
||||
if (wrapper)
|
||||
builder.environment().put("JAVA_HOME", System.getProperty("java.home"));
|
||||
//else
|
||||
//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);
|
||||
}
|
||||
}
|
||||
} catch (IOException ex)
|
||||
{
|
||||
} catch (IOException ex) {
|
||||
LogHelper.error(ex);
|
||||
try (HInput input = new HInput(IOHelper.newInput(paramsFile))) {
|
||||
params = new Params(input);
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
|
||||
public class ClientModuleContext implements ModuleContext {
|
||||
public final LauncherEngine engine;
|
||||
ClientModuleContext(LauncherEngine engine)
|
||||
{
|
||||
|
||||
ClientModuleContext(LauncherEngine engine) {
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.CLIENT;
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
import ru.gravit.launcher.modules.SimpleModuleManager;
|
||||
|
||||
public class ClientModuleManager extends SimpleModuleManager {
|
||||
public ClientModuleManager(LauncherEngine engine)
|
||||
{
|
||||
public ClientModuleManager(LauncherEngine engine) {
|
||||
context = new ClientModuleContext(engine);
|
||||
modules = new ArrayList<>();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
@SuppressWarnings("AbstractClassNeverImplemented")
|
||||
public abstract class JSApplication extends Application {
|
||||
private static final AtomicReference<JSApplication> INSTANCE = new AtomicReference<>();
|
||||
|
||||
@LauncherAPI
|
||||
public static JSApplication getInstance() {
|
||||
return INSTANCE.get();
|
||||
|
|
|
@ -43,12 +43,14 @@ public boolean isOverfilled() {
|
|||
return onlinePlayers >= maxPlayers;
|
||||
}
|
||||
}
|
||||
|
||||
// Constants
|
||||
private static final String LEGACY_PING_HOST_MAGIC = "§1";
|
||||
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 int PACKET_LENGTH = 65535;
|
||||
|
||||
private static String readUTF16String(HInput input) throws IOException {
|
||||
int length = input.readUnsignedShort() << 1;
|
||||
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.stream.write(s.getBytes(StandardCharsets.UTF_16BE));
|
||||
}
|
||||
|
||||
// Instance
|
||||
private final InetSocketAddress address;
|
||||
private final ClientProfile.Version version;
|
||||
|
|
|
@ -75,6 +75,7 @@ public StyleableProperty<Number> getStyleableProperty(ProgressCircleIndicator n)
|
|||
};
|
||||
|
||||
public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
|
||||
|
||||
static {
|
||||
final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData());
|
||||
styleables.add(INNER_CIRCLE_RADIUS);
|
||||
|
@ -83,9 +84,6 @@ public StyleableProperty<Number> getStyleableProperty(ProgressCircleIndicator n)
|
|||
}
|
||||
|
||||
@LauncherAPI
|
||||
/**
|
||||
* @return The CssMetaData associated with this class, which may include the CssMetaData of its super classes.
|
||||
*/
|
||||
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
|
||||
return StyleableProperties.STYLEABLES;
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ public StyleableProperty<Number> getStyleableProperty(RingProgressIndicator n) {
|
|||
};
|
||||
|
||||
public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
|
||||
|
||||
static {
|
||||
final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData());
|
||||
styleables.addAll(getClassCssMetaData());
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* @author Andrea Vacondio
|
||||
*
|
||||
*/
|
||||
@LauncherAPI
|
||||
public class RingProgressIndicatorSkin implements Skin<RingProgressIndicator> {
|
||||
|
@ -29,6 +28,7 @@ public class RingProgressIndicatorSkin implements Skin<RingProgressIndicator> {
|
|||
private final StackPane container = new StackPane();
|
||||
private final Arc fillerArc = new Arc();
|
||||
private final RotateTransition transition = new RotateTransition(Duration.millis(2000), fillerArc);
|
||||
|
||||
@LauncherAPI
|
||||
public RingProgressIndicatorSkin(final RingProgressIndicator indicator) {
|
||||
this.indicator = indicator;
|
||||
|
@ -108,16 +108,19 @@ private void initIndeterminate(boolean newVal) {
|
|||
transition.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public RingProgressIndicator getSkinnable() {
|
||||
return indicator;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public Node getNode() {
|
||||
return container;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import com.sun.javafx.collections.NonIterableChange;
|
||||
import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList;
|
||||
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.collections.ListChangeListener;
|
||||
|
@ -104,6 +103,7 @@ public int size() {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public void check(int index) {
|
||||
|
@ -114,23 +114,27 @@ public void check(int index) {
|
|||
checkedIndicesList.callObservers(
|
||||
new NonIterableChange.SimpleAddChange<>(changeIndex, changeIndex + 1, checkedIndicesList));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(T item) {
|
||||
int index = getItemIndex(item);
|
||||
check(index);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public void checkAll() {
|
||||
for (int i = 0; i < getItemCount(); i++)
|
||||
check(i);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public void checkIndices(int... indices) {
|
||||
for (int indice : indices)
|
||||
check(indice);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public void clearCheck(int index) {
|
||||
|
@ -142,57 +146,69 @@ public void clearCheck(int index) {
|
|||
checkedIndicesList.callObservers(
|
||||
new NonIterableChange.SimpleRemovedChange<>(changeIndex, changeIndex, index, checkedIndicesList));
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public void clearCheck(T item) {
|
||||
int index = getItemIndex(item);
|
||||
clearCheck(index);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public void clearChecks() {
|
||||
for (int index = 0; index < checkedIndices.length(); index++)
|
||||
clearCheck(index);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public ObservableList<Integer> getCheckedIndices() {
|
||||
return checkedIndicesList;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public ObservableList<T> getCheckedItems() {
|
||||
return checkedItemsList;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public abstract T getItem(int index);
|
||||
|
||||
@LauncherAPI
|
||||
BooleanProperty getItemBooleanProperty(T item) {
|
||||
return itemBooleanMap.get(item);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public abstract int getItemCount();
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public abstract int getItemIndex(T item);
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public boolean isChecked(int index) {
|
||||
return checkedIndices.get(index);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public boolean isChecked(T item) {
|
||||
int index = getItemIndex(item);
|
||||
return isChecked(index);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return checkedIndices.isEmpty();
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public void toggleCheckState(int index) {
|
||||
|
@ -208,6 +224,7 @@ public void toggleCheckState(T item) {
|
|||
int index = getItemIndex(item);
|
||||
toggleCheckState(index);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
protected void updateMap() {
|
||||
itemBooleanMap.clear();
|
||||
|
|
|
@ -50,6 +50,7 @@ public int getItemIndex(T item) {
|
|||
return items.indexOf(item);
|
||||
}
|
||||
}
|
||||
|
||||
private final ObservableList<T> items;
|
||||
private final Map<T, BooleanProperty> itemBooleanMap;
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@ public class CheckComboBoxSkin<T> extends BehaviorSkinBase<CheckComboBox<T>, Beh
|
|||
private final ListCell<T> buttonCell;
|
||||
|
||||
private final CheckComboBox<T> control;
|
||||
private final ObservableList<T> items;
|
||||
private final ReadOnlyUnbackedObservableList<Integer> selectedIndices;
|
||||
private final ReadOnlyUnbackedObservableList<T> selectedItems;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -34,9 +32,9 @@ public CheckComboBoxSkin(final CheckComboBox<T> control) {
|
|||
super(control, new BehaviorBase<>(control, Collections.emptyList()));
|
||||
|
||||
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();
|
||||
|
||||
comboBox = new ComboBox<T>(items) {
|
||||
|
@ -143,8 +141,7 @@ protected boolean isHideOnClickEnabled() {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
@SuppressWarnings("unchecked")
|
||||
final ListView<T> listView = (ListView<T>) comboBoxListViewSkin.getPopupContent();
|
||||
@SuppressWarnings("unchecked") final ListView<T> listView = (ListView<T>) comboBoxListViewSkin.getPopupContent();
|
||||
listView.setOnKeyPressed(e -> {
|
||||
if (e.getCode() == KeyCode.SPACE) {
|
||||
T item = listView.getSelectionModel().getSelectedItem();
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
|
||||
public abstract class Request<R> {
|
||||
private static final long session = SecurityHelper.secureRandom.nextLong();
|
||||
|
||||
@LauncherAPI
|
||||
public static void requestError(String message) throws RequestException {
|
||||
throw new RequestException(message);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
protected final LauncherConfig config;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ private Result(PlayerProfile pp, String accessToken) {
|
|||
this.accessToken = accessToken;
|
||||
}
|
||||
}
|
||||
|
||||
private final String login;
|
||||
|
||||
private final byte[] encryptedPassword;
|
||||
|
|
|
@ -46,6 +46,7 @@ public byte[] getSign() {
|
|||
return sign.clone();
|
||||
}
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public static final Path BINARY_PATH = IOHelper.getCodeSource(Launcher.class);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ public ProfilesRequest(LauncherConfig config) {
|
|||
public Integer getType() {
|
||||
return RequestType.PROFILES.getNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result requestDo(HInput input, HOutput output) throws Exception {
|
||||
output.writeBoolean(true);
|
||||
|
|
|
@ -41,6 +41,7 @@ public static final class State {
|
|||
public interface Callback {
|
||||
void call(State state);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public final long fileDownloaded;
|
||||
@LauncherAPI
|
||||
|
@ -166,6 +167,7 @@ public double getTotalSizeMiB() {
|
|||
return getTotalSizeKiB() / 1024.0D;
|
||||
}
|
||||
}
|
||||
|
||||
private static void fillActionsQueue(Queue<UpdateAction> queue, HashedDir mismatch) {
|
||||
for (Entry<String, HashedEntry> mapEntry : mismatch.map().entrySet()) {
|
||||
String name = mapEntry.getKey();
|
||||
|
@ -185,6 +187,7 @@ private static void fillActionsQueue(Queue<UpdateAction> queue, HashedDir mismat
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Instance
|
||||
private final String dirName;
|
||||
private final Path dir;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
public class ServerWrapper {
|
||||
public static ModulesManager modulesManager;
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
ServerWrapper wrapper = new ServerWrapper();
|
||||
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))));
|
||||
modulesManager.preInitModules();
|
||||
ProfilesRequest.Result result = new ProfilesRequest(cfg).request();
|
||||
for(SignedObjectHolder<ClientProfile> p : result.profiles)
|
||||
{
|
||||
LogHelper.debug("Get profile: %s",p.object.getTitle());
|
||||
if(p.object.getTitle().equals(ClientLauncher.title)) {
|
||||
for (SignedObjectHolder<ClientProfile> p : result.profiles) {
|
||||
LogHelper.debug("Get profile: %s", p.object.getTitle());
|
||||
if (p.object.getTitle().equals(ClientLauncher.title)) {
|
||||
wrapper.profile = p.object;
|
||||
LogHelper.debug("Found profile: %s",ClientLauncher.title);
|
||||
LogHelper.debug("Found profile: %s", ClientLauncher.title);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -40,9 +40,10 @@ public static void main(String[] args) throws Throwable {
|
|||
Class<?> mainClass = Class.forName(classname);
|
||||
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
|
||||
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();
|
||||
mainMethod.invoke(real_args);
|
||||
}
|
||||
|
||||
public ClientProfile profile;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
public static UUID toUUID(String username) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(Arrays.copyOf(username.getBytes(StandardCharsets.US_ASCII), 16));
|
||||
return new UUID(buffer.getLong(), buffer.getLong()); // MOST, LEAST
|
||||
}
|
||||
public static UUID toUUID(String username){
|
||||
ByteBuffer buffer=ByteBuffer.wrap(Arrays.copyOf(username.getBytes(StandardCharsets.US_ASCII),16));
|
||||
return new UUID(buffer.getLong(),buffer.getLong()); // MOST, LEAST
|
||||
}
|
||||
|
||||
public static String toUsername(UUID uuid) {
|
||||
byte[] bytes = ByteBuffer.allocate(16).
|
||||
public static String toUsername(UUID uuid){
|
||||
byte[]bytes=ByteBuffer.allocate(16).
|
||||
putLong(uuid.getMostSignificantBits()).
|
||||
putLong(uuid.getLeastSignificantBits()).array();
|
||||
|
||||
// Find username end
|
||||
int length = 0;
|
||||
while(length < bytes.length && bytes[length] != 0) {
|
||||
int length=0;
|
||||
while(length<bytes.length&&bytes[length]!=0){
|
||||
length++;
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
|
|
@ -5,12 +5,13 @@ public class AutogenConfig {
|
|||
public String address;
|
||||
public int port;
|
||||
private boolean isInitModules;
|
||||
|
||||
AutogenConfig() {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnnecessaryReturnStatement")
|
||||
public void initModules()
|
||||
{
|
||||
if(isInitModules) return;
|
||||
public void initModules() {
|
||||
if (isInitModules) return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ static int readBuildNumber() {
|
|||
return 0; // Maybe dev env?
|
||||
}
|
||||
}
|
||||
|
||||
private static final AtomicReference<LauncherConfig> CONFIG = new AtomicReference<>();
|
||||
@LauncherAPI
|
||||
public static ModulesManagerInterface modulesManager = null;
|
||||
|
@ -85,6 +86,6 @@ public static String toHash(UUID uuid) {
|
|||
}
|
||||
|
||||
public static Version getVersion() {
|
||||
return new Version(MAJOR,MINOR,PATCH,BUILD,RELEASE);
|
||||
return new Version(MAJOR, MINOR, PATCH, BUILD, RELEASE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,17 +13,18 @@
|
|||
@LauncherAPI
|
||||
public class LauncherAgent {
|
||||
private static final boolean enabled = false;
|
||||
private static boolean isAgentStarted=false;
|
||||
private static boolean isAgentStarted = false;
|
||||
public static Instrumentation inst;
|
||||
|
||||
public static void addJVMClassPath(String path) throws IOException {
|
||||
LogHelper.debug("Launcher Agent addJVMClassPath");
|
||||
inst.appendToSystemClassLoaderSearch(new JarFile(path));
|
||||
}
|
||||
public boolean isAgentStarted()
|
||||
{
|
||||
|
||||
public boolean isAgentStarted() {
|
||||
return isAgentStarted;
|
||||
}
|
||||
|
||||
public static long getObjSize(Object obj) {
|
||||
return inst.getObjectSize(obj);
|
||||
}
|
||||
|
@ -33,7 +34,7 @@ public static void premain(String agentArgument, Instrumentation instrumentation
|
|||
inst = instrumentation;
|
||||
isAgentStarted = true;
|
||||
|
||||
if(ClassFile.MAJOR_VERSION > ClassFile.JAVA_8 || enabled) {
|
||||
if (ClassFile.MAJOR_VERSION > ClassFile.JAVA_8 || enabled) {
|
||||
inst.addTransformer(new SystemClassLoaderTransformer());
|
||||
Class<?>[] classes = inst.getAllLoadedClasses(); // Получаем список уже загруженных классов, которые могут быть изменены. Классы, которые ещё не загружены, будут изменены при загрузке
|
||||
ArrayList<Class<?>> classList = new ArrayList<>();
|
||||
|
|
|
@ -23,11 +23,12 @@ public final class LauncherConfig extends StreamObject {
|
|||
@LauncherAPI
|
||||
public static final String ADDRESS_OVERRIDE = System.getProperty(ADDRESS_OVERRIDE_PROPERTY, null);
|
||||
private static final AutogenConfig config = new AutogenConfig();
|
||||
|
||||
@LauncherAPI
|
||||
public static AutogenConfig getAutogenConfig()
|
||||
{
|
||||
public static AutogenConfig getAutogenConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
// Instance
|
||||
@LauncherAPI
|
||||
public final InetSocketAddress address;
|
||||
|
@ -38,6 +39,7 @@ public static AutogenConfig getAutogenConfig()
|
|||
|
||||
@LauncherAPI
|
||||
public final Map<String, byte[]> runtime;
|
||||
|
||||
@LauncherAPI
|
||||
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
|
||||
String localAddress = config.address;
|
||||
|
@ -60,14 +62,16 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException
|
|||
if (ADDRESS_OVERRIDE != null)
|
||||
LogHelper.warning("Address override is enabled: '%s'", ADDRESS_OVERRIDE);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@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.publicKey = Objects.requireNonNull(publicKey, "publicKey");
|
||||
this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime));
|
||||
this.projectname = projectname;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter")
|
||||
public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<String, byte[]> runtime) {
|
||||
|
|
|
@ -63,15 +63,18 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
|
|||
private static final Kind<?>[] KINDS = {
|
||||
StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE
|
||||
};
|
||||
|
||||
private static void handleError(Throwable e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
|
||||
private static Deque<String> toPath(Iterable<Path> path) {
|
||||
Deque<String> result = new LinkedList<>();
|
||||
for (Path pe : path)
|
||||
result.add(pe.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
// Instance
|
||||
private final Path dir;
|
||||
private final HashedDir hdir;
|
||||
|
|
|
@ -18,6 +18,7 @@ private static boolean anyMatch(String[] entries, Collection<String> path) {
|
|||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
// Instance
|
||||
private final String[] update;
|
||||
private final String[] verify;
|
||||
|
|
|
@ -13,6 +13,7 @@ public abstract class HashedEntry extends StreamObject {
|
|||
public enum Type implements Itf {
|
||||
DIR(1), FILE(2);
|
||||
private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class);
|
||||
|
||||
public static Type read(HInput input) throws IOException {
|
||||
return SERIALIZER.read(input);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ public Entry(NeedGarbageCollection invoke, long timer) {
|
|||
this.timer = timer;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Timer timer = new Timer("GarbageTimer");
|
||||
|
||||
private static final ArrayList<Entry> NEED_GARBARE_COLLECTION = new ArrayList<>();
|
||||
|
|
|
@ -9,6 +9,7 @@ public interface Module extends AutoCloseable {
|
|||
Version getVersion();
|
||||
|
||||
int getPriority();
|
||||
|
||||
void init(ModuleContext context);
|
||||
|
||||
void postInit(ModuleContext context);
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
public interface ModuleContext {
|
||||
enum Type {
|
||||
SERVER,CLIENT,LAUNCHSERVER
|
||||
SERVER, CLIENT, LAUNCHSERVER
|
||||
}
|
||||
|
||||
Type getType();
|
||||
|
||||
ModulesManagerInterface getModulesManager();
|
||||
}
|
||||
|
|
|
@ -3,14 +3,23 @@
|
|||
import java.net.URL;
|
||||
|
||||
public interface ModulesManagerInterface {
|
||||
void initModules() throws Exception;
|
||||
void load(Module module) throws Exception;
|
||||
void load(Module module, boolean preload) throws Exception;
|
||||
void initModules();
|
||||
|
||||
void load(Module module);
|
||||
|
||||
void load(Module module, boolean preload);
|
||||
|
||||
void loadModule(URL jarpath, boolean preload) throws Exception;
|
||||
|
||||
void loadModule(URL jarpath, String classname, boolean preload) throws Exception;
|
||||
void postInitModules() throws Exception;
|
||||
void preInitModules() throws Exception;
|
||||
void printModules() throws Exception;
|
||||
|
||||
void postInitModules();
|
||||
|
||||
void preInitModules();
|
||||
|
||||
void printModules();
|
||||
|
||||
void sort();
|
||||
void registerModule(Module module,boolean preload) throws Exception;
|
||||
|
||||
void registerModule(Module module, boolean preload);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
public class SimpleModuleManager implements ModulesManagerInterface,AutoCloseable {
|
||||
public class SimpleModuleManager implements ModulesManagerInterface, AutoCloseable {
|
||||
protected final class ModulesVisitor extends SimpleFileVisitor<Path> {
|
||||
private ModulesVisitor() {
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
|||
return super.visitFile(file, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Module> modules;
|
||||
public PublicURLClassLoader classloader;
|
||||
protected ModuleContext context;
|
||||
|
@ -48,9 +49,8 @@ public void autoload(Path dir) throws IOException {
|
|||
LogHelper.info("Loaded %d modules", modules.size());
|
||||
}
|
||||
|
||||
public void sort()
|
||||
{
|
||||
modules.sort((m1,m2) -> {
|
||||
public void sort() {
|
||||
modules.sort((m1, m2) -> {
|
||||
int p1 = m1.getPriority();
|
||||
int p2 = m2.getPriority();
|
||||
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();
|
||||
modules.add(module);
|
||||
module.preInit(context);
|
||||
if(!preload) module.init(context);
|
||||
LogHelper.info("Module %s version: %s loaded",module.getName(),module.getVersion());
|
||||
if (!preload) module.init(context);
|
||||
LogHelper.info("Module %s version: %s loaded", module.getName(), module.getVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -142,9 +142,8 @@ public void printModules() {
|
|||
|
||||
@Override
|
||||
@LauncherAPI
|
||||
public void registerModule(Module module,boolean preload)
|
||||
{
|
||||
public void registerModule(Module module, boolean 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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
public class TestClientModule implements Module {
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -32,12 +32,14 @@ public enum Version {
|
|||
MC113("1.13", 393),
|
||||
MC1131("1.13.1", 401);
|
||||
private static final Map<String, Version> VERSIONS;
|
||||
|
||||
static {
|
||||
Version[] versionsValues = values();
|
||||
VERSIONS = new HashMap<>(versionsValues.length);
|
||||
for (Version version : versionsValues)
|
||||
VERSIONS.put(version.name, version);
|
||||
}
|
||||
|
||||
public static Version byName(String name) {
|
||||
return VerifyHelper.getMapValue(VERSIONS, name, String.format("Unknown client version: '%s'", name));
|
||||
}
|
||||
|
@ -56,6 +58,7 @@ public String toString() {
|
|||
return "Minecraft " + name;
|
||||
}
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public static final StreamObject.Adapter<ClientProfile> RO_ADAPTER = input -> new ClientProfile(input, true);
|
||||
|
||||
|
@ -157,6 +160,7 @@ public FileNameMatcher getClientUpdateMatcher() {
|
|||
public String[] getJvmArgs() {
|
||||
return jvmArgs.stream(StringConfigEntry.class).toArray(String[]::new);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public String getMainClass() {
|
||||
return mainClass.getValue();
|
||||
|
@ -198,9 +202,8 @@ public boolean isUpdateFastCheck() {
|
|||
}
|
||||
|
||||
@LauncherAPI
|
||||
public boolean isWhitelistContains(String username)
|
||||
{
|
||||
if(!useWhitelist.getValue()) return true;
|
||||
public boolean isWhitelistContains(String username) {
|
||||
if (!useWhitelist.getValue()) return true;
|
||||
return whitelist.stream(StringConfigEntry.class).anyMatch(e -> e.equals(username));
|
||||
}
|
||||
|
||||
|
|
|
@ -16,10 +16,12 @@ public final class PlayerProfile extends StreamObject {
|
|||
public static PlayerProfile newOfflineProfile(String username) {
|
||||
return new PlayerProfile(offlineUUID(username), username, null, null);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public static UUID offlineUUID(String username) {
|
||||
return UUID.nameUUIDFromBytes(IOHelper.encodeASCII("OfflinePlayer:" + username));
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public final UUID uuid;
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ public enum RequestType implements EnumSerializer.Itf {
|
|||
PROFILES(10),
|
||||
CUSTOM(255); // Custom requests
|
||||
private static final EnumSerializer<RequestType> SERIALIZER = new EnumSerializer<>(RequestType.class);
|
||||
|
||||
@LauncherAPI
|
||||
public static RequestType read(HInput input) throws IOException {
|
||||
return SERIALIZER.read(input);
|
||||
|
|
|
@ -13,6 +13,7 @@ public final class UpdateAction extends StreamObject {
|
|||
public enum Type implements EnumSerializer.Itf {
|
||||
CD(1), CD_BACK(2), GET(3), FINISH(255);
|
||||
private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class);
|
||||
|
||||
public static Type read(HInput input) throws IOException {
|
||||
return SERIALIZER.read(input);
|
||||
}
|
||||
|
@ -28,6 +29,7 @@ public int getNumber() {
|
|||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
public static final UpdateAction CD_BACK = new UpdateAction(Type.CD_BACK, null, null);
|
||||
|
||||
public static final UpdateAction FINISH = new UpdateAction(Type.FINISH, null, null);
|
||||
|
|
|
@ -22,6 +22,7 @@ public final class TextConfigReader {
|
|||
public static BlockConfigEntry read(Reader reader, boolean ro) throws IOException {
|
||||
return new TextConfigReader(reader, ro).readBlock(0);
|
||||
}
|
||||
|
||||
private final LineNumberReader reader;
|
||||
private final boolean ro;
|
||||
private String skipped;
|
||||
|
|
|
@ -19,6 +19,7 @@ public final class TextConfigWriter {
|
|||
public static void write(BlockConfigEntry block, Writer writer, boolean comments) throws IOException {
|
||||
new TextConfigWriter(writer, comments).writeBlock(block, false);
|
||||
}
|
||||
|
||||
private final Writer writer;
|
||||
|
||||
private final boolean comments;
|
||||
|
|
|
@ -15,6 +15,7 @@ public abstract class ConfigEntry<V> extends StreamObject {
|
|||
public enum Type implements Itf {
|
||||
BLOCK(1), BOOLEAN(2), INTEGER(3), STRING(4), LIST(5);
|
||||
private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class);
|
||||
|
||||
public static Type read(HInput input) throws IOException {
|
||||
return SERIALIZER.read(input);
|
||||
}
|
||||
|
@ -30,6 +31,7 @@ public int getNumber() {
|
|||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
protected static ConfigEntry<?> readEntry(HInput input, boolean ro) throws IOException {
|
||||
Type type = Type.read(input);
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
protected static void writeEntry(ConfigEntry<?> entry, HOutput output) throws IOException {
|
||||
EnumSerializer.write(output, entry.getType());
|
||||
entry.write(output);
|
||||
|
|
|
@ -9,15 +9,10 @@
|
|||
import java.security.cert.CertificateException;
|
||||
|
||||
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");
|
||||
InputStream ksIs = new FileInputStream(keystore);
|
||||
try {
|
||||
try (InputStream ksIs = new FileInputStream(keystore)) {
|
||||
ks.load(ksIs, password.toCharArray());
|
||||
} finally {
|
||||
if (ksIs != null) {
|
||||
ksIs.close();
|
||||
}
|
||||
}
|
||||
return ks;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,9 @@ public class LauncherSSLContext {
|
|||
public SSLServerSocketFactory ssf;
|
||||
public SSLSocketFactory sf;
|
||||
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()
|
||||
};
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
|
||||
|
@ -21,8 +22,9 @@ public LauncherSSLContext(KeyStore ks,String keypassword) throws NoSuchAlgorithm
|
|||
ssf = sc.getServerSocketFactory();
|
||||
sf = sc.getSocketFactory();
|
||||
}
|
||||
|
||||
public LauncherSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
|
||||
TrustManager[] trustAllCerts = new TrustManager[] {
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new LauncherTrustManager()
|
||||
};
|
||||
SSLContext sc = SSLContext.getInstance("TLSv1.2");
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
|
||||
public class SystemClassLoaderTransformer implements ClassFileTransformer {
|
||||
@Override
|
||||
public byte[] transform(ClassLoader classLoader, String classname, Class<?> aClass, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException {
|
||||
if(classname.startsWith("ru/gravit/launcher/")) return bytes;
|
||||
if(classname.startsWith("java/")) return bytes;
|
||||
if(classname.startsWith("sun/")) return bytes;
|
||||
if(classname.startsWith("com/sun/")) return bytes;
|
||||
if(classname.startsWith("javax/")) return bytes;
|
||||
if(classname.startsWith("jdk/")) return bytes;
|
||||
public byte[] transform(ClassLoader classLoader, String classname, Class<?> aClass, ProtectionDomain protectionDomain, byte[] bytes) {
|
||||
if (classname.startsWith("ru/gravit/launcher/")) return bytes;
|
||||
if (classname.startsWith("java/")) return bytes;
|
||||
if (classname.startsWith("sun/")) return bytes;
|
||||
if (classname.startsWith("com/sun/")) return bytes;
|
||||
if (classname.startsWith("javax/")) return bytes;
|
||||
if (classname.startsWith("jdk/")) return bytes;
|
||||
try {
|
||||
ClassPool pool = ClassPool.getDefault();
|
||||
pool.appendClassPath(new LoaderClassPath(PublicURLClassLoader.systemclassloader));
|
||||
|
@ -34,15 +34,15 @@ public byte[] transform(ClassLoader classLoader, String classname, Class<?> aCla
|
|||
cc.redirectMethodCall(m11, m21); // Указываем что на что нам нужно заменить
|
||||
|
||||
CtClass cl = pool.makeClass(new ByteArrayInputStream(bytes), false); // Загружаем класс, переданный для трансформации
|
||||
if(cl.isFrozen()) return null;
|
||||
if (cl.isFrozen()) return null;
|
||||
CtConstructor[] constructors = cl.getConstructors(); // Находим все конструкторы класса
|
||||
for(CtConstructor constructor : constructors)
|
||||
for (CtConstructor constructor : constructors)
|
||||
constructor.instrument(cc); // Заменяем вызовы
|
||||
CtMethod[] methods = cl.getDeclaredMethods(); // Находим все методы класса
|
||||
for(CtMethod method : methods)
|
||||
for (CtMethod method : methods)
|
||||
method.instrument(cc); // Заменяем вызовы
|
||||
return cl.toBytecode();
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return bytes;
|
||||
|
|
|
@ -33,8 +33,8 @@ public HttpDownloader(URL url, String file) {
|
|||
thread = downloader;
|
||||
downloader.start();
|
||||
}
|
||||
public synchronized String getFilename()
|
||||
{
|
||||
|
||||
public synchronized String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
@ -47,10 +47,10 @@ public void downloadFile(URL url, String file) throws IOException {
|
|||
int writed_local = 0;
|
||||
while ((count = in.read(data, 0, BUFER_SIZE)) != -1) {
|
||||
fout.write(data, 0, count);
|
||||
writed_local+=count;
|
||||
if(System.currentTimeMillis() - timestamp > INTERVAL) {
|
||||
writed_local += count;
|
||||
if (System.currentTimeMillis() - timestamp > INTERVAL) {
|
||||
writed.set(writed_local);
|
||||
LogHelper.debug("Downloaded %d",writed_local);
|
||||
LogHelper.debug("Downloaded %d", writed_local);
|
||||
}
|
||||
}
|
||||
writed.set(writed_local);
|
||||
|
|
|
@ -4,14 +4,13 @@
|
|||
import java.net.URLClassLoader;
|
||||
|
||||
import ru.gravit.launcher.LauncherAPI;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class PublicURLClassLoader extends URLClassLoader {
|
||||
@LauncherAPI
|
||||
public static ClassLoader systemclassloader = ClassLoader.getSystemClassLoader();
|
||||
|
||||
@LauncherAPI
|
||||
public static ClassLoader getSystemClassLoader()
|
||||
{
|
||||
public static ClassLoader getSystemClassLoader() {
|
||||
return systemclassloader;
|
||||
}
|
||||
|
||||
|
@ -38,6 +37,7 @@ public static ClassLoader getSystemClassLoader()
|
|||
public PublicURLClassLoader(URL[] urls) {
|
||||
super(urls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new URLClassLoader for the given URLs. The URLs will be
|
||||
* searched in the order specified for classes and resources after first
|
||||
|
@ -62,6 +62,7 @@ public PublicURLClassLoader(URL[] urls) {
|
|||
public PublicURLClassLoader(URL[] urls, ClassLoader parent) {
|
||||
super(urls, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addURL(URL url) {
|
||||
super.addURL(url);
|
||||
|
|
|
@ -15,6 +15,7 @@ public class Version {
|
|||
public final int build;
|
||||
@LauncherAPI
|
||||
public final Type release;
|
||||
|
||||
@LauncherAPI
|
||||
public Version(int major, int minor, int patch) {
|
||||
this.major = major;
|
||||
|
@ -23,6 +24,7 @@ public Version(int major, int minor, int patch) {
|
|||
build = 0;
|
||||
release = Type.UNKNOWN;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public Version(int major, int minor, int patch, int build) {
|
||||
this.major = major;
|
||||
|
@ -31,6 +33,7 @@ public Version(int major, int minor, int patch, int build) {
|
|||
this.build = build;
|
||||
release = Type.UNKNOWN;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public Version(int major, int minor, int patch, int build, Type release) {
|
||||
this.major = major;
|
||||
|
@ -51,6 +54,7 @@ public boolean equals(Object o) {
|
|||
patch == that.patch &&
|
||||
build == that.build;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public String getVersionString() {
|
||||
return String.format("%d.%d.%d", major, minor, patch);
|
||||
|
@ -61,46 +65,47 @@ public String getVersionString() {
|
|||
public int hashCode() {
|
||||
return Objects.hash(major, minor, patch, build);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public String getReleaseStatus()
|
||||
{
|
||||
public String getReleaseStatus() {
|
||||
String result;
|
||||
switch (release) {
|
||||
case LTS:
|
||||
result="lts";
|
||||
result = "lts";
|
||||
break;
|
||||
case STABLE:
|
||||
result="stable";
|
||||
result = "stable";
|
||||
break;
|
||||
case BETA:
|
||||
result="beta";
|
||||
result = "beta";
|
||||
break;
|
||||
case ALPHA:
|
||||
result="alpha";
|
||||
result = "alpha";
|
||||
break;
|
||||
case DEV:
|
||||
result="dev";
|
||||
result = "dev";
|
||||
break;
|
||||
case EXPERIMENTAL:
|
||||
result="experimental";
|
||||
result = "experimental";
|
||||
break;
|
||||
case UNKNOWN:
|
||||
result="";
|
||||
result = "";
|
||||
break;
|
||||
default:
|
||||
result="";
|
||||
result = "";
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@LauncherAPI
|
||||
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
|
||||
public enum Type
|
||||
{
|
||||
public enum Type {
|
||||
LTS,
|
||||
STABLE,
|
||||
BETA,
|
||||
|
|
|
@ -84,6 +84,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
|||
return super.visitFile(file, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SkipHiddenVisitor implements FileVisitor<Path> {
|
||||
private final FileVisitor<Path> visitor;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ public final class JVMHelper {
|
|||
@LauncherAPI
|
||||
public enum OS {
|
||||
MUSTDIE("mustdie"), LINUX("linux"), MACOSX("macosx");
|
||||
|
||||
public static OS byName(String name) {
|
||||
if (name.startsWith("Windows"))
|
||||
return MUSTDIE;
|
||||
|
@ -36,6 +37,7 @@ public static OS byName(String name) {
|
|||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
// MXBeans exports
|
||||
@LauncherAPI
|
||||
public static final RuntimeMXBean RUNTIME_MXBEAN = ManagementFactory.getRuntimeMXBean();
|
||||
|
|
|
@ -26,8 +26,10 @@
|
|||
public final class LogHelper {
|
||||
@LauncherAPI
|
||||
public static final String DEBUG_PROPERTY = "launcher.debug";
|
||||
@LauncherAPI public static final String NO_JANSI_PROPERTY = "launcher.noJAnsi";
|
||||
@LauncherAPI public static final boolean JANSI;
|
||||
@LauncherAPI
|
||||
public static final String NO_JANSI_PROPERTY = "launcher.noJAnsi";
|
||||
@LauncherAPI
|
||||
public static final boolean JANSI;
|
||||
|
||||
// Output settings
|
||||
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
|
||||
public static void addOutput(Writer writer) throws IOException {
|
||||
public static void addOutput(Writer writer) {
|
||||
addOutput(new WriterOutput(writer));
|
||||
}
|
||||
|
||||
|
@ -303,7 +305,7 @@ public String toString() {
|
|||
}
|
||||
|
||||
private static final class JAnsiOutput extends WriterOutput {
|
||||
private JAnsiOutput(OutputStream output) throws IOException {
|
||||
private JAnsiOutput(OutputStream output) {
|
||||
super(IOHelper.newWriter(new AnsiOutputStream(output)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,9 +41,11 @@ public enum DigestAlgorithm {
|
|||
for (DigestAlgorithm algorithm : algorithmsValues)
|
||||
ALGORITHMS.put(algorithm.name, algorithm);
|
||||
}
|
||||
|
||||
public static DigestAlgorithm byName(String name) {
|
||||
return VerifyHelper.getMapValue(ALGORITHMS, name, String.format("Unknown digest algorithm: '%s'", name));
|
||||
}
|
||||
|
||||
// Instance
|
||||
public final String name;
|
||||
|
||||
|
@ -71,6 +73,7 @@ public byte[] verify(byte[] digest) {
|
|||
return digest;
|
||||
}
|
||||
}
|
||||
|
||||
// Algorithm constants
|
||||
@LauncherAPI
|
||||
public static final String RSA_ALGO = "RSA";
|
||||
|
|
Loading…
Reference in a new issue