mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-22 16:41:46 +03:00
Merge branch 'release/5.4.0'
This commit is contained in:
commit
aa47fd6f1b
184 changed files with 656 additions and 2524 deletions
|
@ -50,17 +50,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
tasks.register('sourcesJar', Jar) {
|
||||
from sourceSets.main.allJava
|
||||
archiveClassifier.set('sources')
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
tasks.register('javadocJar', Jar) {
|
||||
from javadoc
|
||||
archiveClassifier.set('javadoc')
|
||||
}
|
||||
|
||||
task cleanjar(type: Jar, dependsOn: jar) {
|
||||
tasks.register('cleanjar', Jar) {
|
||||
dependsOn jar
|
||||
archiveClassifier.set('clean')
|
||||
manifest.attributes("Main-Class": mainClassName,
|
||||
"Premain-Class": mainAgentName,
|
||||
|
@ -117,13 +118,13 @@ pack project(':LauncherAPI')
|
|||
compileOnlyA 'org.apache.logging.log4j:log4j-core:2.14.1'
|
||||
}
|
||||
|
||||
task hikari(type: Copy) {
|
||||
tasks.register('hikari', Copy) {
|
||||
duplicatesStrategy = 'EXCLUDE'
|
||||
into "$buildDir/libs/libraries/hikaricp"
|
||||
from configurations.hikari
|
||||
}
|
||||
|
||||
task launch4j(type: Copy) {
|
||||
tasks.register('launch4j', Copy) {
|
||||
duplicatesStrategy = 'EXCLUDE'
|
||||
into "$buildDir/libs/libraries/launch4j"
|
||||
from(configurations.launch4j.collect {
|
||||
|
@ -141,20 +142,20 @@ task launch4j(type: Copy) {
|
|||
}
|
||||
}
|
||||
|
||||
task dumpLibs(type: Copy) {
|
||||
tasks.register('dumpLibs', Copy) {
|
||||
duplicatesStrategy = 'EXCLUDE'
|
||||
dependsOn tasks.hikari, tasks.launch4j
|
||||
into "$buildDir/libs/libraries"
|
||||
from configurations.bundleOnly
|
||||
}
|
||||
|
||||
task dumpCompileOnlyLibs(type: Copy) {
|
||||
tasks.register('dumpCompileOnlyLibs', Copy) {
|
||||
duplicatesStrategy = 'EXCLUDE'
|
||||
into "$buildDir/libs/launcher-libraries-compile"
|
||||
from configurations.compileOnlyA
|
||||
}
|
||||
|
||||
task bundle(type: Zip) {
|
||||
tasks.register('bundle', Zip) {
|
||||
duplicatesStrategy = 'EXCLUDE'
|
||||
dependsOn parent.childProjects.Launcher.tasks.build, tasks.dumpLibs, tasks.dumpCompileOnlyLibs, tasks.jar
|
||||
archiveFileName = 'LaunchServer.zip'
|
||||
|
@ -165,7 +166,7 @@ task bundle(type: Zip) {
|
|||
from(parent.childProjects.Launcher.tasks.dumpLibs) { into 'launcher-libraries' }
|
||||
}
|
||||
|
||||
task dumpClientLibs(type: Copy) {
|
||||
tasks.register('dumpClientLibs', Copy) {
|
||||
dependsOn parent.childProjects.Launcher.tasks.build
|
||||
into "$buildDir/libs/launcher-libraries"
|
||||
from parent.childProjects.Launcher.tasks.dumpLibs
|
||||
|
|
|
@ -121,7 +121,6 @@ public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurab
|
|||
// Updates and profiles
|
||||
private volatile Set<ClientProfile> profilesList;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, LaunchServerConfig config, LaunchServerRuntimeConfig runtimeConfig, LaunchServerConfigManager launchServerConfigManager, LaunchServerModulesManager modulesManager, KeyAgreementManager keyAgreementManager, CommandHandler commandHandler, CertificateManager certificateManager) throws IOException {
|
||||
this.dir = directories.dir;
|
||||
this.tmpDir = directories.tmpDir;
|
||||
|
@ -219,7 +218,14 @@ public void reload(ReloadType type) throws Exception {
|
|||
});
|
||||
logger.debug("Init components successful");
|
||||
}
|
||||
|
||||
if(!type.equals(ReloadType.NO_AUTH)) {
|
||||
nettyServerSocketHandler.nettyServer.service.forEachActiveChannels((channel, wsHandler) -> {
|
||||
Client client = wsHandler.getClient();
|
||||
if(client.auth != null) {
|
||||
client.auth = config.getAuthProviderPair(client.auth_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -236,7 +242,7 @@ public void invoke(String... args) throws Exception {
|
|||
case "full" -> reload(ReloadType.FULL);
|
||||
case "no_auth" -> reload(ReloadType.NO_AUTH);
|
||||
case "no_components" -> reload(ReloadType.NO_COMPONENTS);
|
||||
default -> reload(ReloadType.FULL);
|
||||
default -> reload(ReloadType.NO_AUTH);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
|
||||
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
|
||||
import pro.gravit.launchserver.socket.WebSocketService;
|
||||
import pro.gravit.utils.Version;
|
||||
import pro.gravit.utils.command.CommandHandler;
|
||||
import pro.gravit.utils.command.JLineCommandHandler;
|
||||
import pro.gravit.utils.command.StdCommandHandler;
|
||||
|
@ -202,7 +201,6 @@ public static void initGson(LaunchServerModulesManager modulesManager) {
|
|||
Launcher.gsonManager.initGson();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void registerAll() {
|
||||
AuthCoreProvider.registerProviders();
|
||||
PasswordVerifier.registerProviders();
|
||||
|
|
|
@ -65,7 +65,7 @@ private static void visit(ClassNode classNode, Map<String, Object> values) {
|
|||
return newClinitMethod;
|
||||
});
|
||||
List<MethodNode> constructors = classNode.methods.stream().filter(method -> "<init>".equals(method.name))
|
||||
.collect(Collectors.toList());
|
||||
.toList();
|
||||
MethodNode initMethod = constructors.stream().filter(method -> method.invisibleAnnotations != null
|
||||
&& method.invisibleAnnotations.stream().anyMatch(annotation -> INJECTED_CONSTRUCTOR_DESC.equals(annotation.desc))).findFirst()
|
||||
.orElseGet(() -> constructors.stream().filter(method -> method.desc.equals("()V")).findFirst().orElse(null));
|
||||
|
@ -112,7 +112,7 @@ public void visit(final String name, final Object value) {
|
|||
}
|
||||
List<FieldInsnNode> putStaticNodes = Arrays.stream(initMethod.instructions.toArray())
|
||||
.filter(node -> node instanceof FieldInsnNode && node.getOpcode() == Opcodes.PUTSTATIC).map(p -> (FieldInsnNode) p)
|
||||
.filter(node -> node.owner.equals(classNode.name) && node.name.equals(field.name) && node.desc.equals(field.desc)).collect(Collectors.toList());
|
||||
.filter(node -> node.owner.equals(classNode.name) && node.name.equals(field.name) && node.desc.equals(field.desc)).toList();
|
||||
InsnList setter = serializeValue(value);
|
||||
if (putStaticNodes.isEmpty()) {
|
||||
setter.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, field.name, field.desc));
|
||||
|
@ -130,7 +130,7 @@ public void visit(final String name, final Object value) {
|
|||
}
|
||||
List<FieldInsnNode> putFieldNodes = Arrays.stream(initMethod.instructions.toArray())
|
||||
.filter(node -> node instanceof FieldInsnNode && node.getOpcode() == Opcodes.PUTFIELD).map(p -> (FieldInsnNode) p)
|
||||
.filter(node -> node.owner.equals(classNode.name) && node.name.equals(field.name) && node.desc.equals(field.desc)).collect(Collectors.toList());
|
||||
.filter(node -> node.owner.equals(classNode.name) && node.name.equals(field.name) && node.desc.equals(field.desc)).toList();
|
||||
InsnList setter = serializeValue(value);
|
||||
if (putFieldNodes.isEmpty()) {
|
||||
setter.insert(new VarInsnNode(Opcodes.ALOAD, 0));
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
import pro.gravit.launcher.events.request.AuthRequestEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serial;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class AuthException extends IOException {
|
||||
@Serial
|
||||
private static final long serialVersionUID = -2586107832847245863L;
|
||||
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
|
||||
import pro.gravit.launchserver.auth.core.MySQLCoreProvider;
|
||||
import pro.gravit.launchserver.auth.core.PostgresSQLCoreProvider;
|
||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -23,7 +21,6 @@ public final class AuthProviderPair {
|
|||
public transient Set<String> features;
|
||||
public String displayName;
|
||||
public boolean visible = true;
|
||||
private transient boolean warnOAuthShow = false;
|
||||
|
||||
public AuthProviderPair() {
|
||||
}
|
||||
|
@ -56,15 +53,6 @@ public static void getFeatures(Class<?> clazz, Set<String> list) {
|
|||
}
|
||||
}
|
||||
|
||||
public void internalShowOAuthWarnMessage() {
|
||||
if (!warnOAuthShow) {
|
||||
if (!(core instanceof MySQLCoreProvider) && !(core instanceof PostgresSQLCoreProvider)) { // MySQL and PostgreSQL upgraded later
|
||||
logger.warn("AuthCoreProvider {} ({}) not supported OAuth. Legacy session system may be removed in next release", name, core.getClass().getName());
|
||||
}
|
||||
warnOAuthShow = true;
|
||||
}
|
||||
}
|
||||
|
||||
public final <T> T isSupport(Class<T> clazz) {
|
||||
if (core == null) return null;
|
||||
T result = null;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractSQLCoreProvider extends AuthCoreProvider {
|
||||
public transient Logger logger = LogManager.getLogger();
|
||||
public final transient Logger logger = LogManager.getLogger();
|
||||
public int expireSeconds = 3600;
|
||||
public String uuidColumn;
|
||||
public String usernameColumn;
|
||||
|
@ -208,7 +208,7 @@ protected String makeUserCols() {
|
|||
return String.format("%s, %s, %s, %s, %s", uuidColumn, usernameColumn, accessTokenColumn, serverIDColumn, passwordColumn);
|
||||
}
|
||||
|
||||
protected boolean updateAuth(User user, String accessToken) throws IOException {
|
||||
protected void updateAuth(User user, String accessToken) throws IOException {
|
||||
try (Connection c = getSQLConfig().getConnection()) {
|
||||
SQLUser SQLUser = (SQLUser) user;
|
||||
SQLUser.accessToken = accessToken;
|
||||
|
@ -216,7 +216,7 @@ protected boolean updateAuth(User user, String accessToken) throws IOException {
|
|||
s.setString(1, accessToken);
|
||||
s.setString(2, user.getUUID().toString());
|
||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||
return s.executeUpdate() > 0;
|
||||
s.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ protected boolean updateServerID(User user, String serverID) throws IOException
|
|||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
getSQLConfig().close();
|
||||
}
|
||||
|
||||
|
@ -299,12 +299,12 @@ private List<String> queryRolesNames(String sql, String value) throws SQLExcepti
|
|||
}
|
||||
|
||||
public static class SQLUser implements User {
|
||||
protected UUID uuid;
|
||||
protected String username;
|
||||
protected final UUID uuid;
|
||||
protected final String username;
|
||||
protected String accessToken;
|
||||
protected String serverId;
|
||||
protected String password;
|
||||
protected ClientPermissions permissions;
|
||||
protected final String password;
|
||||
protected final ClientPermissions permissions;
|
||||
|
||||
public SQLUser(UUID uuid, String username, String accessToken, String serverId, String password, ClientPermissions permissions) {
|
||||
this.uuid = uuid;
|
||||
|
|
|
@ -140,7 +140,7 @@ public void invoke(String... args) throws Exception {
|
|||
if (instance != null) {
|
||||
map.put("getallusers", new SubCommand("(limit)", "print all users information") {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
public void invoke(String... args) {
|
||||
int max = Integer.MAX_VALUE;
|
||||
if (args.length > 0) max = Integer.parseInt(args[0]);
|
||||
Iterable<User> users = instance.getAllUsers();
|
||||
|
@ -316,7 +316,7 @@ public <T> T isSupport(Class<T> clazz) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public abstract void close() throws IOException;
|
||||
public abstract void close();
|
||||
|
||||
public static class PasswordVerifyReport {
|
||||
public static final PasswordVerifyReport REQUIRED_2FA = new PasswordVerifyReport(-1);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package pro.gravit.launchserver.auth.core;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import pro.gravit.launcher.ClientPermissions;
|
||||
|
@ -318,7 +317,7 @@ public void init(LaunchServer server) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
|
@ -525,10 +524,6 @@ public class HttpUser implements User, UserSupportTextures, UserSupportPropertie
|
|||
private String serverId;
|
||||
private String accessToken;
|
||||
private ClientPermissions permissions;
|
||||
@Deprecated
|
||||
private Texture skin;
|
||||
@Deprecated
|
||||
private Texture cloak;
|
||||
private Map<String, Texture> assets;
|
||||
private Map<String, String> properties;
|
||||
private long hwidId;
|
||||
|
@ -552,8 +547,6 @@ public HttpUser(String username, UUID uuid, String serverId, String accessToken,
|
|||
this.serverId = serverId;
|
||||
this.accessToken = accessToken;
|
||||
this.permissions = permissions;
|
||||
this.skin = skin;
|
||||
this.cloak = cloak;
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
||||
|
@ -563,8 +556,6 @@ public HttpUser(String username, UUID uuid, String serverId, String accessToken,
|
|||
this.serverId = serverId;
|
||||
this.accessToken = accessToken;
|
||||
this.permissions = permissions;
|
||||
this.skin = skin;
|
||||
this.cloak = cloak;
|
||||
this.properties = properties;
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
@ -607,30 +598,17 @@ public ClientPermissions getPermissions() {
|
|||
|
||||
@Override
|
||||
public Texture getSkinTexture() {
|
||||
if (assets == null) {
|
||||
return skin;
|
||||
}
|
||||
return assets.get("SKIN");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Texture getCloakTexture() {
|
||||
if (assets == null) {
|
||||
return cloak;
|
||||
}
|
||||
return assets.get("CAPE");
|
||||
}
|
||||
|
||||
public Map<String, Texture> getAssets() {
|
||||
if (assets == null) {
|
||||
Map<String, Texture> map = new HashMap<>();
|
||||
if (skin != null) {
|
||||
map.put("SKIN", skin);
|
||||
}
|
||||
if (cloak != null) {
|
||||
map.put("CAPE", cloak);
|
||||
}
|
||||
return map;
|
||||
return new HashMap<>();
|
||||
}
|
||||
return assets;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public User getUserByUUID(UUID uuid) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws OAuthAccessTokenExpired {
|
||||
public UserSession getUserSessionByOAuthAccessToken(String accessToken) {
|
||||
synchronized (memory) {
|
||||
for (MemoryUser u : memory) {
|
||||
if (u.accessToken.equals(accessToken)) {
|
||||
|
@ -95,14 +95,14 @@ public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext c
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateServerID(User user, String serverID) throws IOException {
|
||||
protected boolean updateServerID(User user, String serverID) {
|
||||
MemoryUser memoryUser = (MemoryUser) user;
|
||||
memoryUser.serverId = serverID;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User checkServer(Client client, String username, String serverID) throws IOException {
|
||||
public User checkServer(Client client, String username, String serverID) {
|
||||
synchronized (memory) {
|
||||
for (MemoryUser u : memory) {
|
||||
if (u.username.equals(username)) {
|
||||
|
@ -116,7 +116,7 @@ public User checkServer(Client client, String username, String serverID) throws
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean joinServer(Client client, String username, String accessToken, String serverID) throws IOException {
|
||||
public boolean joinServer(Client client, String username, String accessToken, String serverID) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -126,16 +126,16 @@ public void init(LaunchServer server) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
public static class MemoryUser implements User {
|
||||
private String username;
|
||||
private UUID uuid;
|
||||
private final String username;
|
||||
private final UUID uuid;
|
||||
private String serverId;
|
||||
private String accessToken;
|
||||
private ClientPermissions permissions;
|
||||
private final String accessToken;
|
||||
private final ClientPermissions permissions;
|
||||
|
||||
public MemoryUser(String username) {
|
||||
this.username = username;
|
||||
|
@ -188,9 +188,9 @@ public int hashCode() {
|
|||
}
|
||||
|
||||
public static class MemoryUserSession implements UserSession {
|
||||
private String id;
|
||||
private MemoryUser user;
|
||||
private long expireIn;
|
||||
private final String id;
|
||||
private final MemoryUser user;
|
||||
private final long expireIn;
|
||||
|
||||
public MemoryUserSession(MemoryUser user) {
|
||||
this.id = SecurityHelper.randomStringToken();
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
public class MergeAuthCoreProvider extends AuthCoreProvider {
|
||||
private transient final Logger logger = LogManager.getLogger(MergeAuthCoreProvider.class);
|
||||
public List<String> list = new ArrayList<>();
|
||||
private transient List<AuthCoreProvider> providers = new ArrayList<>();
|
||||
private final transient List<AuthCoreProvider> providers = new ArrayList<>();
|
||||
@Override
|
||||
public User getUserByUsername(String username) {
|
||||
for(var core : providers) {
|
||||
|
@ -67,7 +67,7 @@ public User checkServer(Client client, String username, String serverID) throws
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean joinServer(Client client, String username, String accessToken, String serverID) throws IOException {
|
||||
public boolean joinServer(Client client, String username, String accessToken, String serverID) {
|
||||
return false; // Authorization not supported
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ public void init(LaunchServer server) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
// Providers closed automatically
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public User getUserByUUID(UUID uuid) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws OAuthAccessTokenExpired {
|
||||
public UserSession getUserSessionByOAuthAccessToken(String accessToken) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -46,12 +46,12 @@ public void init(LaunchServer server) {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateServerID(User user, String serverID) throws IOException {
|
||||
protected boolean updateServerID(User user, String serverID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import pro.gravit.launchserver.auth.core.UserSession;
|
||||
|
||||
public interface AuthSupportExit extends AuthSupport {
|
||||
boolean deleteSession(UserSession session);
|
||||
void deleteSession(UserSession session);
|
||||
|
||||
boolean exitUser(User user);
|
||||
void exitUser(User user);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
import java.time.Duration;
|
||||
|
||||
public class JsonPasswordVerifier extends PasswordVerifier {
|
||||
private static transient final Logger logger = LogManager.getLogger();
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
private transient final HttpClient client = HttpClient.newBuilder().build();
|
||||
public String url;
|
||||
public String bearerToken;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
import pro.gravit.launchserver.auth.protect.interfaces.JoinServerProtectHandler;
|
||||
import pro.gravit.launchserver.auth.protect.interfaces.SecureProtectHandler;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
import pro.gravit.launchserver.socket.response.auth.RestoreResponse;
|
||||
import pro.gravit.launchserver.socket.response.secure.HardwareReportResponse;
|
||||
|
||||
|
@ -27,16 +26,6 @@ public class AdvancedProtectHandler extends StdProtectHandler implements SecureP
|
|||
public boolean enableHardwareFeature;
|
||||
private transient LaunchServer server;
|
||||
|
||||
@Override
|
||||
public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
|
||||
return (context.authType == AuthResponse.ConnectTypes.CLIENT) && context.client.checkSign;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkLaunchServerLicense() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetSecureLevelInfoRequestEvent onGetSecureLevelInfo(GetSecureLevelInfoRequestEvent event) {
|
||||
return event;
|
||||
|
@ -73,11 +62,9 @@ public void onHardwareReport(HardwareReportResponse response, Client client) {
|
|||
}
|
||||
client.trustLevel.hardwareInfo = hardware.getHardwareInfo();
|
||||
response.sendResult(new HardwareReportRequestEvent(createHardwareToken(client.username, hardware)));
|
||||
return;
|
||||
} else {
|
||||
logger.error("AuthCoreProvider not supported hardware");
|
||||
response.sendError("AuthCoreProvider not supported hardware");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,10 +100,6 @@ public void init(LaunchServer server) {
|
|||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public String createHardwareToken(String username, UserHardware hardware) {
|
||||
return Jwts.builder()
|
||||
.setIssuer("LaunchServer")
|
||||
|
@ -138,12 +121,10 @@ public String createPublicKeyToken(String username, byte[] publicKey) {
|
|||
}
|
||||
|
||||
public static class HardwareInfoTokenVerifier implements RestoreResponse.ExtendedTokenProvider {
|
||||
private transient final LaunchServer server;
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
private final JwtParser parser;
|
||||
|
||||
public HardwareInfoTokenVerifier(LaunchServer server) {
|
||||
this.server = server;
|
||||
this.parser = Jwts.parserBuilder()
|
||||
.requireIssuer("LaunchServer")
|
||||
.setSigningKey(server.keyAgreementManager.ecdsaPublicKey)
|
||||
|
@ -172,12 +153,10 @@ public boolean accept(Client client, AuthProviderPair pair, String extendedToken
|
|||
}
|
||||
|
||||
public static class PublicKeyTokenVerifier implements RestoreResponse.ExtendedTokenProvider {
|
||||
private transient final LaunchServer server;
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
private final JwtParser parser;
|
||||
|
||||
public PublicKeyTokenVerifier(LaunchServer server) {
|
||||
this.server = server;
|
||||
this.parser = Jwts.parserBuilder()
|
||||
.requireIssuer("LaunchServer")
|
||||
.setSigningKey(server.keyAgreementManager.ecdsaPublicKey)
|
||||
|
|
|
@ -9,8 +9,4 @@ public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkLaunchServerLicense() {
|
||||
// None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,6 @@ public static void registerHandlers() {
|
|||
|
||||
public abstract boolean allowGetAccessToken(AuthResponse.AuthContext context);
|
||||
|
||||
public abstract void checkLaunchServerLicense(); //Выдает SecurityException при ошибке проверки лицензии
|
||||
|
||||
public void init(LaunchServer server) {
|
||||
|
||||
}
|
||||
|
|
|
@ -20,11 +20,6 @@ public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
|
|||
return (context.authType == AuthResponse.ConnectTypes.CLIENT) && context.client.checkSign;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkLaunchServerLicense() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LaunchServer server) {
|
||||
if (profileWhitelist != null && profileWhitelist.size() > 0) {
|
||||
|
@ -59,7 +54,6 @@ private boolean isWhitelisted(String property, ClientProfile profile, Client cli
|
|||
}
|
||||
}
|
||||
List<String> allowedUsername = profileWhitelist.get(profile.getTitle());
|
||||
if (allowedUsername != null && allowedUsername.contains(client.username)) return true;
|
||||
return false;
|
||||
return allowedUsername != null && allowedUsername.contains(client.username);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,24 +15,24 @@
|
|||
import java.util.UUID;
|
||||
|
||||
public class JsonTextureProvider extends TextureProvider {
|
||||
private transient static final Type MAP_TYPE = new TypeToken<Map<String, Texture>>() {
|
||||
private static final Type MAP_TYPE = new TypeToken<Map<String, Texture>>() {
|
||||
}.getType();
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
public String url;
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
//None
|
||||
}
|
||||
|
||||
@Override
|
||||
public Texture getCloakTexture(UUID uuid, String username, String client) throws IOException {
|
||||
public Texture getCloakTexture(UUID uuid, String username, String client) {
|
||||
logger.warn("Ineffective get cloak texture for {}", username);
|
||||
return getAssets(uuid, username, client).get("CAPE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Texture getSkinTexture(UUID uuid, String username, String client) throws IOException {
|
||||
public Texture getSkinTexture(UUID uuid, String username, String client) {
|
||||
logger.warn("Ineffective get skin texture for {}", username);
|
||||
return getAssets(uuid, username, client).get("SKIN");
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public RequestTextureProvider(String skinURL, String cloakURL) {
|
|||
|
||||
private static Texture getTexture(String url, boolean cloak) throws IOException {
|
||||
try {
|
||||
return new Texture(url, cloak);
|
||||
return new Texture(url, cloak, null);
|
||||
} catch (FileNotFoundException ignored) {
|
||||
return null; // Simply not found
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ private static Texture getTexture(String url, boolean cloak) throws IOException
|
|||
|
||||
private static Texture getTexture(String url, Path local, boolean cloak) throws IOException {
|
||||
try {
|
||||
return new Texture(url, local, cloak);
|
||||
return new Texture(url, local, cloak, null);
|
||||
} catch (FileNotFoundException ignored) {
|
||||
return null; // Simply not found
|
||||
}
|
||||
|
@ -60,7 +60,8 @@ public Texture getCloakTexture(UUID uuid, String username, String client) throws
|
|||
if (cloakLocalPath == null) {
|
||||
return getTexture(textureUrl, true);
|
||||
} else {
|
||||
return getTexture(textureUrl, Paths.get(cloakLocalPath), true);
|
||||
String path = getTextureURL(cloakLocalPath, uuid, username, client);
|
||||
return getTexture(textureUrl, Paths.get(path), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,7 +71,8 @@ public Texture getSkinTexture(UUID uuid, String username, String client) throws
|
|||
if (skinLocalPath == null) {
|
||||
return getTexture(textureUrl, false);
|
||||
} else {
|
||||
return getTexture(textureUrl, Paths.get(skinLocalPath), false);
|
||||
String path = getTextureURL(skinLocalPath, uuid, username, client);
|
||||
return getTexture(textureUrl, Paths.get(path), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public void build(Path target, boolean deleteTempFiles) throws IOException {
|
|||
long time_task_end = System.currentTimeMillis();
|
||||
long time_task = time_task_end - time_this;
|
||||
time_this = time_task_end;
|
||||
if (isNeedDelete && deleteTempFiles) Files.deleteIfExists(oldPath);
|
||||
if (isNeedDelete && deleteTempFiles && oldPath != thisPath) Files.deleteIfExists(oldPath);
|
||||
isNeedDelete = task.allowDelete();
|
||||
logger.info("Task {} processed from {} millis", task.getName(), time_task);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
public final class JARLauncherBinary extends LauncherBinary {
|
||||
public final AtomicLong count;
|
||||
public final Path runtimeDir;
|
||||
public final Path guardDir;
|
||||
public final Path buildDir;
|
||||
public final List<Path> coreLibs;
|
||||
public final List<Path> addonLibs;
|
||||
|
@ -27,7 +26,6 @@ public JARLauncherBinary(LaunchServer server) throws IOException {
|
|||
super(server, resolve(server, ".jar"), "Launcher-%s-%d.jar");
|
||||
count = new AtomicLong(0);
|
||||
runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR);
|
||||
guardDir = server.dir.resolve(Launcher.GUARD_DIR);
|
||||
buildDir = server.dir.resolve("build");
|
||||
coreLibs = new ArrayList<>();
|
||||
addonLibs = new ArrayList<>();
|
||||
|
|
|
@ -4,12 +4,9 @@
|
|||
import pro.gravit.utils.helper.IOHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
|
|
@ -72,7 +72,6 @@ public Path process(Path inputJar) throws IOException {
|
|||
} else {
|
||||
context.pushDir(server.launcherBinary.runtimeDir, Launcher.RUNTIME_DIR, runtime, false);
|
||||
}
|
||||
context.pushDir(server.launcherBinary.guardDir, Launcher.GUARD_DIR, runtime, false);
|
||||
|
||||
LauncherConfig launcherConfig = new LauncherConfig(server.config.netty.address, server.keyAgreementManager.ecdsaPublicKey, server.keyAgreementManager.rsaPublicKey, runtime, server.config.projectName);
|
||||
context.pushFile(Launcher.CONFIG_FILE, launcherConfig);
|
||||
|
@ -108,7 +107,6 @@ protected void initProps() {
|
|||
properties.put("launcher.projectName", server.config.projectName);
|
||||
properties.put("runtimeconfig.secretKeyClient", SecurityHelper.randomStringAESKey());
|
||||
properties.put("launcher.port", 32148 + SecurityHelper.newRandom().nextInt(512));
|
||||
properties.put("launcher.guardType", server.config.launcher.guardType);
|
||||
properties.put("launchercore.env", server.config.env);
|
||||
properties.put("launcher.memory", server.config.launcher.memoryLimit);
|
||||
properties.put("launcher.customJvmOptions", server.config.launcher.customJvmOptions);
|
||||
|
@ -126,7 +124,8 @@ protected void initProps() {
|
|||
properties.put("runtimeconfig.secureCheckSalt", launcherSalt);
|
||||
if (server.runtime.unlockSecret == null) server.runtime.unlockSecret = SecurityHelper.randomStringToken();
|
||||
properties.put("runtimeconfig.unlockSecret", server.runtime.unlockSecret);
|
||||
|
||||
server.runtime.buildNumber++;
|
||||
properties.put("runtimeconfig.buildNumber", server.runtime.buildNumber);
|
||||
}
|
||||
|
||||
public byte[] transformClass(byte[] bytes, String classname, BuildContext context) {
|
||||
|
|
|
@ -45,7 +45,7 @@ public Path process(Path inputFile) throws IOException {
|
|||
throw new RuntimeException(ex);
|
||||
}
|
||||
})) {
|
||||
var map = stream.collect(Collectors.toMap(k -> server.launcherPack.relativize(k).toString(), (v) -> v));
|
||||
var map = stream.collect(Collectors.toMap(k -> server.launcherPack.relativize(k).toString().replace("\\", "/"), (v) -> v));
|
||||
server.launcherBinary.files.putAll(map);
|
||||
}
|
||||
UnpackHelper.unpack(IOHelper.getResourceURL("Launcher.jar"), result);
|
||||
|
@ -60,7 +60,6 @@ public boolean allowDelete() {
|
|||
|
||||
public void tryUnpack() throws IOException {
|
||||
logger.info("Unpacking launcher native guard list and runtime");
|
||||
UnpackHelper.unpackZipNoCheck("guard.zip", server.launcherBinary.guardDir);
|
||||
UnpackHelper.unpackZipNoCheck("runtime.zip", server.launcherBinary.runtimeDir);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
public class SignJarTask implements LauncherBuildTask {
|
||||
|
||||
private transient static final Logger logger = LogManager.getLogger();
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
private final LaunchServerConfig.JarSignerConf config;
|
||||
private final LaunchServer srv;
|
||||
|
||||
|
|
|
@ -4,8 +4,11 @@
|
|||
import me.tongfei.progressbar.ProgressBarBuilder;
|
||||
import me.tongfei.progressbar.ProgressBarStyle;
|
||||
import pro.gravit.launcher.AsyncDownloader;
|
||||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.utils.Downloader;
|
||||
import pro.gravit.utils.command.CommandException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
@ -29,6 +32,13 @@ public Command(Map<String, pro.gravit.utils.command.Command> childCommands, Laun
|
|||
this.server = server;
|
||||
}
|
||||
|
||||
protected ClientProfile.Version parseClientVersion(String arg) throws CommandException {
|
||||
if(arg.isEmpty()) {
|
||||
throw new CommandException("ClientVersion can't be empty");
|
||||
}
|
||||
return Launcher.gsonManager.gson.fromJson(arg, ClientProfile.Version.class);
|
||||
}
|
||||
|
||||
protected boolean showApplyDialog(String text) throws IOException {
|
||||
System.out.printf("%s [Y/N]:", text);
|
||||
String response = server.commandHandler.readLine().toLowerCase(Locale.ROOT);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
import pro.gravit.launchserver.command.Command;
|
||||
|
||||
public class DebugCommand extends Command {
|
||||
private transient Logger logger = LogManager.getLogger();
|
||||
private final transient Logger logger = LogManager.getLogger();
|
||||
|
||||
public DebugCommand(LaunchServer server) {
|
||||
super(server);
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
import pro.gravit.utils.command.basic.HelpCommand;
|
||||
|
||||
public abstract class CommandHandler extends pro.gravit.utils.command.CommandHandler {
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void registerCommands(pro.gravit.utils.command.CommandHandler handler, LaunchServer server) {
|
||||
BaseCommandCategory basic = new BaseCommandCategory();
|
||||
// Register basic commands
|
||||
|
|
|
@ -43,7 +43,7 @@ public void invoke(String... args) throws Exception {
|
|||
verifyArgs(args, 1);
|
||||
//Version version = Version.byName(args[0]);
|
||||
String versionName = args[0];
|
||||
String dirName = IOHelper.verifyFileName(args[1] != null ? args[1] : "assets");
|
||||
String dirName = IOHelper.verifyFileName(args.length > 1 ? args[1] : "assets");
|
||||
String type = args.length > 2 ? args[2] : "mojang";
|
||||
Path assetDir = server.updatesDir.resolve(dirName);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
import pro.gravit.launcher.profiles.ClientProfileVersions;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.launchserver.helper.MakeProfileHelper;
|
||||
|
@ -81,9 +82,9 @@ public void invoke(String... args) throws IOException, CommandException {
|
|||
if (internalVersion.contains("-")) {
|
||||
internalVersion = internalVersion.substring(0, versionName.indexOf('-'));
|
||||
}
|
||||
ClientProfile.Version version = ClientProfile.Version.byName(internalVersion);
|
||||
if (version.compareTo(ClientProfile.Version.MC164) <= 0) {
|
||||
logger.warn("Minecraft 1.6.4 and below not supported. Use at your own risk");
|
||||
ClientProfile.Version version = ClientProfile.Version.of(internalVersion);
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_7_10) <= 0) {
|
||||
logger.warn("Minecraft 1.7.9 and below not supported. Use at your own risk");
|
||||
}
|
||||
MakeProfileHelper.MakeProfileOption[] options = MakeProfileHelper.getMakeProfileOptionsFromDir(clientDir, version, Files.exists(server.updatesDir.resolve("assets")));
|
||||
for (MakeProfileHelper.MakeProfileOption option : options) {
|
||||
|
|
|
@ -32,12 +32,12 @@ public String getUsageDescription() {
|
|||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 3);
|
||||
ClientProfile.Version version = ClientProfile.Version.byName(args[1]);
|
||||
ClientProfile.Version version = parseClientVersion(args[1]);
|
||||
MakeProfileHelper.MakeProfileOption[] options = MakeProfileHelper.getMakeProfileOptionsFromDir(server.updatesDir.resolve(args[2]), version, Files.exists(server.updatesDir.resolve("assets")));
|
||||
for (MakeProfileHelper.MakeProfileOption option : options) {
|
||||
logger.info("Detected option {}", option);
|
||||
}
|
||||
ClientProfile profile = MakeProfileHelper.makeProfile(ClientProfile.Version.byName(args[1]), args[0], options);
|
||||
ClientProfile profile = MakeProfileHelper.makeProfile(version, args[0], options);
|
||||
try (Writer writer = IOHelper.newWriter(server.profilesDir.resolve(args[0].concat(".json")))) {
|
||||
Launcher.gsonManager.configGson.toJson(profile, writer);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
public class SecurityCheckCommand extends Command {
|
||||
private static transient final Logger logger = LogManager.getLogger();
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
|
||||
public SecurityCheckCommand(LaunchServer server) {
|
||||
super(server);
|
||||
|
@ -110,7 +110,7 @@ public void invoke(String... args) {
|
|||
try {
|
||||
KeyStore keyStore = SignHelper.getStore(new File(config.sign.keyStore).toPath(), config.sign.keyStorePass, config.sign.keyStoreType);
|
||||
Certificate[] certChainPlain = keyStore.getCertificateChain(config.sign.keyAlias);
|
||||
List<X509Certificate> certChain = Arrays.stream(certChainPlain).map(e -> (X509Certificate) e).collect(Collectors.toList());
|
||||
List<X509Certificate> certChain = Arrays.stream(certChainPlain).map(e -> (X509Certificate) e).toList();
|
||||
X509Certificate cert = certChain.get(0);
|
||||
cert.checkValidity();
|
||||
if (certChain.size() <= 1) {
|
||||
|
@ -169,7 +169,7 @@ public void invoke(String... args) {
|
|||
bad = true;
|
||||
}
|
||||
} else {
|
||||
if (nextToken.equals("memory_repo") || nextToken.equals(profile.getVersion().name)) {
|
||||
if (nextToken.equals("memory_repo") || nextToken.equals(profile.getVersion().toString())) {
|
||||
printCheckResult(profileModuleName, String.format("updateExclusions %s not safe. Cheats may be injected very easy!", exc), false);
|
||||
bad = true;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public void invoke(String... args) throws Exception {
|
|||
Optional<SignJarTask> task = server.launcherBinary.getTaskByClass(SignJarTask.class);
|
||||
if (task.isEmpty()) throw new IllegalStateException("SignJarTask not found");
|
||||
task.get().sign(server.config.sign, target, tmpSign);
|
||||
if (args.length <= 1) {
|
||||
if (args.length == 1) {
|
||||
logger.info("Move temp jar {} to {}", tmpSign.toString(), target.toString());
|
||||
Files.deleteIfExists(target);
|
||||
Files.move(tmpSign, target);
|
||||
|
|
|
@ -25,7 +25,7 @@ public void invoke(String... args) throws Exception {
|
|||
});
|
||||
this.childCommands.put("server", new SubCommand("[profileName] (authId)", "generate new server token") {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
public void invoke(String... args) {
|
||||
AuthProviderPair pair = args.length > 1 ? server.config.getAuthProviderPair(args[1]) : server.config.getAuthProviderPair();
|
||||
ClientProfile profile = null;
|
||||
for (ClientProfile p : server.getProfiles()) {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
import java.util.Map;
|
||||
|
||||
public class ProGuardComponent extends Component implements AutoCloseable, Reconfigurable {
|
||||
private transient static final Logger logger = LogManager.getLogger();
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
public String modeAfter = "MainBuild";
|
||||
public String dir = "proguard";
|
||||
public boolean enabled = true;
|
||||
|
@ -79,7 +79,7 @@ public void init(LaunchServer launchServer) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
public void close() {
|
||||
if (launchServer != null && buildTask != null) {
|
||||
launchServer.launcherBinary.tasks.remove(buildTask);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ public boolean hookJoin(JoinServerResponse response, Client client) throws HookE
|
|||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
public void close() {
|
||||
this.server.authHookManager.preHook.unregisterHook(this::hookAuth);
|
||||
this.server.authHookManager.joinServerHook.unregisterHook(this::hookJoin);
|
||||
}
|
||||
|
@ -82,14 +82,14 @@ public void invoke(String... args) throws Exception {
|
|||
});
|
||||
commands.put("disable", new SubCommand() {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
public void invoke(String... args) {
|
||||
enabled = false;
|
||||
logger.info("Whitelist disabled");
|
||||
}
|
||||
});
|
||||
commands.put("enable", new SubCommand() {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
public void invoke(String... args) {
|
||||
enabled = true;
|
||||
logger.info("Whitelist enabled");
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public final class LaunchServerConfig {
|
|||
|
||||
public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) {
|
||||
LaunchServerConfig newConfig = new LaunchServerConfig();
|
||||
newConfig.mirrors = new String[]{"https://mirror.gravitlauncher.com/5.3.x/", "https://gravit-launcher-mirror.storage.googleapis.com/"};
|
||||
newConfig.mirrors = new String[]{"https://mirror.gravitlauncher.com/5.4.x/", "https://gravit-launcher-mirror.storage.googleapis.com/"};
|
||||
newConfig.launch4j = new LaunchServerConfig.ExeConf();
|
||||
newConfig.launch4j.enabled = false;
|
||||
newConfig.launch4j.copyright = "© GravitLauncher Team";
|
||||
|
@ -84,7 +84,6 @@ public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) {
|
|||
newConfig.netty.performance.schedulerThread = 2;
|
||||
|
||||
newConfig.launcher = new LauncherConf();
|
||||
newConfig.launcher.guardType = "no";
|
||||
newConfig.launcher.compress = true;
|
||||
newConfig.launcher.deleteTempFiles = true;
|
||||
newConfig.launcher.stripLineNumbers = true;
|
||||
|
@ -107,9 +106,8 @@ public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) {
|
|||
return newConfig;
|
||||
}
|
||||
|
||||
public LaunchServerConfig setLaunchServer(LaunchServer server) {
|
||||
public void setLaunchServer(LaunchServer server) {
|
||||
this.server = server;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuthProviderPair getAuthProviderPair(String name) {
|
||||
|
@ -188,7 +186,6 @@ public void init(LaunchServer.ReloadType type) {
|
|||
if (protectHandler != null) {
|
||||
server.registerObject("protectHandler", protectHandler);
|
||||
protectHandler.init(server);
|
||||
protectHandler.checkLaunchServerLicense();
|
||||
}
|
||||
if (components != null) {
|
||||
components.forEach((k, v) -> server.registerObject("component.".concat(k), v));
|
||||
|
@ -269,7 +266,6 @@ public static class NettyUpdatesBind {
|
|||
}
|
||||
|
||||
public static class LauncherConf {
|
||||
public String guardType;
|
||||
public boolean compress;
|
||||
public boolean stripLineNumbers;
|
||||
public boolean deleteTempFiles;
|
||||
|
|
|
@ -11,6 +11,7 @@ public class LaunchServerRuntimeConfig {
|
|||
public String unlockSecret;
|
||||
public String registerApiKey;
|
||||
public String clientCheckSecret;
|
||||
public long buildNumber;
|
||||
|
||||
public void verify() {
|
||||
if (passwordEncryptKey == null) logger.error("[RuntimeConfig] passwordEncryptKey must not be null");
|
||||
|
@ -25,5 +26,6 @@ public void reset() {
|
|||
runtimeEncryptKey = SecurityHelper.randomStringAESKey();
|
||||
registerApiKey = SecurityHelper.randomStringToken();
|
||||
clientCheckSecret = SecurityHelper.randomStringToken();
|
||||
buildNumber = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
import java.util.function.Function;
|
||||
|
||||
public final class HttpHelper {
|
||||
private static transient final Logger logger = LogManager.getLogger();
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
|
||||
private HttpHelper() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
@ -37,7 +37,7 @@ public static <T, E> HttpOptional<T, E> send(HttpClient client, HttpRequest requ
|
|||
}
|
||||
}
|
||||
|
||||
public static <T, E> CompletableFuture<HttpOptional<T, E>> sendAsync(HttpClient client, HttpRequest request, HttpErrorHandler<T, E> handler) throws IOException {
|
||||
public static <T, E> CompletableFuture<HttpOptional<T, E>> sendAsync(HttpClient client, HttpRequest request, HttpErrorHandler<T, E> handler) {
|
||||
return client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()).thenApply(handler::apply);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
import pro.gravit.launcher.profiles.ClientProfileBuilder;
|
||||
import pro.gravit.launcher.profiles.ClientProfileVersions;
|
||||
import pro.gravit.launcher.profiles.optional.OptionalFile;
|
||||
import pro.gravit.launcher.profiles.optional.actions.OptionalActionFile;
|
||||
import pro.gravit.launcher.profiles.optional.actions.OptionalActionJvmArgs;
|
||||
|
@ -16,14 +17,14 @@
|
|||
public class MakeProfileHelper {
|
||||
public static ClientProfile makeProfile(ClientProfile.Version version, String title, MakeProfileOption... options) {
|
||||
ClientProfileBuilder builder = new ClientProfileBuilder();
|
||||
builder.setVersion(version.name);
|
||||
builder.setVersion(version);
|
||||
builder.setDir(title);
|
||||
if (findOption(options, MakeProfileOptionGlobalAssets.class).isPresent()) {
|
||||
builder.setAssetDir("assets");
|
||||
} else {
|
||||
builder.setAssetDir("asset" + version.name);
|
||||
builder.setAssetDir("asset" + version.toCleanString());
|
||||
}
|
||||
builder.setAssetIndex(version.name);
|
||||
builder.setAssetIndex(version.toString());
|
||||
builder.setInfo("Информация о сервере");
|
||||
builder.setTitle(title);
|
||||
builder.setUuid(UUID.randomUUID());
|
||||
|
@ -35,7 +36,7 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
|
|||
List<String> classPath = new ArrayList<>(5);
|
||||
classPath.add("libraries");
|
||||
classPath.add("minecraft.jar");
|
||||
if (version.compareTo(ClientProfile.Version.MC1122) <= 0) {
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) <= 0) {
|
||||
findOption(options, MakeProfileOptionForge.class).ifPresent(e -> classPath.add("forge.jar"));
|
||||
findOption(options, MakeProfileOptionLiteLoader.class).ifPresent(e -> classPath.add("liteloader.jar"));
|
||||
}
|
||||
|
@ -46,20 +47,21 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
|
|||
Set<OptionalFile> optionals = new HashSet<>();
|
||||
jvmArgs.add("-XX:+DisableAttachMechanism");
|
||||
// Official Mojang launcher java arguments
|
||||
if (version.compareTo(ClientProfile.Version.MC112) <= 0) {
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) <= 0) {
|
||||
jvmArgs.add("-XX:+UseConcMarkSweepGC");
|
||||
jvmArgs.add("-XX:+CMSIncrementalMode");
|
||||
} else if (version.compareTo(ClientProfile.Version.MC118) <= 0) { // 1.13 - 1.16.5
|
||||
} else if (version.compareTo(ClientProfileVersions.MINECRAFT_1_18) <= 0) { // 1.13 - 1.16.5
|
||||
jvmArgs.add("-XX:+UseG1GC");
|
||||
jvmArgs.add("-XX:+UnlockExperimentalVMOptions");
|
||||
} else { // 1.18+
|
||||
jvmArgs.add("-XX:+UseShenandoahGC");
|
||||
jvmArgs.add("-XX:+UnlockExperimentalVMOptions");
|
||||
//jvmArgs.add("-XX:+UseShenandoahGC");
|
||||
//jvmArgs.add("-XX:+UnlockExperimentalVMOptions");
|
||||
}
|
||||
// -----------
|
||||
Optional<MakeProfileOptionForge> forge = findOption(options, MakeProfileOptionForge.class);
|
||||
Optional<MakeProfileOptionFabric> fabric = findOption(options, MakeProfileOptionFabric.class);
|
||||
if (version.compareTo(ClientProfile.Version.MC1122) > 0) {
|
||||
Optional<MakeProfilesOptionsQuilt> quilt = findOption(options, MakeProfilesOptionsQuilt.class);
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) > 0) {
|
||||
jvmArgs.add("-Djava.library.path=natives");
|
||||
OptionalFile optionalMacOs = new OptionalFile();
|
||||
optionalMacOs.name = "MacOSArgs";
|
||||
|
@ -72,6 +74,9 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
|
|||
if (fabric.isPresent()) {
|
||||
builder.setAltClassPath(fabric.orElseThrow().getAltClassPath());
|
||||
}
|
||||
if(quilt.isPresent()) {
|
||||
builder.setClassLoaderConfig(ClientProfile.ClassLoaderConfig.SYSTEM_ARGS);
|
||||
}
|
||||
if (findOption(options, MakeProfileOptionLwjgl.class).isPresent()) {
|
||||
OptionalFile optionalMac = new OptionalFile();
|
||||
optionalMac.name = "MacLwjgl";
|
||||
|
@ -112,16 +117,16 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
|
|||
if (log4jOption.logFile != null) {
|
||||
jvmArgs.add("-Dlog4j.configurationFile=".concat(logFile.get().logFile));
|
||||
} else if (log4jOption.affected) {
|
||||
if (version.compareTo(ClientProfile.Version.MC117) >= 0 && version.compareTo(ClientProfile.Version.MC118) < 0) {
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_17) >= 0 && version.compareTo(ClientProfileVersions.MINECRAFT_1_18) < 0) {
|
||||
jvmArgs.add("-Dlog4j2.formatMsgNoLookups=true");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (version.compareTo(ClientProfile.Version.MC117) >= 0 && version.compareTo(ClientProfile.Version.MC118) < 0) {
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_17) >= 0 && version.compareTo(ClientProfileVersions.MINECRAFT_1_18) < 0) {
|
||||
builder.setMinJavaVersion(16);
|
||||
builder.setRecommendJavaVersion(16);
|
||||
}
|
||||
if (version.compareTo(ClientProfile.Version.MC118) >= 0) {
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_18) >= 0) {
|
||||
builder.setMinJavaVersion(17);
|
||||
builder.setRecommendJavaVersion(17);
|
||||
}
|
||||
|
@ -137,22 +142,22 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
|
|||
}
|
||||
if (forge.isPresent()) {
|
||||
clientArgs.add("--tweakClass");
|
||||
if (version.compareTo(ClientProfile.Version.MC1710) > 0) {
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_7_10) > 0) {
|
||||
clientArgs.add("net.minecraftforge.fml.common.launcher.FMLTweaker");
|
||||
} else {
|
||||
clientArgs.add("cpw.mods.fml.common.launcher.FMLTweaker");
|
||||
}
|
||||
if (version.compareTo(ClientProfile.Version.MC1122) <= 0) {
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) <= 0) {
|
||||
builder.setMinJavaVersion(8);
|
||||
builder.setRecommendJavaVersion(8);
|
||||
builder.setMaxJavaVersion(8);
|
||||
}
|
||||
}
|
||||
} else if (version.compareTo(ClientProfile.Version.MC1122) > 0) {
|
||||
} else if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) > 0) {
|
||||
if (forge.isPresent()) {
|
||||
clientArgs.addAll(forge.get().makeClientArgs());
|
||||
builder.setClassLoaderConfig(ClientProfile.ClassLoaderConfig.AGENT);
|
||||
if (version.compareTo(ClientProfile.Version.MC1165) <= 0) {
|
||||
builder.setClassLoaderConfig(ClientProfile.ClassLoaderConfig.SYSTEM_ARGS);
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_16_5) <= 0) {
|
||||
builder.setMaxJavaVersion(15);
|
||||
}
|
||||
}
|
||||
|
@ -171,12 +176,15 @@ public static String getMainClassByVersion(ClientProfile.Version version, MakePr
|
|||
if (findOption(options, MakeProfileOptionLaunchWrapper.class).isPresent()) {
|
||||
return "net.minecraft.launchwrapper.Launch";
|
||||
}
|
||||
if (findOption(options, MakeProfileOptionForge.class).isPresent() && version.compareTo(ClientProfile.Version.MC1122) > 0) {
|
||||
if (findOption(options, MakeProfileOptionForge.class).isPresent() && version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) > 0) {
|
||||
return "cpw.mods.modlauncher.Launcher";
|
||||
}
|
||||
if (findOption(options, MakeProfileOptionFabric.class).isPresent()) {
|
||||
return "net.fabricmc.loader.launch.knot.KnotClient";
|
||||
}
|
||||
if(findOption(options, MakeProfilesOptionsQuilt.class).isPresent()) {
|
||||
return "org.quiltmc.loader.impl.launch.knot.KnotClient";
|
||||
}
|
||||
return "net.minecraft.client.main.Main";
|
||||
}
|
||||
|
||||
|
@ -206,7 +214,7 @@ public static MakeProfileOption[] getMakeProfileOptionsFromDir(Path dir, ClientP
|
|||
if (Files.exists(dir.resolve("forge.jar"))) {
|
||||
options.add(new MakeProfileOptionForge());
|
||||
} else if (Files.exists(dir.resolve("libraries/net/minecraftforge/forge"))) {
|
||||
if (version.compareTo(ClientProfile.Version.MC1122) > 0) {
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) > 0) {
|
||||
options.add(new MakeProfileOptionForge(dir));
|
||||
} else {
|
||||
options.add(new MakeProfileOptionForge());
|
||||
|
@ -215,6 +223,9 @@ public static MakeProfileOption[] getMakeProfileOptionsFromDir(Path dir, ClientP
|
|||
if (Files.exists(dir.resolve("libraries/net/fabricmc/fabric-loader"))) {
|
||||
options.add(new MakeProfileOptionFabric(dir));
|
||||
}
|
||||
if (Files.exists(dir.resolve("libraries/org/quiltmc/quilt-loader"))) {
|
||||
options.add(new MakeProfilesOptionsQuilt());
|
||||
}
|
||||
{
|
||||
String log4jVersion = getLog4jVersion(dir);
|
||||
if (log4jVersion != null) {
|
||||
|
@ -343,6 +354,10 @@ public List<String> getAltClassPath() {
|
|||
}
|
||||
}
|
||||
|
||||
public static class MakeProfilesOptionsQuilt implements MakeProfileOption {
|
||||
|
||||
}
|
||||
|
||||
public static class MakeProfileOptionLiteLoader implements MakeProfileOption {
|
||||
|
||||
}
|
||||
|
|
|
@ -119,17 +119,6 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
|||
ModuleEntity entity = new ModuleEntity();
|
||||
entity.path = file;
|
||||
entity.moduleMainClass = mainClass;
|
||||
try {
|
||||
Class<? extends LauncherModule> mainClazz = (Class<? extends LauncherModule>) classLoader.loadClass(entity.moduleMainClass);
|
||||
entity.checkResult = server.modulesManager.checkModuleClass(mainClazz);
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof ClassNotFoundException || e instanceof NoClassDefFoundError) {
|
||||
logger.error("Module-MainClass in module {} incorrect", file.toString());
|
||||
} else {
|
||||
logger.error(e);
|
||||
}
|
||||
return super.visitFile(file, attrs);
|
||||
}
|
||||
entity.moduleConfigClass = attributes.getValue("Module-Config-Class");
|
||||
if (entity.moduleConfigClass != null) {
|
||||
entity.moduleConfigName = attributes.getValue("Module-Config-Name");
|
||||
|
|
|
@ -7,11 +7,9 @@
|
|||
import java.util.Map;
|
||||
|
||||
public class FeaturesManager {
|
||||
private final transient LaunchServer server;
|
||||
private final Map<String, String> map;
|
||||
|
||||
public FeaturesManager(LaunchServer server) {
|
||||
this.server = server;
|
||||
map = new HashMap<>();
|
||||
addFeatureInfo("version", Version.getVersion().getVersionString());
|
||||
addFeatureInfo("projectName", server.config.projectName);
|
||||
|
@ -25,8 +23,8 @@ public String getFeatureInfo(String name) {
|
|||
return map.get(name);
|
||||
}
|
||||
|
||||
public String addFeatureInfo(String name, String featureInfo) {
|
||||
return map.put(name, featureInfo);
|
||||
public void addFeatureInfo(String name, String featureInfo) {
|
||||
map.put(name, featureInfo);
|
||||
}
|
||||
|
||||
public String removeFeatureInfo(String name) {
|
||||
|
|
|
@ -22,7 +22,6 @@ public class KeyAgreementManager {
|
|||
public final RSAPublicKey rsaPublicKey;
|
||||
public final RSAPrivateKey rsaPrivateKey;
|
||||
public final String legacySalt;
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
|
||||
public KeyAgreementManager(ECPublicKey ecdsaPublicKey, ECPrivateKey ecdsaPrivateKey, RSAPublicKey rsaPublicKey, RSAPrivateKey rsaPrivateKey, String legacySalt) {
|
||||
this.ecdsaPublicKey = ecdsaPublicKey;
|
||||
|
@ -34,6 +33,7 @@ public KeyAgreementManager(ECPublicKey ecdsaPublicKey, ECPrivateKey ecdsaPrivate
|
|||
|
||||
public KeyAgreementManager(Path keyDirectory) throws IOException, InvalidKeySpecException {
|
||||
Path ecdsaPublicKeyPath = keyDirectory.resolve("ecdsa_id.pub"), ecdsaPrivateKeyPath = keyDirectory.resolve("ecdsa_id");
|
||||
Logger logger = LogManager.getLogger();
|
||||
if (IOHelper.isFile(ecdsaPublicKeyPath) && IOHelper.isFile(ecdsaPrivateKeyPath)) {
|
||||
logger.info("Reading ECDSA keypair");
|
||||
ecdsaPublicKey = SecurityHelper.toPublicECDSAKey(IOHelper.read(ecdsaPublicKeyPath));
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import pro.gravit.launcher.events.request.GetAvailabilityAuthRequestEvent;
|
||||
import pro.gravit.launcher.managers.GsonManager;
|
||||
import pro.gravit.launcher.modules.events.PreGsonPhase;
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
|
||||
import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger;
|
||||
import pro.gravit.launcher.request.JsonResultSerializeAdapter;
|
||||
|
@ -35,6 +36,7 @@ public void registerAdapters(GsonBuilder builder) {
|
|||
builder.registerTypeAdapterFactory(RecordTypeAdapterFactory.builder()
|
||||
.allowMissingComponentValues()
|
||||
.create());
|
||||
builder.registerTypeAdapter(ClientProfile.Version.class, new ClientProfile.Version.GsonSerializer());
|
||||
builder.registerTypeAdapter(TextureProvider.class, new UniversalJsonAdapter<>(TextureProvider.providers));
|
||||
builder.registerTypeAdapter(AuthCoreProvider.class, new UniversalJsonAdapter<>(AuthCoreProvider.providers));
|
||||
builder.registerTypeAdapter(PasswordVerifier.class, new UniversalJsonAdapter<>(PasswordVerifier.providers));
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package pro.gravit.launchserver.modules.events;
|
||||
|
||||
import pro.gravit.launcher.modules.LauncherModule;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
|
||||
public class LaunchServerNettyFullInitEvent extends LauncherModule.Event {
|
||||
public final LaunchServer server;
|
||||
|
||||
public LaunchServerNettyFullInitEvent(LaunchServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package pro.gravit.launchserver.socket;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
|
@ -34,11 +33,11 @@ public class LauncherNettyServer implements AutoCloseable {
|
|||
public final EventLoopGroup workerGroup;
|
||||
public final WebSocketService service;
|
||||
public final BiHookSet<NettyConnectContext, SocketChannel> pipelineHook = new BiHookSet<>();
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
|
||||
public LauncherNettyServer(LaunchServer server) {
|
||||
LaunchServerConfig.NettyConfig config = server.config.netty;
|
||||
NettyObjectFactory.setUsingEpoll(config.performance.usingEpoll);
|
||||
Logger logger = LogManager.getLogger();
|
||||
if (config.performance.usingEpoll) {
|
||||
logger.debug("Netty: Epoll enabled");
|
||||
}
|
||||
|
@ -74,8 +73,8 @@ public void initChannel(SocketChannel ch) {
|
|||
});
|
||||
}
|
||||
|
||||
public ChannelFuture bind(InetSocketAddress address) {
|
||||
return serverBootstrap.bind(address);
|
||||
public void bind(InetSocketAddress address) {
|
||||
serverBootstrap.bind(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.group.ChannelGroup;
|
||||
import io.netty.channel.group.ChannelMatchers;
|
||||
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
@ -21,7 +20,6 @@
|
|||
import pro.gravit.launchserver.socket.response.auth.*;
|
||||
import pro.gravit.launchserver.socket.response.management.FeaturesResponse;
|
||||
import pro.gravit.launchserver.socket.response.management.GetPublicKeyResponse;
|
||||
import pro.gravit.launchserver.socket.response.management.ServerStatusResponse;
|
||||
import pro.gravit.launchserver.socket.response.profile.BatchProfileByUsername;
|
||||
import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse;
|
||||
import pro.gravit.launchserver.socket.response.profile.ProfileByUsername;
|
||||
|
@ -33,26 +31,21 @@
|
|||
import pro.gravit.launchserver.socket.response.update.UpdateListResponse;
|
||||
import pro.gravit.launchserver.socket.response.update.UpdateResponse;
|
||||
import pro.gravit.utils.BiHookSet;
|
||||
import pro.gravit.utils.HookSet;
|
||||
import pro.gravit.utils.ProviderMap;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class WebSocketService {
|
||||
public static final ProviderMap<WebSocketServerResponse> providers = new ProviderMap<>();
|
||||
public final ChannelGroup channels;
|
||||
public final BiHookSet<WebSocketRequestContext, ChannelHandlerContext> hook = new BiHookSet<>();
|
||||
//Statistic data
|
||||
public final AtomicLong shortRequestLatency = new AtomicLong();
|
||||
public final AtomicLong shortRequestCounter = new AtomicLong();
|
||||
public final AtomicLong middleRequestLatency = new AtomicLong();
|
||||
public final AtomicLong middleRequestCounter = new AtomicLong();
|
||||
public final AtomicLong longRequestLatency = new AtomicLong();
|
||||
public final AtomicLong longRequestCounter = new AtomicLong();
|
||||
public final AtomicLong lastRequestTime = new AtomicLong();
|
||||
public final HookSet<WebSocketRequestContext> hookBeforeParsing = new HookSet<>();
|
||||
public final HookSet<WebSocketRequestContext> hookBeforeExecute = new HookSet<>();
|
||||
public final HookSet<WebSocketRequestContext> hookComplete = new HookSet<>();
|
||||
public final BiHookSet<Channel, Object> hookSend = new BiHookSet<>();
|
||||
private final LaunchServer server;
|
||||
private final Gson gson;
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
|
@ -63,7 +56,6 @@ public WebSocketService(ChannelGroup channels, LaunchServer server) {
|
|||
this.gson = Launcher.gsonManager.gson;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void registerResponses() {
|
||||
providers.register("auth", AuthResponse.class);
|
||||
providers.register("checkServer", CheckServerResponse.class);
|
||||
|
@ -83,7 +75,6 @@ public static void registerResponses() {
|
|||
providers.register("verifySecureLevelKey", VerifySecureLevelKeyResponse.class);
|
||||
providers.register("securityReport", SecurityReportResponse.class);
|
||||
providers.register("hardwareReport", HardwareReportResponse.class);
|
||||
providers.register("serverStatus", ServerStatusResponse.class);
|
||||
providers.register("currentUser", CurrentUserResponse.class);
|
||||
providers.register("features", FeaturesResponse.class);
|
||||
providers.register("refreshToken", RefreshTokenResponse.class);
|
||||
|
@ -119,55 +110,27 @@ public void forEachActiveChannels(BiConsumer<Channel, WebSocketFrameHandler> cal
|
|||
}
|
||||
|
||||
public void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) {
|
||||
long startTimeNanos = System.nanoTime();
|
||||
String request = frame.text();
|
||||
WebSocketRequestContext context = new WebSocketRequestContext(ctx, request, client, ip);
|
||||
if(hookBeforeParsing.hook(context)) {
|
||||
return;
|
||||
}
|
||||
WebSocketServerResponse response = gson.fromJson(request, WebSocketServerResponse.class);
|
||||
context.response = response;
|
||||
if (response == null) {
|
||||
RequestEvent event = new ErrorRequestEvent("This type of request is not supported");
|
||||
sendObject(ctx, event);
|
||||
hookComplete.hook(context);
|
||||
sendObject(ctx.channel(), event, WebSocketEvent.class);
|
||||
return;
|
||||
}
|
||||
process(ctx, response, client, ip);
|
||||
long executeTime = System.nanoTime() - startTimeNanos;
|
||||
if (executeTime > 0) {
|
||||
addRequestTimeToStats(executeTime);
|
||||
}
|
||||
process(context, response, client, ip);
|
||||
}
|
||||
|
||||
public void addRequestTimeToStats(long nanos) {
|
||||
if (nanos < 100_000_000L) // < 100 millis
|
||||
{
|
||||
shortRequestCounter.getAndIncrement();
|
||||
shortRequestLatency.getAndAdd(nanos);
|
||||
} else if (nanos < 1_000_000_000L) // > 100 millis and < 1 second
|
||||
{
|
||||
middleRequestCounter.getAndIncrement();
|
||||
middleRequestLatency.getAndAdd(nanos);
|
||||
} else // > 1 second
|
||||
{
|
||||
longRequestCounter.getAndIncrement();
|
||||
longRequestLatency.getAndAdd(nanos);
|
||||
}
|
||||
long lastTime = lastRequestTime.get();
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (currentTime - lastTime > 60 * 1000) //1 minute
|
||||
{
|
||||
lastRequestTime.set(currentTime);
|
||||
shortRequestLatency.set(0);
|
||||
shortRequestCounter.set(0);
|
||||
middleRequestCounter.set(0);
|
||||
middleRequestLatency.set(0);
|
||||
longRequestCounter.set(0);
|
||||
longRequestLatency.set(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void process(ChannelHandlerContext ctx, WebSocketServerResponse response, Client client, String ip) {
|
||||
WebSocketRequestContext context = new WebSocketRequestContext(response, client, ip);
|
||||
if (hook.hook(context, ctx)) {
|
||||
void process(WebSocketRequestContext context, WebSocketServerResponse response, Client client, String ip) {
|
||||
if (hookBeforeExecute.hook(context)) {
|
||||
return;
|
||||
}
|
||||
ChannelHandlerContext ctx = context.context;
|
||||
if (response instanceof SimpleResponse simpleResponse) {
|
||||
simpleResponse.server = server;
|
||||
simpleResponse.service = this;
|
||||
|
@ -177,38 +140,27 @@ void process(ChannelHandlerContext ctx, WebSocketServerResponse response, Client
|
|||
}
|
||||
try {
|
||||
response.execute(ctx, client);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
context.exception = e;
|
||||
logger.error("WebSocket request processing failed", e);
|
||||
RequestEvent event;
|
||||
event = new ErrorRequestEvent("Fatal server error. Contact administrator");
|
||||
if (response instanceof SimpleResponse) {
|
||||
event.requestUUID = ((SimpleResponse) response).requestUUID;
|
||||
}
|
||||
sendObject(ctx, event);
|
||||
sendObject(ctx.channel(), event);
|
||||
}
|
||||
hookComplete.hook(context);
|
||||
}
|
||||
|
||||
public void registerClient(Channel channel) {
|
||||
channels.add(channel);
|
||||
}
|
||||
|
||||
public void sendObject(ChannelHandlerContext ctx, Object obj) {
|
||||
String msg = gson.toJson(obj, WebSocketEvent.class);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to {}: {}", getIPFromContext(ctx), msg);
|
||||
}
|
||||
ctx.writeAndFlush(new TextWebSocketFrame(msg), ctx.voidPromise());
|
||||
}
|
||||
|
||||
public void sendObject(ChannelHandlerContext ctx, Object obj, Type type) {
|
||||
String msg = gson.toJson(obj, type);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to {}: {}", getIPFromContext(ctx), msg);
|
||||
}
|
||||
ctx.writeAndFlush(new TextWebSocketFrame(msg), ctx.voidPromise());
|
||||
}
|
||||
|
||||
public void sendObject(Channel channel, Object obj) {
|
||||
if(hookSend.hook(channel, obj)) {
|
||||
return;
|
||||
}
|
||||
String msg = gson.toJson(obj, WebSocketEvent.class);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to channel {}: {}", getIPFromChannel(channel), msg);
|
||||
|
@ -217,6 +169,9 @@ public void sendObject(Channel channel, Object obj) {
|
|||
}
|
||||
|
||||
public void sendObject(Channel channel, Object obj, Type type) {
|
||||
if(hookSend.hook(channel, obj)) {
|
||||
return;
|
||||
}
|
||||
String msg = gson.toJson(obj, type);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to channel {}: {}", getIPFromChannel(channel), msg);
|
||||
|
@ -224,23 +179,9 @@ public void sendObject(Channel channel, Object obj, Type type) {
|
|||
channel.writeAndFlush(new TextWebSocketFrame(msg), channel.voidPromise());
|
||||
}
|
||||
|
||||
public void sendObjectAll(Object obj) {
|
||||
String msg = gson.toJson(obj, WebSocketEvent.class);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to all: {}", msg);
|
||||
}
|
||||
for (Channel ch : channels) {
|
||||
ch.writeAndFlush(new TextWebSocketFrame(msg), ch.voidPromise());
|
||||
}
|
||||
}
|
||||
|
||||
public void sendObjectAll(Object obj, Type type) {
|
||||
String msg = gson.toJson(obj, type);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to all: {}", msg);
|
||||
}
|
||||
for (Channel ch : channels) {
|
||||
ch.writeAndFlush(new TextWebSocketFrame(msg), ch.voidPromise());
|
||||
sendObject(ch, obj, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,6 +192,9 @@ public void sendObjectToUUID(UUID userUuid, Object obj, Type type) {
|
|||
if (wsHandler == null) continue;
|
||||
Client client = wsHandler.getClient();
|
||||
if (client == null || !userUuid.equals(client.uuid)) continue;
|
||||
if(hookSend.hook(ch, obj)) {
|
||||
continue;
|
||||
}
|
||||
String msg = gson.toJson(obj, type);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to {}({}): {}", getIPFromChannel(ch), userUuid, msg);
|
||||
|
@ -319,6 +263,9 @@ public boolean kickByIP(String ip, boolean isClose) {
|
|||
}
|
||||
|
||||
public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) {
|
||||
if(hookSend.hook(ctx.channel(), obj)) {
|
||||
return;
|
||||
}
|
||||
String msg = gson.toJson(obj, WebSocketEvent.class);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send and close {}: {}", getIPFromContext(ctx), msg);
|
||||
|
@ -327,6 +274,9 @@ public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) {
|
|||
}
|
||||
|
||||
public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj, Type type) {
|
||||
if(hookSend.hook(ctx.channel(), obj)) {
|
||||
return;
|
||||
}
|
||||
String msg = gson.toJson(obj, type);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send and close {}: {}", getIPFromContext(ctx), msg);
|
||||
|
@ -334,22 +284,17 @@ public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj, Type type)
|
|||
ctx.writeAndFlush(new TextWebSocketFrame(msg)).addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void sendEvent(EventResult obj) {
|
||||
String msg = gson.toJson(obj, WebSocketEvent.class);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send event: {}", msg);
|
||||
}
|
||||
channels.writeAndFlush(new TextWebSocketFrame(msg), ChannelMatchers.all(), true);
|
||||
}
|
||||
|
||||
public static class WebSocketRequestContext {
|
||||
public final WebSocketServerResponse response;
|
||||
public final ChannelHandlerContext context;
|
||||
public final String text;
|
||||
public final Client client;
|
||||
public final String ip;
|
||||
public WebSocketServerResponse response;
|
||||
public Throwable exception;
|
||||
|
||||
public WebSocketRequestContext(WebSocketServerResponse response, Client client, String ip) {
|
||||
this.response = response;
|
||||
public WebSocketRequestContext(ChannelHandlerContext context, String text, Client client, String ip) {
|
||||
this.context = context;
|
||||
this.text = text;
|
||||
this.client = client;
|
||||
this.ip = ip;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.config.LaunchServerConfig;
|
||||
import pro.gravit.launchserver.modules.events.LaunchServerNettyFullInitEvent;
|
||||
import pro.gravit.launchserver.socket.LauncherNettyServer;
|
||||
|
||||
import javax.net.ssl.SSLServerSocketFactory;
|
||||
|
@ -34,5 +35,6 @@ public void run() {
|
|||
for (LaunchServerConfig.NettyBindAddress address : server.config.netty.binds) {
|
||||
nettyServer.bind(new InetSocketAddress(address.address, address.port));
|
||||
}
|
||||
server.modulesManager.invokeEvent(new LaunchServerNettyFullInitEvent(server));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,10 +36,9 @@ public NettyWebAPIHandler(NettyConnectContext context) {
|
|||
this.context = context;
|
||||
}
|
||||
|
||||
public static SeverletPathPair addNewSeverlet(String path, SimpleSeverletHandler callback) {
|
||||
public static void addNewSeverlet(String path, SimpleSeverletHandler callback) {
|
||||
SeverletPathPair pair = new SeverletPathPair("/webapi/".concat(path), callback);
|
||||
severletList.add(pair);
|
||||
return pair;
|
||||
}
|
||||
|
||||
public static SeverletPathPair addUnsafeSeverlet(String path, SimpleSeverletHandler callback) {
|
||||
|
@ -53,7 +52,7 @@ public static void removeSeverlet(SeverletPathPair pair) {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
|
||||
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) {
|
||||
boolean isNext = true;
|
||||
for (SeverletPathPair pair : severletList) {
|
||||
if (msg.uri().startsWith(pair.key)) {
|
||||
|
@ -75,7 +74,7 @@ protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) thro
|
|||
|
||||
@FunctionalInterface
|
||||
public interface SimpleSeverletHandler {
|
||||
void handle(ChannelHandlerContext ctx, FullHttpRequest msg, NettyConnectContext context) throws Exception;
|
||||
void handle(ChannelHandlerContext ctx, FullHttpRequest msg, NettyConnectContext context);
|
||||
|
||||
default Map<String, String> getParamsFromUri(String uri) {
|
||||
int ind = uri.indexOf("?");
|
||||
|
|
|
@ -17,7 +17,7 @@ public abstract class SimpleResponse implements WebSocketServerResponse {
|
|||
|
||||
public void sendResult(RequestEvent result) {
|
||||
result.requestUUID = requestUUID;
|
||||
service.sendObject(ctx, result);
|
||||
service.sendObject(ctx.channel(), result);
|
||||
}
|
||||
|
||||
public void sendResultAndClose(RequestEvent result) {
|
||||
|
@ -28,6 +28,6 @@ public void sendResultAndClose(RequestEvent result) {
|
|||
public void sendError(String errorMessage) {
|
||||
ErrorRequestEvent event = new ErrorRequestEvent(errorMessage);
|
||||
event.requestUUID = requestUUID;
|
||||
service.sendObject(ctx, event);
|
||||
service.sendObject(ctx.channel(), event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class AdditionalDataResponse extends SimpleResponse {
|
||||
public String username;
|
||||
public UUID uuid;
|
||||
|
@ -22,7 +21,7 @@ public String getType() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||
if (!client.isAuth) {
|
||||
sendError("Access denied");
|
||||
return;
|
||||
|
|
|
@ -28,7 +28,7 @@ public String getType() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client clientData) throws Exception {
|
||||
public void execute(ChannelHandlerContext ctx, Client clientData) {
|
||||
try {
|
||||
AuthRequestEvent result = new AuthRequestEvent();
|
||||
AuthProviderPair pair;
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class CurrentUserResponse extends SimpleResponse {
|
||||
|
||||
public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(LaunchServer server, Client client) throws IOException {
|
||||
public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(LaunchServer server, Client client) {
|
||||
CurrentUserRequestEvent.UserInfo result = new CurrentUserRequestEvent.UserInfo();
|
||||
if (client.auth != null && client.isAuth && client.username != null) {
|
||||
result.playerProfile = server.authManager.getPlayerProfile(client);
|
||||
|
|
|
@ -14,7 +14,7 @@ public String getType() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||
if (!client.isAuth || client.type != AuthResponse.ConnectTypes.CLIENT) {
|
||||
sendError("Permissions denied");
|
||||
return;
|
||||
|
|
|
@ -18,7 +18,7 @@ public String getType() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||
if (refreshToken == null) {
|
||||
sendError("Invalid request");
|
||||
return;
|
||||
|
|
|
@ -76,6 +76,10 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
|||
return;
|
||||
}
|
||||
User user = session.getUser();
|
||||
if(user == null) {
|
||||
sendError("Internal Auth error: UserSession is broken");
|
||||
return;
|
||||
}
|
||||
client.coreObject = user;
|
||||
client.sessionObject = session;
|
||||
server.authManager.internalAuth(client, client.type == null ? AuthResponse.ConnectTypes.API : client.type, pair, user.getUsername(), user.getUUID(), user.getPermissions(), true);
|
||||
|
|
|
@ -18,7 +18,7 @@ public String getType() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||
sendError("Legacy session system removed");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ public String getType() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||
sendResult(new GetPublicKeyRequestEvent(server.keyAgreementManager.rsaPublicKey, server.keyAgreementManager.ecdsaPublicKey));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
package pro.gravit.launchserver.socket.response.management;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.ServerStatusRequestEvent;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.utils.helper.JVMHelper;
|
||||
|
||||
public class ServerStatusResponse extends SimpleResponse {
|
||||
@Override
|
||||
public String getType() {
|
||||
return "serverStatus";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||
ServerStatusRequestEvent event = new ServerStatusRequestEvent(server.config.projectName);
|
||||
event.totalJavaMemory = JVMHelper.RUNTIME.totalMemory();
|
||||
event.freeJavaMemory = JVMHelper.RUNTIME.freeMemory();
|
||||
event.shortLatency = (service.shortRequestLatency.get() / service.shortRequestCounter.get()) / 1_000_000;
|
||||
event.middleLatency = (service.middleRequestLatency.get() / service.middleRequestCounter.get()) / 1_000_000;
|
||||
event.longLatency = (service.longRequestLatency.get() / service.longRequestCounter.get()) / 1_000_000;
|
||||
event.latency = ((service.shortRequestLatency.get() + service.middleRequestLatency.get() + service.longRequestLatency.get()) /
|
||||
(service.shortRequestCounter.get() + service.middleRequestCounter.get() + service.longRequestCounter.get())) / 1_000_000;
|
||||
sendResult(event);
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ public String getType() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||
BatchProfileByUsernameRequestEvent result = new BatchProfileByUsernameRequestEvent();
|
||||
if (list == null) {
|
||||
sendError("Invalid request");
|
||||
|
|
|
@ -19,7 +19,7 @@ public String getType() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||
AuthProviderPair pair;
|
||||
if (client.auth == null) {
|
||||
pair = server.config.getAuthProviderPair();
|
||||
|
|
|
@ -17,7 +17,7 @@ public String getType() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||
AuthProviderPair pair = client.auth;
|
||||
if (pair == null) pair = server.config.getAuthProviderPair();
|
||||
PlayerProfile profile = server.authManager.getPlayerProfile(pair, username);
|
||||
|
|
|
@ -85,12 +85,10 @@ private boolean checkSecure(String hash, String salt) {
|
|||
}
|
||||
|
||||
public static class LauncherTokenVerifier implements RestoreResponse.ExtendedTokenProvider {
|
||||
private final LaunchServer server;
|
||||
private final JwtParser parser;
|
||||
private final Logger logger = LogManager.getLogger();
|
||||
|
||||
public LauncherTokenVerifier(LaunchServer server) {
|
||||
this.server = server;
|
||||
parser = Jwts.parserBuilder()
|
||||
.setSigningKey(server.keyAgreementManager.ecdsaPublicKey)
|
||||
.requireIssuer("LaunchServer")
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"version": "1.10.2",
|
||||
"assetIndex": "1.10.2",
|
||||
"assetDir": "asset1.10",
|
||||
"dir": "HiTech",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "xxxxxxxx",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar", "forge.jar", "liteloader.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"jvmArgs": [
|
||||
"-Dfml.ignorePatchDiscrepancies=true",
|
||||
"-Dfml.ignoreInvalidMinecraftCertificates=true",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"],
|
||||
"clientArgs": [
|
||||
"--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker",
|
||||
"--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker"
|
||||
],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"version": "1.11.2",
|
||||
"assetIndex": "1.11.2",
|
||||
"assetDir": "asset1.11",
|
||||
"dir": "HiTech",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "xxxxxxxx",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar", "forge.jar", "liteloader.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"jvmArgs": [
|
||||
"-Dfml.ignorePatchDiscrepancies=true",
|
||||
"-Dfml.ignoreInvalidMinecraftCertificates=true",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"],
|
||||
"clientArgs": [
|
||||
"--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker",
|
||||
"--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker"
|
||||
],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"version": "1.12.2",
|
||||
"assetIndex": "1.12.2",
|
||||
"assetDir": "asset1.12",
|
||||
"dir": "HiTech",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "xxxxxxxx",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar", "forge.jar", "liteloader.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"jvmArgs": [
|
||||
"-Dfml.ignorePatchDiscrepancies=true",
|
||||
"-Dfml.ignoreInvalidMinecraftCertificates=true",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"],
|
||||
"clientArgs": [
|
||||
"--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker",
|
||||
"--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker"
|
||||
],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
{
|
||||
"version": "1.13.1",
|
||||
"assetIndex": "1.13.1",
|
||||
"assetDir": "asset1.13.1",
|
||||
"dir": "HiTech",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "xxxxxxxx",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar", "forge.jar", "liteloader.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.client.main.Main",
|
||||
"jvmArgs": [
|
||||
"-Dfml.ignorePatchDiscrepancies=true",
|
||||
"-Dfml.ignoreInvalidMinecraftCertificates=true",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"],
|
||||
"clientArgs": [
|
||||
],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
{
|
||||
"version": "1.13",
|
||||
"assetIndex": "1.13",
|
||||
"assetDir": "asset1.13",
|
||||
"dir": "HiTech",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "xxxxxxxx",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar", "forge.jar", "liteloader.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.client.main.Main",
|
||||
"jvmArgs": [
|
||||
"-Dfml.ignorePatchDiscrepancies=true",
|
||||
"-Dfml.ignoreInvalidMinecraftCertificates=true",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"],
|
||||
"clientArgs": [
|
||||
],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
{
|
||||
"version": "1.14.4",
|
||||
"assetIndex": "1.14.4",
|
||||
"assetDir": "asset1.14.4",
|
||||
"dir": "HiTech",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "xxxxxxxx",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": [
|
||||
"servers.dat"
|
||||
],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries",
|
||||
"natives",
|
||||
"minecraft.jar"
|
||||
],
|
||||
"updateOptional": [],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.client.main.Main",
|
||||
"jvmArgs": [
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": [
|
||||
"minecraft.jar",
|
||||
"libraries"
|
||||
],
|
||||
"clientArgs": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
{
|
||||
"version": "1.15.1",
|
||||
"assetIndex": "1.15.1",
|
||||
"assetDir": "asset1.15.1",
|
||||
"dir": "HiTech",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "xxxxxxxx",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": [
|
||||
"servers.dat"
|
||||
],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries",
|
||||
"natives",
|
||||
"minecraft.jar"
|
||||
],
|
||||
"updateOptional": [],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.client.main.Main",
|
||||
"jvmArgs": [
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": [
|
||||
"minecraft.jar",
|
||||
"libraries"
|
||||
],
|
||||
"clientArgs": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
{
|
||||
"version": "1.15.2",
|
||||
"assetIndex": "1.15.2",
|
||||
"assetDir": "asset1.15.2",
|
||||
"dir": "HiTech",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "xxxxxxxx",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": [
|
||||
"servers.dat"
|
||||
],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries",
|
||||
"natives",
|
||||
"minecraft.jar"
|
||||
],
|
||||
"updateOptional": [],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.client.main.Main",
|
||||
"jvmArgs": [
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": [
|
||||
"minecraft.jar",
|
||||
"libraries"
|
||||
],
|
||||
"clientArgs": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
{
|
||||
"version": "1.16.1",
|
||||
"assetIndex": "1.16.1",
|
||||
"assetDir": "asset1.16.1",
|
||||
"dir": "HiTech",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "xxxxxxxx",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": [
|
||||
"servers.dat"
|
||||
],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries",
|
||||
"natives",
|
||||
"minecraft.jar"
|
||||
],
|
||||
"updateOptional": [],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.client.main.Main",
|
||||
"jvmArgs": [
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": [
|
||||
"minecraft.jar",
|
||||
"libraries"
|
||||
],
|
||||
"clientArgs": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
{
|
||||
"version": "1.4.7",
|
||||
"assetIndex": "---",
|
||||
"assetDir": "asset1.4.7",
|
||||
"dir": "xxxxxxx",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "Test1.4.7",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"jvmArgs": [
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism",
|
||||
"-Dlauncher.legacy.skinsURL=http://skins.minecraft.net/MinecraftSkins/%username%.png",
|
||||
"-Dlauncher.legacy.cloaksURL=http://skins.minecraft.net/MinecraftCloaks/%username%.png"
|
||||
],
|
||||
"classPath": ["minecraft.jar", "libraries"],
|
||||
"clientArgs": [],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
{
|
||||
"version": "1.5.2",
|
||||
"assetIndex": "---",
|
||||
"assetDir": "asset1.5.2",
|
||||
"dir": "xxxxxxx",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "Test1.5.2",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"jvmArgs": [
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism",
|
||||
"-Dlauncher.legacy.skinsURL=http://skins.minecraft.net/MinecraftSkins/%username%.png",
|
||||
"-Dlauncher.legacy.cloaksURL=http://skins.minecraft.net/MinecraftCloaks/%username%.png"
|
||||
],
|
||||
"classPath": ["minecraft.jar", "libraries"],
|
||||
"clientArgs": [],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
{
|
||||
"version": "1.6.4",
|
||||
"assetIndex": "---",
|
||||
"assetDir": "asset1.6.4",
|
||||
"dir": "xxxxxxx",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "Test1.6.4",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar", "forge.jar", "liteloader.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"jvmArgs": [
|
||||
"-Dfml.ignorePatchDiscrepancies=true",
|
||||
"-Dfml.ignoreInvalidMinecraftCertificates=true",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism",
|
||||
"-Dlauncher.legacy.skinsURL=http://skins.minecraft.net/MinecraftSkins/%username%.png",
|
||||
"-Dlauncher.legacy.cloaksURL=http://skins.minecraft.net/MinecraftCloaks/%username%.png"
|
||||
],
|
||||
"classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"],
|
||||
"clientArgs": [
|
||||
"--tweakClass", "cpw.mods.fml.common.launcher.FMLTweaker",
|
||||
"--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker"
|
||||
],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"version": "1.7.10",
|
||||
"assetIndex": "1.7.10",
|
||||
"assetDir": "asset1.7.10",
|
||||
"dir": "xxxxxxx",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "Test1.7.10",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar", "forge.jar", "liteloader.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"jvmArgs": [
|
||||
"-Dfml.ignorePatchDiscrepancies=true",
|
||||
"-Dfml.ignoreInvalidMinecraftCertificates=true",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"],
|
||||
"clientArgs": [
|
||||
"--tweakClass", "cpw.mods.fml.common.launcher.FMLTweaker",
|
||||
"--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker"
|
||||
],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"version": "1.7.2",
|
||||
"assetIndex": "1.7.2",
|
||||
"assetDir": "asset1.7.2",
|
||||
"dir": "xxxxxxx",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "Test1.7.2",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar", "forge.jar", "liteloader.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"jvmArgs": [
|
||||
"-Dfml.ignorePatchDiscrepancies=true",
|
||||
"-Dfml.ignoreInvalidMinecraftCertificates=true",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"],
|
||||
"clientArgs": [
|
||||
"--tweakClass", "cpw.mods.fml.common.launcher.FMLTweaker",
|
||||
"--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker"
|
||||
],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"version": "1.8.9",
|
||||
"assetIndex": "1.8.9",
|
||||
"assetDir": "asset1.8.9",
|
||||
"dir": "xxxxxxx",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "Test1.8.9",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar", "forge.jar", "liteloader.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"jvmArgs": [
|
||||
"-Dfml.ignorePatchDiscrepancies=true",
|
||||
"-Dfml.ignoreInvalidMinecraftCertificates=true",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"],
|
||||
"clientArgs": [
|
||||
"--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker",
|
||||
"--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker"
|
||||
],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"version": "1.9.4",
|
||||
"assetIndex": "1.9.4",
|
||||
"assetDir": "asset1.9.4",
|
||||
"dir": "xxxxxxx",
|
||||
"info": "Информация о сервере",
|
||||
"sortIndex": 0,
|
||||
"title": "Test1.9.4",
|
||||
"servers": [
|
||||
{
|
||||
"name": "----",
|
||||
"serverAddress": "localhost",
|
||||
"serverPort": 25565,
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"update": ["servers.dat"],
|
||||
"updateExclusions": [],
|
||||
"updateShared": [],
|
||||
"updateVerify": [
|
||||
"libraries", "natives", "mods",
|
||||
"minecraft.jar", "forge.jar", "liteloader.jar"
|
||||
],
|
||||
"updateOptional": [
|
||||
],
|
||||
"updateFastCheck": true,
|
||||
"useWhitelist": false,
|
||||
"mainClass": "net.minecraft.launchwrapper.Launch",
|
||||
"jvmArgs": [
|
||||
"-Dfml.ignorePatchDiscrepancies=true",
|
||||
"-Dfml.ignoreInvalidMinecraftCertificates=true",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+CMSIncrementalMode",
|
||||
"-XX:-UseAdaptiveSizePolicy",
|
||||
"-Xmn128M",
|
||||
"-XX:+DisableAttachMechanism"
|
||||
],
|
||||
"classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"],
|
||||
"clientArgs": [
|
||||
"--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker",
|
||||
"--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker"
|
||||
],
|
||||
"optionalJVMArgs": [],
|
||||
"optionalClientArgs": [],
|
||||
"optionalClassPath": [],
|
||||
"whitelist": []
|
||||
}
|
|
@ -21,7 +21,7 @@ public class ASMTransformersTest {
|
|||
public static ASMClassLoader classLoader;
|
||||
|
||||
@BeforeAll
|
||||
public static void prepare() throws Throwable {
|
||||
public static void prepare() {
|
||||
classLoader = new ASMClassLoader(ASMTransformersTest.class.getClassLoader());
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.launchserver.config.LaunchServerConfig;
|
||||
|
@ -45,4 +46,9 @@ public static void prepare() throws Throwable {
|
|||
.setCommandHandler(new StdCommandHandler(false));
|
||||
launchServer = builder.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
import pro.gravit.launchserver.config.LaunchServerConfig;
|
||||
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TestLaunchServerConfigManager implements LaunchServer.LaunchServerConfigManager {
|
||||
public LaunchServerConfig config;
|
||||
public LaunchServerRuntimeConfig runtimeConfig;
|
||||
|
@ -17,22 +15,22 @@ public TestLaunchServerConfigManager() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public LaunchServerConfig readConfig() throws IOException {
|
||||
public LaunchServerConfig readConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LaunchServerRuntimeConfig readRuntimeConfig() throws IOException {
|
||||
public LaunchServerRuntimeConfig readRuntimeConfig() {
|
||||
return runtimeConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeConfig(LaunchServerConfig config) throws IOException {
|
||||
public void writeConfig(LaunchServerConfig config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRuntimeConfig(LaunchServerRuntimeConfig config) throws IOException {
|
||||
public void writeRuntimeConfig(LaunchServerRuntimeConfig config) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,12 @@
|
|||
"Multi-Release": "true")
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
tasks.register('sourcesJar', Jar) {
|
||||
from sourceSets.main.allJava
|
||||
archiveClassifier.set('sources')
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
tasks.register('javadocJar', Jar) {
|
||||
from javadoc
|
||||
archiveClassifier.set('javadoc')
|
||||
}
|
||||
|
@ -53,14 +53,14 @@ pack project(':LauncherAPI')
|
|||
pack group: 'io.netty', name: 'netty-codec-http', version: rootProject['verNetty']
|
||||
}
|
||||
|
||||
task genRuntimeJS(type: Zip) {
|
||||
tasks.register('genRuntimeJS', Zip) {
|
||||
duplicatesStrategy = 'EXCLUDE'
|
||||
archiveFileName = "runtime.zip"
|
||||
destinationDirectory = file("${buildDir}/tmp")
|
||||
from "runtime/"
|
||||
}
|
||||
|
||||
task dumpLibs(type: Copy) {
|
||||
tasks.register('dumpLibs', Copy) {
|
||||
duplicatesStrategy = 'EXCLUDE'
|
||||
into "$buildDir/libs/libraries"
|
||||
from configurations.bundle
|
||||
|
|
|
@ -83,8 +83,6 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
|||
}
|
||||
|
||||
context.executePath = IOHelper.resolveJavaBin(context.javaVersion.jvmDir);
|
||||
//List<String> args = new LinkedList<>();
|
||||
//args.add(javaBin.toString());
|
||||
String pathLauncher = IOHelper.getCodeSource(LauncherEngine.class).toString();
|
||||
context.mainClass = LauncherEngine.class.getName();
|
||||
context.memoryLimit = launcherMemoryLimit;
|
||||
|
@ -143,8 +141,12 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
|||
if (customJvmOptions != null) {
|
||||
args.addAll(customJvmOptions);
|
||||
}
|
||||
args.add("-cp");
|
||||
args.add(String.join(IOHelper.PLATFORM_SEPARATOR, context.classpath));
|
||||
if(context.useLegacyClasspathProperty) {
|
||||
args.add(String.format("-Djava.class.path=%s", String.join(IOHelper.PLATFORM_SEPARATOR, context.classpath)));
|
||||
} else {
|
||||
args.add("-cp");
|
||||
args.add(String.join(IOHelper.PLATFORM_SEPARATOR, context.classpath));
|
||||
}
|
||||
args.add(context.mainClass);
|
||||
args.addAll(context.clientArgs);
|
||||
LogHelper.debug("Commandline: " + args);
|
||||
|
@ -172,6 +174,7 @@ public static class ClientLauncherWrapperContext {
|
|||
public Path executePath;
|
||||
public String mainClass;
|
||||
public int memoryLimit;
|
||||
public boolean useLegacyClasspathProperty;
|
||||
public ProcessBuilder processBuilder;
|
||||
public List<String> args = new ArrayList<>(8);
|
||||
public Map<String, String> jvmProperties = new HashMap<>();
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
import pro.gravit.launcher.console.ModulesCommand;
|
||||
import pro.gravit.launcher.console.SignDataCommand;
|
||||
import pro.gravit.launcher.events.request.*;
|
||||
import pro.gravit.launcher.guard.LauncherGuard;
|
||||
import pro.gravit.launcher.guard.LauncherNoGuard;
|
||||
import pro.gravit.launcher.guard.LauncherWrapperGuard;
|
||||
import pro.gravit.launcher.gui.NoRuntimeProvider;
|
||||
import pro.gravit.launcher.gui.RuntimeProvider;
|
||||
import pro.gravit.launcher.managers.ClientGsonManager;
|
||||
|
@ -49,7 +46,6 @@
|
|||
|
||||
public class LauncherEngine {
|
||||
public static ClientLauncherProcess.ClientParams clientParams;
|
||||
public static LauncherGuard guard;
|
||||
public static ClientModuleManager modulesManager;
|
||||
public final boolean clientInstance;
|
||||
// Instance
|
||||
|
@ -134,8 +130,6 @@ public static void main(String... args) throws Throwable {
|
|||
}
|
||||
long endTime = System.currentTimeMillis();
|
||||
LogHelper.debug("Launcher started in %dms", endTime - startTime);
|
||||
//Request.service.close();
|
||||
//FunctionalBridge.close();
|
||||
LauncherEngine.exitLauncher(0);
|
||||
}
|
||||
|
||||
|
@ -153,16 +147,6 @@ public static void verifyNoAgent() {
|
|||
throw new SecurityException("JavaAgent found");
|
||||
}
|
||||
|
||||
public static LauncherGuard tryGetStdGuard() {
|
||||
switch (Launcher.getConfig().guardType) {
|
||||
case "no":
|
||||
return new LauncherNoGuard();
|
||||
case "wrapper":
|
||||
return new LauncherWrapperGuard();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RequestService initOffline() {
|
||||
OfflineRequestService service = new OfflineRequestService();
|
||||
applyBasicOfflineProcessors(service);
|
||||
|
@ -232,7 +216,6 @@ public void readKeys() throws IOException, InvalidKeySpecException {
|
|||
|
||||
public void start(String... args) throws Throwable {
|
||||
//Launcher.modulesManager = new ClientModuleManager(this);
|
||||
LauncherEngine.guard = tryGetStdGuard();
|
||||
ClientPreGuiPhase event = new ClientPreGuiPhase(null);
|
||||
LauncherEngine.modulesManager.invokeEvent(event);
|
||||
runtimeProvider = event.runtimeProvider;
|
||||
|
|
|
@ -5,10 +5,15 @@
|
|||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ClientClassLoader extends URLClassLoader {
|
||||
private static final ClassLoader SYSTEM_CLASS_LOADER = ClassLoader.getSystemClassLoader();
|
||||
public String nativePath;
|
||||
|
||||
private final List<String> packages = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a new URLClassLoader for the specified URLs using the
|
||||
* default delegation parent {@code ClassLoader}. The URLs will
|
||||
|
@ -27,10 +32,11 @@ public class ClientClassLoader extends URLClassLoader {
|
|||
* {@code checkCreateClassLoader} method doesn't allow
|
||||
* creation of a class loader.
|
||||
* @throws NullPointerException if {@code urls} is {@code null}.
|
||||
* @see SecurityManager#checkCreateClassLoader
|
||||
*/
|
||||
public ClientClassLoader(URL[] urls) {
|
||||
super(urls);
|
||||
packages.add("pro.gravit.launcher.");
|
||||
packages.add("pro.gravit.utils.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,12 +58,23 @@ public ClientClassLoader(URL[] urls) {
|
|||
* {@code checkCreateClassLoader} method doesn't allow
|
||||
* creation of a class loader.
|
||||
* @throws NullPointerException if {@code urls} is {@code null}.
|
||||
* @see SecurityManager#checkCreateClassLoader
|
||||
*/
|
||||
public ClientClassLoader(URL[] urls, ClassLoader parent) {
|
||||
super(urls, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
if(name != null) {
|
||||
for(String pkg : packages) {
|
||||
if(name.startsWith(pkg)) {
|
||||
return SYSTEM_CLASS_LOADER.loadClass(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findLibrary(String name) {
|
||||
return nativePath.concat(IOHelper.PLATFORM_SEPARATOR).concat(getNativePrefix()).concat(name).concat(getNativeEx());
|
||||
|
@ -81,6 +98,10 @@ else if (JVMHelper.OS_TYPE == JVMHelper.OS.MACOSX)
|
|||
return "";
|
||||
}
|
||||
|
||||
public void addAllowedPackage(String pkg) {
|
||||
packages.add(pkg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addURL(URL url) {
|
||||
super.addURL(url);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
import pro.gravit.launcher.modules.events.OfflineModeEvent;
|
||||
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
import pro.gravit.launcher.profiles.ClientProfileVersions;
|
||||
import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
|
||||
import pro.gravit.launcher.profiles.optional.actions.OptionalActionClassPath;
|
||||
import pro.gravit.launcher.profiles.optional.actions.OptionalActionClientArgs;
|
||||
|
@ -33,7 +34,6 @@
|
|||
import pro.gravit.launcher.utils.DirWatcher;
|
||||
import pro.gravit.utils.helper.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
|
@ -46,6 +46,7 @@
|
|||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -107,7 +108,6 @@ public static void main(String[] args) throws Throwable {
|
|||
} else if (params.session != null) {
|
||||
throw new UnsupportedOperationException("Legacy session not supported");
|
||||
}
|
||||
checkJVMBitsAndVersion(params.profile.getMinJavaVersion(), params.profile.getRecommendJavaVersion(), params.profile.getMaxJavaVersion(), params.profile.isWarnMissJavaVersion());
|
||||
LauncherEngine.modulesManager.invokeEvent(new ClientProcessInitPhase(engine, params));
|
||||
|
||||
Path clientDir = Paths.get(params.clientDir);
|
||||
|
@ -144,7 +144,7 @@ public static void main(String[] args) throws Throwable {
|
|||
LogHelper.debug("Natives dir %s", params.nativesDir);
|
||||
ClientProfile.ClassLoaderConfig classLoaderConfig = profile.getClassLoaderConfig();
|
||||
if (classLoaderConfig == ClientProfile.ClassLoaderConfig.LAUNCHER) {
|
||||
ClientClassLoader classLoader = new ClientClassLoader(classpathURLs.toArray(new URL[0]), ClassLoader.getSystemClassLoader());
|
||||
ClientClassLoader classLoader = new ClientClassLoader(classpathURLs.toArray(new URL[0]), ClientLauncherEntryPoint.class.getClassLoader());
|
||||
System.setProperty("java.class.path", classpath.stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator)));
|
||||
ClientLauncherEntryPoint.classLoader = classLoader;
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
|
@ -174,15 +174,6 @@ public static void main(String[] args) throws Throwable {
|
|||
AuthService.username = params.playerProfile.username;
|
||||
AuthService.uuid = params.playerProfile.uuid;
|
||||
KeyService.serverRsaPublicKey = Launcher.getConfig().rsaPublicKey;
|
||||
if (params.profile.getRuntimeInClientConfig() != ClientProfile.RuntimeInClientConfig.NONE) {
|
||||
CommonHelper.newThread("Client Launcher Thread", true, () -> {
|
||||
try {
|
||||
engine.start(args);
|
||||
} catch (Throwable throwable) {
|
||||
LogHelper.error(throwable);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
LauncherEngine.modulesManager.invokeEvent(new ClientProcessReadyEvent(engine, params));
|
||||
LogHelper.debug("Starting JVM and client WatchService");
|
||||
FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher();
|
||||
|
@ -251,45 +242,26 @@ public static void verifyHDir(Path dir, HashedDir hdir, FileNameMatcher matcher,
|
|||
// Hash directory and compare (ignore update-only matcher entries, it will break offline-mode)
|
||||
HashedDir currentHDir = new HashedDir(dir, matcher, true, digest);
|
||||
HashedDir.Diff diff = hdir.diff(currentHDir, matcher);
|
||||
AtomicReference<String> latestPath = new AtomicReference<>("unknown");
|
||||
if (!diff.mismatch.isEmpty() || (checkExtra && !diff.extra.isEmpty())) {
|
||||
diff.extra.walk(File.separator, (e, k, v) -> {
|
||||
if (v.getType().equals(HashedEntry.Type.FILE)) {
|
||||
LogHelper.error("Extra file %s", e);
|
||||
latestPath.set(e);
|
||||
} else LogHelper.error("Extra %s", e);
|
||||
return HashedDir.WalkAction.CONTINUE;
|
||||
});
|
||||
diff.mismatch.walk(File.separator, (e, k, v) -> {
|
||||
if (v.getType().equals(HashedEntry.Type.FILE)) {
|
||||
LogHelper.error("Mismatch file %s", e);
|
||||
latestPath.set(e);
|
||||
} else LogHelper.error("Mismatch %s", e);
|
||||
return HashedDir.WalkAction.CONTINUE;
|
||||
});
|
||||
throw new SecurityException(String.format("Forbidden modification: '%s'", IOHelper.getFileName(dir)));
|
||||
throw new SecurityException(String.format("Forbidden modification: '%s' file '%s'", IOHelper.getFileName(dir), latestPath.get()));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean checkJVMBitsAndVersion(int minVersion, int recommendVersion, int maxVersion, boolean showMessage) {
|
||||
boolean ok = true;
|
||||
if (JVMHelper.JVM_BITS == 64 && JVMHelper.ARCH_TYPE == JVMHelper.ARCH.X86) {
|
||||
String error = "У Вас установлена Java x64, но Ваша система определена как x32. Установите Java правильной разрядности";
|
||||
LogHelper.error(error);
|
||||
if (showMessage)
|
||||
JOptionPane.showMessageDialog(null, error);
|
||||
ok = false;
|
||||
}
|
||||
String jvmVersion = JVMHelper.RUNTIME_MXBEAN.getVmVersion();
|
||||
LogHelper.info(jvmVersion);
|
||||
int version = JVMHelper.getVersion();
|
||||
if (version < minVersion || version > maxVersion) {
|
||||
String error = String.format("У Вас установлена Java %d, но этот клиент требует Java %d", JVMHelper.getVersion(), recommendVersion);
|
||||
LogHelper.error(error);
|
||||
if (showMessage)
|
||||
JOptionPane.showMessageDialog(null, error);
|
||||
ok = false;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private static LinkedList<Path> resolveClassPathList(Path clientDir, String... classPath) throws IOException {
|
||||
return resolveClassPathStream(clientDir, classPath).collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
@ -319,7 +291,7 @@ public static Stream<Path> resolveClassPath(Path clientDir, Set<OptionalAction>
|
|||
private static void launch(ClientProfile profile, ClientLauncherProcess.ClientParams params) throws Throwable {
|
||||
// Add client args
|
||||
Collection<String> args = new LinkedList<>();
|
||||
if (profile.getVersion().compareTo(ClientProfile.Version.MC164) >= 0)
|
||||
if (profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0)
|
||||
params.addClientArgs(args);
|
||||
else {
|
||||
params.addClientLegacyArgs(args);
|
||||
|
@ -353,7 +325,7 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa
|
|||
List<String> compatClasses = profile.getCompatClasses();
|
||||
for (String e : compatClasses) {
|
||||
Class<?> clazz = classLoader.loadClass(e);
|
||||
MethodHandle runMethod = MethodHandles.publicLookup().findStatic(clazz, "run", MethodType.methodType(void.class));
|
||||
MethodHandle runMethod = MethodHandles.lookup().findStatic(clazz, "run", MethodType.methodType(void.class));
|
||||
runMethod.invoke();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
import pro.gravit.launcher.events.request.AuthRequestEvent;
|
||||
import pro.gravit.launcher.hasher.HashedDir;
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
import pro.gravit.launcher.profiles.ClientProfileVersions;
|
||||
import pro.gravit.launcher.profiles.PlayerProfile;
|
||||
import pro.gravit.launcher.profiles.optional.OptionalView;
|
||||
import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
|
||||
|
@ -31,6 +32,8 @@
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
public class ClientLauncherProcess {
|
||||
|
||||
public final List<String> pre = new LinkedList<>();
|
||||
public final ClientParams params = new ClientParams();
|
||||
public final List<String> jvmArgs = new LinkedList<>();
|
||||
public final List<String> jvmModules = new LinkedList<>();
|
||||
|
@ -76,9 +79,14 @@ public ClientLauncherProcess(Path clientDir, Path assetDir, JavaHelper.JavaVersi
|
|||
this.params.clientDir = this.workDir.toString();
|
||||
this.params.resourcePackDir = resourcePackDir.toAbsolutePath().toString();
|
||||
this.params.assetDir = assetDir.toAbsolutePath().toString();
|
||||
Path nativesPath = workDir.resolve("natives").resolve(JVMHelper.OS_TYPE.name).resolve(javaVersion.arch.name);
|
||||
if (!Files.isDirectory(nativesPath)) {
|
||||
Path nativesPath;
|
||||
if(profile.hasFlag(ClientProfile.CompatibilityFlags.LEGACY_NATIVES_DIR)) {
|
||||
nativesPath = workDir.resolve("natives");
|
||||
} else {
|
||||
nativesPath = workDir.resolve("natives").resolve(JVMHelper.OS_TYPE.name).resolve(javaVersion.arch.name);
|
||||
}
|
||||
if (!Files.isDirectory(nativesPath)) {
|
||||
throw new RuntimeException(String.format("Natives dir %s not exist! Your operating system or architecture not supported", nativesPath.toAbsolutePath()));
|
||||
}
|
||||
this.params.nativesDir = nativesPath.toString();
|
||||
this.params.profile = profile;
|
||||
|
@ -123,24 +131,13 @@ private void applyClientProfile() {
|
|||
}
|
||||
this.jvmModules.addAll(this.params.profile.getModules());
|
||||
this.jvmModulesPaths.addAll(this.params.profile.getModulePath());
|
||||
if (this.params.profile.getRuntimeInClientConfig() != ClientProfile.RuntimeInClientConfig.NONE) {
|
||||
jvmModules.add("javafx.base");
|
||||
jvmModules.add("javafx.graphics");
|
||||
jvmModules.add("javafx.fxml");
|
||||
jvmModules.add("javafx.controls");
|
||||
jvmModules.add("javafx.swing");
|
||||
jvmModules.add("javafx.media");
|
||||
jvmModules.add("javafx.web");
|
||||
}
|
||||
|
||||
LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderCreateEvent(this));
|
||||
}
|
||||
|
||||
public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
||||
if (isStarted) throw new IllegalStateException("Process already started");
|
||||
if (LauncherEngine.guard != null) LauncherEngine.guard.applyGuardParams(this);
|
||||
LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderPreLaunchEvent(this));
|
||||
List<String> processArgs = new LinkedList<>();
|
||||
List<String> processArgs = new LinkedList<>(pre);
|
||||
processArgs.add(executeFile.toString());
|
||||
processArgs.addAll(jvmArgs);
|
||||
if (javaVersion.version >= 9) {
|
||||
|
@ -192,20 +189,10 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
|||
}
|
||||
|
||||
private void applyJava9Params(List<String> processArgs) {
|
||||
/*jvmModulesPaths.add(javaVersion.jvmDir);
|
||||
jvmModulesPaths.add(javaVersion.jvmDir.resolve("jre"));
|
||||
Path openjfxPath = JavaHelper.tryGetOpenJFXPath(javaVersion.jvmDir);
|
||||
if (openjfxPath != null) {
|
||||
jvmModulesPaths.add(openjfxPath);
|
||||
}*/ // TODO: fix runtime in client
|
||||
// TODO: fix runtime in client
|
||||
StringBuilder modulesPath = new StringBuilder();
|
||||
StringBuilder modulesAdd = new StringBuilder();
|
||||
for (String moduleName : jvmModules) {
|
||||
/*boolean success = JavaHelper.tryAddModule(jvmModulesPaths, moduleName, modulesPath);
|
||||
if (success) {
|
||||
if (modulesAdd.length() > 0) modulesAdd.append(",");
|
||||
modulesAdd.append(moduleName);
|
||||
}*/
|
||||
if (modulesAdd.length() > 0) modulesAdd.append(",");
|
||||
modulesAdd.append(moduleName);
|
||||
}
|
||||
|
@ -303,7 +290,7 @@ public static class ClientParams {
|
|||
public transient HashedDir javaHDir;
|
||||
|
||||
public void addClientArgs(Collection<String> args) {
|
||||
if (profile.getVersion().compareTo(ClientProfile.Version.MC164) >= 0)
|
||||
if (profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0)
|
||||
addModernClientArgs(args);
|
||||
else
|
||||
addClientLegacyArgs(args);
|
||||
|
@ -314,7 +301,7 @@ public void addClientLegacyArgs(Collection<String> args) {
|
|||
args.add(accessToken);
|
||||
|
||||
// Add args for tweaker
|
||||
Collections.addAll(args, "--version", profile.getVersion().name);
|
||||
Collections.addAll(args, "--version", profile.getVersion().toString());
|
||||
Collections.addAll(args, "--gameDir", clientDir);
|
||||
Collections.addAll(args, "--assetsDir", assetDir);
|
||||
}
|
||||
|
@ -324,12 +311,12 @@ private void addModernClientArgs(Collection<String> args) {
|
|||
// Add version-dependent args
|
||||
ClientProfile.Version version = profile.getVersion();
|
||||
Collections.addAll(args, "--username", playerProfile.username);
|
||||
if (version.compareTo(ClientProfile.Version.MC172) >= 0) {
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_7_2) >= 0) {
|
||||
Collections.addAll(args, "--uuid", Launcher.toHash(playerProfile.uuid));
|
||||
Collections.addAll(args, "--accessToken", accessToken);
|
||||
|
||||
// Add 1.7.10+ args (user properties, asset index)
|
||||
if (version.compareTo(ClientProfile.Version.MC1710) >= 0) {
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_7_10) >= 0) {
|
||||
// Add user properties
|
||||
Collections.addAll(args, "--userType", "mojang");
|
||||
Collections.addAll(args, "--userProperties", "{}");
|
||||
|
@ -341,11 +328,11 @@ private void addModernClientArgs(Collection<String> args) {
|
|||
Collections.addAll(args, "--session", accessToken);
|
||||
|
||||
// Add version and dirs args
|
||||
Collections.addAll(args, "--version", profile.getVersion().name);
|
||||
Collections.addAll(args, "--version", profile.getVersion().toString());
|
||||
Collections.addAll(args, "--gameDir", clientDir);
|
||||
Collections.addAll(args, "--assetsDir", assetDir);
|
||||
Collections.addAll(args, "--resourcePackDir", resourcePackDir);
|
||||
if (version.compareTo(ClientProfile.Version.MC194) >= 0)
|
||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_9_4) >= 0)
|
||||
Collections.addAll(args, "--versionType", "Launcher v" + Version.getVersion().getVersionString());
|
||||
|
||||
// Add server args
|
||||
|
|
|
@ -112,6 +112,17 @@ public static Path getGuardDir() {
|
|||
return dir.resolve("guard");
|
||||
}
|
||||
|
||||
public static Path getGuardDir(JVMHelper.ARCH arch, JVMHelper.OS os) {
|
||||
Path dir = getGuardDir().resolve(Launcher.makeSpecialGuardDirName(arch, os));
|
||||
try {
|
||||
IOHelper.createParentDirs(dir);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
public static Path getLegacyLauncherDir(String projectname) {
|
||||
return IOHelper.HOME_DIR.resolve(projectname);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
import pro.gravit.launcher.profiles.ClientProfileVersions;
|
||||
import pro.gravit.launcher.serialize.HInput;
|
||||
import pro.gravit.launcher.serialize.HOutput;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
|
@ -29,6 +30,7 @@ public final class ServerPinger {
|
|||
private static final int PACKET_LENGTH = 65535;
|
||||
// Instance
|
||||
private final InetSocketAddress address;
|
||||
private final int protocol;
|
||||
private final ClientProfile.Version version;
|
||||
// Cache
|
||||
private final Object cacheLock = new Object();
|
||||
|
@ -46,6 +48,7 @@ public ServerPinger(ClientProfile.ServerProfile profile, ClientProfile.Version v
|
|||
}
|
||||
this.address = profile.toSocketAddress();
|
||||
this.version = Objects.requireNonNull(version, "version");
|
||||
this.protocol = profile.protocol;
|
||||
}
|
||||
|
||||
private static String readUTF16String(HInput input) throws IOException {
|
||||
|
@ -64,7 +67,7 @@ private Result doPing() throws IOException {
|
|||
socket.connect(IOHelper.resolve(address), IOHelper.SOCKET_TIMEOUT);
|
||||
try (HInput input = new HInput(socket.getInputStream());
|
||||
HOutput output = new HOutput(socket.getOutputStream())) {
|
||||
return version.compareTo(ClientProfile.Version.MC172) >= 0 ? modernPing(input, output) : legacyPing(input, output, version.compareTo(ClientProfile.Version.MC164) >= 0);
|
||||
return version.compareTo(ClientProfileVersions.MINECRAFT_1_7_2) >= 0 ? modernPing(input, output, protocol) : legacyPing(input, output, version.compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +83,7 @@ private Result legacyPing(HInput input, HOutput output, boolean mc16) throws IOE
|
|||
byte[] customPayloadPacket;
|
||||
try (ByteArrayOutputStream packetArray = IOHelper.newByteArrayOutput()) {
|
||||
try (HOutput packetOutput = new HOutput(packetArray)) {
|
||||
packetOutput.writeUnsignedByte(version.protocol); // Protocol version
|
||||
packetOutput.writeUnsignedByte(0x4a); // Protocol version
|
||||
writeUTF16String(packetOutput, address.getHostString()); // Server address
|
||||
packetOutput.writeInt(address.getPort()); // Server port
|
||||
}
|
||||
|
@ -110,11 +113,7 @@ private Result legacyPing(HInput input, HOutput output, boolean mc16) throws IOE
|
|||
if (!magic.equals(LEGACY_PING_HOST_MAGIC))
|
||||
throw new IOException("Magic file mismatch: " + magic);
|
||||
int protocol = Integer.parseInt(splitted[1]);
|
||||
if (protocol != version.protocol)
|
||||
throw new IOException("Protocol mismatch: " + protocol);
|
||||
String clientVersion = splitted[2];
|
||||
if (!clientVersion.equals(version.name))
|
||||
throw new IOException(String.format("Version mismatch: '%s'", clientVersion));
|
||||
int onlinePlayers = VerifyHelper.verifyInt(Integer.parseInt(splitted[4]),
|
||||
VerifyHelper.NOT_NEGATIVE, "onlinePlayers can't be < 0");
|
||||
int maxPlayers = VerifyHelper.verifyInt(Integer.parseInt(splitted[5]),
|
||||
|
@ -124,13 +123,13 @@ private Result legacyPing(HInput input, HOutput output, boolean mc16) throws IOE
|
|||
return new Result(onlinePlayers, maxPlayers, response);
|
||||
}
|
||||
|
||||
private Result modernPing(HInput input, HOutput output) throws IOException {
|
||||
private Result modernPing(HInput input, HOutput output, int protocol) throws IOException {
|
||||
// Prepare handshake packet
|
||||
byte[] handshakePacket;
|
||||
try (ByteArrayOutputStream packetArray = IOHelper.newByteArrayOutput()) {
|
||||
try (HOutput packetOutput = new HOutput(packetArray)) {
|
||||
packetOutput.writeVarInt(0x0); // Handshake packet ID
|
||||
packetOutput.writeVarInt(version.protocol); // Protocol version
|
||||
packetOutput.writeVarInt(protocol > 0 ? protocol : 0x4); // Protocol version
|
||||
packetOutput.writeString(address.getHostString(), 0); // Server address
|
||||
packetOutput.writeShort((short) address.getPort()); // Server port
|
||||
packetOutput.writeVarInt(0x1); // Next state - status
|
||||
|
|
|
@ -24,7 +24,7 @@ public String getUsageDescription() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
public void invoke(String... args) {
|
||||
LogHelper.info("PublicKey: %s", Base64.getEncoder().encodeToString(engine.getClientPublicKey().getEncoded()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public String getUsageDescription() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
public void invoke(String... args) {
|
||||
for (LauncherModule module : LauncherEngine.modulesManager.getModules()) {
|
||||
LauncherModuleInfo info = module.getModuleInfo();
|
||||
LauncherTrustManager.CheckClassResult checkStatus = module.getCheckResult();
|
||||
|
|
|
@ -16,7 +16,7 @@ public String getUsageDescription() {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
public void invoke(String... args) {
|
||||
LogHelper.info("Your Hardware ID:");
|
||||
long startTime = System.currentTimeMillis();
|
||||
long currentTime;
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
package pro.gravit.launcher.guard;
|
||||
|
||||
import pro.gravit.launcher.client.ClientLauncherProcess;
|
||||
|
||||
public interface LauncherGuard {
|
||||
String getName();
|
||||
|
||||
void applyGuardParams(ClientLauncherProcess process);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package pro.gravit.launcher.guard;
|
||||
|
||||
import pro.gravit.launcher.client.ClientLauncherProcess;
|
||||
|
||||
public class LauncherNoGuard implements LauncherGuard {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "noGuard";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyGuardParams(ClientLauncherProcess process) {
|
||||
//IGNORED
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package pro.gravit.launcher.guard;
|
||||
|
||||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.launcher.client.ClientLauncherProcess;
|
||||
import pro.gravit.launcher.client.DirBridge;
|
||||
import pro.gravit.utils.helper.JVMHelper;
|
||||
import pro.gravit.utils.helper.UnpackHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class LauncherWrapperGuard implements LauncherGuard {
|
||||
|
||||
public LauncherWrapperGuard() {
|
||||
try {
|
||||
String wrapperName = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe";
|
||||
String projectName = Launcher.getConfig().projectName;
|
||||
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
|
||||
String antiInjectName = JVMHelper.JVM_BITS == 64 ? "AntiInject64.dll" : "AntiInject32.dll";
|
||||
UnpackHelper.unpack(Launcher.getResourceURL(wrapperName, "guard"), DirBridge.getGuardDir().resolve(wrapperUnpackName));
|
||||
UnpackHelper.unpack(Launcher.getResourceURL(antiInjectName, "guard"), DirBridge.getGuardDir().resolve(antiInjectName));
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "wrapper";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyGuardParams(ClientLauncherProcess process) {
|
||||
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) {
|
||||
String projectName = Launcher.getConfig().projectName;
|
||||
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
|
||||
process.executeFile = DirBridge.getGuardDir().resolve(wrapperUnpackName);
|
||||
process.useLegacyJavaClassPathProperty = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
public class NoRuntimeProvider implements RuntimeProvider {
|
||||
@Override
|
||||
public void run(String[] args) throws Exception {
|
||||
public void run(String[] args) {
|
||||
JOptionPane.showMessageDialog(null, "GUI часть лаунчера не найдена.\nС 5.1.0 вам необходимо самостоятельно установить модуль, отвечающий за GUI. Рантайм на JS более не поддерживается");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preLoad() throws Exception {
|
||||
public void preLoad() {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package pro.gravit.launcher.gui;
|
||||
|
||||
public interface RuntimeProvider {
|
||||
void run(String[] args) throws Exception;
|
||||
void run(String[] args);
|
||||
|
||||
void preLoad() throws Exception;
|
||||
void preLoad();
|
||||
|
||||
void init(boolean clientInstance);
|
||||
}
|
||||
|
|
|
@ -115,10 +115,6 @@ private final class RegisterFileVisitor extends SimpleFileVisitor<Path> {
|
|||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||
FileVisitResult result = super.preVisitDirectory(dir, attrs);
|
||||
if (DirWatcher.this.dir.equals(dir)) {
|
||||
dir.register(service, KINDS);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Maybe it's unnecessary to go deeper
|
||||
//if (matcher != null && !matcher.shouldVerify(path)) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue