Введение MirrorManager, теперь можно создавать свои "зеркала", откуда можно скачивать клиенты и ассеты. Список зеркал указывается в LaunchServer.cfg

Модули могут добавлять свои зеркала
This commit is contained in:
Gravit 2018-10-18 16:39:36 +07:00
parent 81a867e631
commit 615ed25e00
No known key found for this signature in database
GPG key ID: 061981E1E85D3216
7 changed files with 105 additions and 12 deletions

View file

@ -4,6 +4,7 @@
import java.io.BufferedWriter;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.SocketAddress;
import java.nio.file.DirectoryStream;
import java.nio.file.FileVisitResult;
@ -32,6 +33,8 @@
import ru.gravit.launcher.Launcher;
import ru.gravit.launcher.LauncherAPI;
import ru.gravit.launcher.hasher.HashedDir;
import ru.gravit.launcher.serialize.config.entry.*;
import ru.gravit.launchserver.manangers.MirrorManager;
import ru.gravit.utils.helper.CommonHelper;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.JVMHelper;
@ -43,10 +46,6 @@
import ru.gravit.launcher.serialize.config.ConfigObject;
import ru.gravit.launcher.serialize.config.TextConfigReader;
import ru.gravit.launcher.serialize.config.TextConfigWriter;
import ru.gravit.launcher.serialize.config.entry.BlockConfigEntry;
import ru.gravit.launcher.serialize.config.entry.BooleanConfigEntry;
import ru.gravit.launcher.serialize.config.entry.IntegerConfigEntry;
import ru.gravit.launcher.serialize.config.entry.StringConfigEntry;
import ru.gravit.launcher.serialize.signed.SignedObjectHolder;
import ru.gravit.launchserver.auth.AuthLimiter;
import ru.gravit.launchserver.auth.handler.AuthHandler;
@ -101,6 +100,7 @@ public static final class Config extends ConfigObject {
public final boolean genMappings;
public ListConfigEntry mirrors;
public final String binaryName;
private final StringConfigEntry address;
private final String bindAddress;
@ -136,6 +136,7 @@ private Config(BlockConfigEntry block, Path coredir,LaunchServer server) {
// Set misc config
genMappings = block.getEntryValue("proguardPrintMappings", BooleanConfigEntry.class);
mirrors = block.getEntry("mirrors",ListConfigEntry.class);
launch4j = new ExeConf(block.getEntry("launch4J", BlockConfigEntry.class));
sign = new SignConf(block.getEntry("signing", BlockConfigEntry.class), coredir);
binaryName = block.getEntryValue("binaryName", StringConfigEntry.class);
@ -314,6 +315,8 @@ public static void main(String... args) throws Throwable {
public final ModulesManager modulesManager;
public final MirrorManager mirrorManager;
public final BuildHookManager buildHookManager;
@ -390,7 +393,7 @@ public LaunchServer(Path dir, boolean portable) throws IOException, InvalidKeySp
// Print keypair fingerprints
CRC32 crc = new CRC32();
crc.update(publicKey.getModulus().toByteArray());
crc.update(publicKey.getModulus().toByteArray()); // IDEA говорит, что это Java 9 API. WTF?
LogHelper.subInfo("Modulus CRC32: 0x%08x", crc.getValue());
// pre init modules
@ -411,8 +414,16 @@ public LaunchServer(Path dir, boolean portable) throws IOException, InvalidKeySp
limiter = new AuthLimiter(this);
proguardConf = new ProguardConf(this);
sessionManager = new SessionManager();
mirrorManager = new MirrorManager();
GarbageManager.registerNeedGC(sessionManager);
GarbageManager.registerNeedGC(limiter);
config.mirrors.stream(StringConfigEntry.class).forEach(s -> {
try {
mirrorManager.addMirror(s);
} catch (MalformedURLException e) {
e.printStackTrace();
}
});
// init modules
modulesManager.initModules();

View file

@ -172,7 +172,7 @@ private void stdBuild() throws IOException {
jaConfigurator.setAddress(server.config.getAddress());
jaConfigurator.setPort(server.config.port);
jaConfigurator.setProjectName(server.config.projectName);
jaConfigurator.setSecretKey(SecurityHelper.randomStringToken());
jaConfigurator.setSecretKey(SecurityHelper.randomStringAESKey());
jaConfigurator.setClientPort(32148 + SecurityHelper.newRandom().nextInt(512));
server.buildHookManager.registerAllClientModuleClass(jaConfigurator);
try (ZipInputStream input = new ZipInputStream(

View file

@ -13,7 +13,6 @@
import ru.gravit.launchserver.command.Command;
public final class DownloadAssetCommand extends Command {
private static final String ASSET_URL_MASK = "http://launcher.sashok724.net/download/assets/%s.zip";
public DownloadAssetCommand(LaunchServer server) {
super(server);
@ -42,7 +41,7 @@ public void invoke(String... args) throws Exception {
// Download required asset
LogHelper.subInfo("Downloading asset, it may take some time");
HttpDownloader.downloadZip(new URL(String.format(ASSET_URL_MASK, IOHelper.urlEncode(version.name))), assetDir);
HttpDownloader.downloadZip(server.mirrorManager.getDefaultMirror().getAssetsURL(version.name), assetDir);
// Finished
server.syncUpdatesDir(Collections.singleton(dirName));

View file

@ -21,7 +21,6 @@
import ru.gravit.launchserver.command.CommandException;
public final class DownloadClientCommand extends Command {
private static final String CLIENT_URL_MASK = "http://launcher.sashok724.net/download/clients/%s.zip";
public DownloadClientCommand(LaunchServer server) {
super(server);
@ -50,8 +49,7 @@ public void invoke(String... args) throws IOException, CommandException {
// Download required client
LogHelper.subInfo("Downloading client, it may take some time");
HttpDownloader.downloadZip(new URL(String.format(CLIENT_URL_MASK,
IOHelper.urlEncode(version.name))), clientDir);
HttpDownloader.downloadZip(server.mirrorManager.getDefaultMirror().getClientsURL(version.name), clientDir);
// Create profile file
LogHelper.subInfo("Creaing profile file: '%s'", dirName);

View file

@ -0,0 +1,64 @@
package ru.gravit.launchserver.manangers;
import ru.gravit.utils.helper.IOHelper;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
public class MirrorManager {
public class Mirror
{
URL url;
String assetsURLMask;
String clientsURLMask;
boolean enabled;
Mirror(String url)
{
assetsURLMask = url.concat("assets/%s.zip");
clientsURLMask = url.concat("clients/%s.zip");
}
private URL formatArg(String mask,String arg) throws MalformedURLException {
return new URL(String.format(mask, IOHelper.urlEncode(arg)));
}
public URL getAssetsURL(String assets) throws MalformedURLException {
return formatArg(assetsURLMask,assets);
}
public URL getClientsURL(String client) throws MalformedURLException {
return formatArg(clientsURLMask,client);
}
}
protected ArrayList<Mirror> list = new ArrayList<>();
private Mirror defaultMirror;
public void addMirror(String mirror) throws MalformedURLException {
Mirror m = new Mirror(mirror);
m.enabled = true;
if(defaultMirror == null) defaultMirror = m;
}
public void addMirror(String mirror,boolean enabled) throws MalformedURLException {
Mirror m = new Mirror(mirror);
m.url = new URL(mirror);
m.enabled = enabled;
if(defaultMirror == null && enabled) defaultMirror = m;
}
public Mirror getDefaultMirror()
{
return defaultMirror;
}
public void setDefaultMirror(Mirror m)
{
defaultMirror = m;
}
public void disableMirror(int index)
{
list.get(index).enabled = false;
}
public void enableMirror(int index)
{
list.get(index).enabled = true;
}
public int size()
{
return list.size();
}
}

View file

@ -1,7 +1,7 @@
address: "x";
bindAddress: "0.0.0.0";
port: 7240;
mirrors: ["http://launcher.sashok724.net/download/"];
# Auth rate limit
authRateLimit: 2;
authRateLimitMilis: 5000;

View file

@ -90,6 +90,8 @@ public byte[] verify(byte[] digest) {
@LauncherAPI
public static final int TOKEN_LENGTH = 16;
@LauncherAPI
public static final int AES_KEY_LENGTH = 24;
@LauncherAPI
public static final int TOKEN_STRING_LENGTH = TOKEN_LENGTH << 1;
@LauncherAPI
public static final int RSA_KEY_LENGTH_BITS = 2048;
@ -310,6 +312,25 @@ public static byte[] randomToken(Random random) {
return randomBytes(random, TOKEN_LENGTH);
}
@LauncherAPI
public static String randomStringAESKey() {
return toHex(randomAESKey(newRandom()));
}
@LauncherAPI
public static String randomStringAESKey(Random random) {
return toHex(randomAESKey(random));
}
@LauncherAPI
public static byte[] randomAESKey() {
return randomAESKey(newRandom());
}
@LauncherAPI
public static byte[] randomAESKey(Random random) {
return randomBytes(random, AES_KEY_LENGTH);
}
@LauncherAPI
public static String randomUsername() {
return randomUsername(newRandom());