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;
|
||||
|
|
|
@ -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,6 +80,7 @@ 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);
|
||||
|
|
|
@ -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,6 +29,7 @@ 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);
|
||||
|
@ -37,9 +38,11 @@ public static void registerHandlers() {
|
|||
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;
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ public void ban(List<HWID> l_hwid) throws HWIDException {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject request(JsonObject request, URL url) throws HWIDException, IOException {
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setDoInput(true);
|
||||
|
@ -97,6 +98,7 @@ 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());
|
||||
|
@ -128,8 +130,7 @@ public List<HWID> getHwid(String username) throws HWIDException {
|
|||
}
|
||||
JsonArray array = responce.get("hwids").asArray();
|
||||
ArrayList<HWID> hwids = new ArrayList<>();
|
||||
for(JsonValue i : array)
|
||||
{
|
||||
for (JsonValue i : array) {
|
||||
long hdd, cpu, bios;
|
||||
JsonObject object = i.asObject();
|
||||
hdd = object.getLong(hddKeyName, 0);
|
||||
|
|
|
@ -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,8 +104,8 @@ public void check0(HWID hwid, String username) throws HWIDException {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void writeHWID(HWID hwid, String username, Connection c)
|
||||
{
|
||||
|
||||
public void writeHWID(HWID hwid, String username, Connection c) {
|
||||
LogHelper.debug("Write HWID %s from username %s", hwid.toString(), username);
|
||||
try (PreparedStatement a = c.prepareStatement(queryUpd)) {
|
||||
//IF
|
||||
|
@ -120,8 +119,8 @@ public void writeHWID(HWID hwid, String username, Connection c)
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void setIsBanned(HWID hwid,boolean isBanned)
|
||||
{
|
||||
|
||||
public void setIsBanned(HWID hwid, boolean isBanned) {
|
||||
LogHelper.debug("%s Request HWID: %s", isBanned ? "Ban" : "UnBan", hwid.toString());
|
||||
Connection c = null;
|
||||
try {
|
||||
|
@ -141,25 +140,24 @@ public void setIsBanned(HWID hwid,boolean isBanned)
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void ban(List<HWID> list) throws HWIDException {
|
||||
|
||||
for(HWID hwid : list)
|
||||
{
|
||||
@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)
|
||||
{
|
||||
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);
|
||||
Connection c = mySQLHolder.getConnection();
|
||||
|
@ -180,8 +178,9 @@ public List<HWID> getHwid(String username) throws HWIDException {
|
|||
}
|
||||
ArrayList<HWID> list = new ArrayList<>();
|
||||
HWID hwid = HWID.gen(hdd, bios, cpu);
|
||||
if(hdd == 0 && cpu == 0 && bios == 0) {LogHelper.warning("Null HWID");}
|
||||
else {
|
||||
if (hdd == 0 && cpu == 0 && bios == 0) {
|
||||
LogHelper.warning("Null HWID");
|
||||
} else {
|
||||
list.add(hwid);
|
||||
LogHelper.debug("Username: %s HWID: %s", username, hwid.toString());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -17,11 +17,13 @@ public BuildContext(ZipOutputStream output, JAConfigurator config) {
|
|||
this.output = output;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public void pushFile(String filename, InputStream inputStream) throws IOException {
|
||||
ZipEntry zip = IOHelper.newZipEntry(filename);
|
||||
output.putNextEntry(zip);
|
||||
IOHelper.transfer(inputStream, output);
|
||||
}
|
||||
|
||||
public void pushJarFile(JarInputStream input) throws IOException {
|
||||
ZipEntry e = input.getNextEntry();
|
||||
while (e != null) {
|
||||
|
@ -30,6 +32,7 @@ public void pushJarFile(JarInputStream input) throws IOException {
|
|||
e = input.getNextEntry();
|
||||
}
|
||||
}
|
||||
|
||||
public void pushJarFile(JarInputStream input, Set<String> blacklist) throws IOException {
|
||||
ZipEntry e = input.getNextEntry();
|
||||
while (e != null) {
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
||||
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,7 +107,7 @@ 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);
|
||||
|
@ -113,13 +116,15 @@ public static final KeyStore getStore(Path file, String storepass, String algo)
|
|||
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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -28,8 +26,7 @@ public void invoke(String... args) throws Exception {
|
|||
verifyArgs(args, 1);
|
||||
if (handler == null)
|
||||
handler = new NettyServerSocketHandler(server);
|
||||
if(args[0].equals("start"))
|
||||
{
|
||||
if (args[0].equals("start")) {
|
||||
handler.run();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
|
||||
public void postHook(BuildContext context) {
|
||||
for (PostBuildHook hook : POST_HOOKS) hook.build(context);
|
||||
}
|
||||
public void preHook(BuildContext context)
|
||||
{
|
||||
|
||||
public void preHook(BuildContext context) {
|
||||
for (PreBuildHook hook : PRE_HOOKS) hook.build(context);
|
||||
}
|
||||
public void registerAllClientModuleClass(JAConfigurator cfg)
|
||||
{
|
||||
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
@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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
@ -339,7 +343,8 @@ public static Process launch(
|
|||
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");
|
||||
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) {
|
||||
|
@ -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,8 +27,7 @@ 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)
|
||||
{
|
||||
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;
|
||||
|
@ -44,5 +44,6 @@ public static void main(String[] args) throws Throwable {
|
|||
modulesManager.postInitModules();
|
||||
mainMethod.invoke(real_args);
|
||||
}
|
||||
|
||||
public ClientProfile profile;
|
||||
}
|
||||
|
|
|
@ -5,12 +5,13 @@ public class AutogenConfig {
|
|||
public String address;
|
||||
public int port;
|
||||
private boolean isInitModules;
|
||||
|
||||
AutogenConfig() {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnnecessaryReturnStatement")
|
||||
public void initModules()
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -20,10 +20,11 @@ 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);
|
||||
}
|
||||
|
|
|
@ -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,6 +62,7 @@ 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) {
|
||||
|
@ -68,6 +71,7 @@ public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<Stri
|
|||
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);
|
||||
|
|
|
@ -4,6 +4,8 @@ public interface ModuleContext {
|
|||
enum Type {
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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,8 +49,7 @@ public void autoload(Path dir) throws IOException {
|
|||
LogHelper.info("Loaded %d modules", modules.size());
|
||||
}
|
||||
|
||||
public void sort()
|
||||
{
|
||||
public void sort() {
|
||||
modules.sort((m1, m2) -> {
|
||||
int p1 = m1.getPriority();
|
||||
int p2 = m2.getPriority();
|
||||
|
@ -142,8 +142,7 @@ 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());
|
||||
}
|
||||
|
|
|
@ -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,8 +202,7 @@ public boolean isUpdateFastCheck() {
|
|||
}
|
||||
|
||||
@LauncherAPI
|
||||
public boolean isWhitelistContains(String username)
|
||||
{
|
||||
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);
|
||||
|
|
|
@ -11,13 +11,8 @@
|
|||
public class LauncherKeyStore {
|
||||
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,7 +9,8 @@ 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 {
|
||||
|
||||
public LauncherSSLContext(KeyStore ks, String keypassword) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException {
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new LauncherTrustManager()
|
||||
};
|
||||
|
@ -21,6 +22,7 @@ public LauncherSSLContext(KeyStore ks,String keypassword) throws NoSuchAlgorithm
|
|||
ssf = sc.getServerSocketFactory();
|
||||
sf = sc.getSocketFactory();
|
||||
}
|
||||
|
||||
public LauncherSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new LauncherTrustManager()
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
public class SystemClassLoaderTransformer implements ClassFileTransformer {
|
||||
@Override
|
||||
public byte[] transform(ClassLoader classLoader, String classname, Class<?> aClass, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException {
|
||||
public byte[] transform(ClassLoader classLoader, String classname, Class<?> aClass, ProtectionDomain protectionDomain, byte[] bytes) {
|
||||
if (classname.startsWith("ru/gravit/launcher/")) return bytes;
|
||||
if (classname.startsWith("java/")) return bytes;
|
||||
if (classname.startsWith("sun/")) return bytes;
|
||||
|
@ -42,7 +42,7 @@ public byte[] transform(ClassLoader classLoader, String classname, Class<?> aCla
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,9 +65,9 @@ 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:
|
||||
|
@ -93,14 +97,15 @@ public String getReleaseStatus()
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@LauncherAPI
|
||||
public String toString() {
|
||||
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