Опциональные моды реализованы

This commit is contained in:
Gravit 2018-09-25 19:05:20 +07:00
parent b32a613fd5
commit 4ef4df0911
3 changed files with 97 additions and 47 deletions

View file

@ -15,12 +15,7 @@
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.security.interfaces.RSAPublicKey;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JOptionPane;
@ -78,6 +73,8 @@ public static final class Params extends StreamObject {
@LauncherAPI
public final PlayerProfile pp;
@LauncherAPI
public final Set<ClientProfile.MarkedString> updateOptional;
@LauncherAPI
public final String accessToken;
@LauncherAPI
public final boolean autoEnter;
@ -95,7 +92,11 @@ public static final class Params extends StreamObject {
public Params(byte[] launcherSign, Path assetDir, Path clientDir, PlayerProfile pp, String accessToken,
boolean autoEnter, boolean fullScreen, int ram, int width, int height) {
this.launcherSign = launcherSign.clone();
this.updateOptional = new HashSet<>();
for(ClientProfile.MarkedString s : ClientLauncher.profile.getOptional())
{
if(s.mark) updateOptional.add(s);
}
// Client paths
this.assetDir = assetDir;
this.clientDir = clientDir;
@ -115,7 +116,12 @@ public Params(HInput input) throws IOException {
// Client paths
assetDir = IOHelper.toPath(input.readString(0));
clientDir = IOHelper.toPath(input.readString(0));
updateOptional = new HashSet<>();
int len = input.readLength(128);
for(int i=0;i<len;++i)
{
updateOptional.add(new ClientProfile.MarkedString(input.readString(512),true));
}
// Client params
pp = new PlayerProfile(input);
accessToken = SecurityHelper.verifyToken(input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH));
@ -132,7 +138,11 @@ public void write(HOutput output) throws IOException {
// Client paths
output.writeString(assetDir.toString(), 0);
output.writeString(clientDir.toString(), 0);
output.writeLength(updateOptional.size(),128);
for(ClientProfile.MarkedString s : updateOptional)
{
output.writeString(s.string,512);
}
// Client params
pp.write(output);
output.writeASCII(accessToken, -SecurityHelper.TOKEN_STRING_LENGTH);
@ -148,7 +158,7 @@ public void write(HOutput output) throws IOException {
private static final String SOCKET_HOST = "127.0.0.1";
private static final int SOCKET_PORT = 32148;
private static final String MAGICAL_INTEL_OPTION = "-XX:HeapDumpPath=ThisTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump";
private static final boolean isUsingWrapper = true;
private static final boolean isUsingWrapper = false;
@SuppressWarnings("unused")
private static final Set<PosixFilePermission> BIN_POSIX_PERMISSIONS = Collections.unmodifiableSet(EnumSet.of(
PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE, // Owner
@ -455,8 +465,14 @@ public static void main(String... args) throws Throwable {
DirWatcher clientWatcher = new DirWatcher(params.clientDir, clientHDir.object, clientMatcher, digest)) {
// Verify current state of all dirs
//verifyHDir(IOHelper.JVM_DIR, jvmHDir.object, null, digest);
HashedDir hdir = clientHDir.object;
for(ClientProfile.MarkedString s : ClientLauncher.profile.getOptional())
{
if(params.updateOptional.contains(s)) s.mark = true;
else hdir.removeR(s.string);
}
verifyHDir(params.assetDir, assetHDir.object, assetMatcher, digest);
verifyHDir(params.clientDir, clientHDir.object, clientMatcher, digest);
verifyHDir(params.clientDir, hdir, clientMatcher, digest);
Launcher.modulesManager.postInitModules();
// Start WatchService, and only then client
CommonHelper.newThread("Asset Directory Watcher", true, assetWatcher).start();

View file

@ -10,6 +10,7 @@
import ru.gravit.launcher.LauncherAPI;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
import ru.gravit.utils.helper.VerifyHelper;
import ru.gravit.launcher.serialize.HInput;
import ru.gravit.launcher.serialize.HOutput;
@ -142,27 +143,39 @@ public Diff diff(HashedDir other, FileNameMatcher matcher) {
HashedDir extra = other.sideDiff(this, matcher, new LinkedList<>(), false);
return new Diff(mismatch, extra);
}
public void pushHashedFile(String name, HashedFile file)
{ //TODO: NOT WORKED
Stack<String> dir_stack = new Stack<>();
StringTokenizer st = new StringTokenizer(name,"/");
while(st.hasMoreTokens())
{
dir_stack.push(st.nextToken());
}
HashedDir dir;
Map<String,HashedEntry> current = map;
while(dir_stack.size() != 1)
{
dir = (HashedDir) current.get(dir_stack.pop());
current = dir.map;
}
current.put(dir_stack.pop(),file);
}
public void remove(String name)
{
map.remove(name);
}
public void removeR(String name)
{
LinkedList<String> dirs = new LinkedList<>();
StringTokenizer t = new StringTokenizer(name,"/");
while(t.hasMoreTokens())
{
dirs.add(t.nextToken());
}
Map<String,HashedEntry> current = map;
for(String s : dirs)
{
HashedEntry e = current.get(s);
if(e == null)
{
LogHelper.debug("Null %s",s);
for(String x : current.keySet()) LogHelper.debug("Contains %s",x);
break;
}
if(e.getType() == Type.DIR)
{
current = ((HashedDir) e).map;
LogHelper.debug("Found dir %s",s);
} else {
current.remove(s);
LogHelper.debug("Found filename %s",s);
break;
}
}
}
@LauncherAPI
public HashedEntry getEntry(String name) {
return map.get(name);

View file

@ -5,10 +5,7 @@
import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import ru.gravit.launcher.LauncherAPI;
import ru.gravit.launcher.hasher.FileNameMatcher;
@ -81,12 +78,37 @@ public String toString() {
private final StringConfigEntry serverAddress;
private final IntegerConfigEntry serverPort;
public static class MarkedString {
public String string;
public boolean mark;
public MarkedString(String string, boolean mark) {
this.string = string;
this.mark = mark;
}
public MarkedString(String string) {
this.string = string;
this.mark = false;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MarkedString that = (MarkedString) o;
return Objects.equals(string, that.string);
}
@Override
public int hashCode() {
return Objects.hash(string);
}
}
// Updater and client watch service
private final List<String> update = new ArrayList<>();
private final List<String> updateExclusions = new ArrayList<>();
private final List<String> updateVerify = new ArrayList<>();
private final List<String> updateOptional = new ArrayList<>();
private final List<String> markUpdateOptional = new ArrayList<>();
private final Set<MarkedString> updateOptional = new HashSet<>();
private final BooleanConfigEntry updateFastCheck;
private final BooleanConfigEntry useWhitelist;
@ -115,7 +137,7 @@ public ClientProfile(BlockConfigEntry block) {
// Updater and client watch service
block.getEntry("update", ListConfigEntry.class).stream(StringConfigEntry.class).forEach(update::add);
block.getEntry("updateVerify", ListConfigEntry.class).stream(StringConfigEntry.class).forEach(updateVerify::add);
block.getEntry("updateOptional", ListConfigEntry.class).stream(StringConfigEntry.class).forEach(updateOptional::add);
block.getEntry("updateOptional", ListConfigEntry.class).stream(StringConfigEntry.class).forEach(e -> updateOptional.add(new MarkedString(e)));
block.getEntry("updateExclusions", ListConfigEntry.class).stream(StringConfigEntry.class).forEach(updateExclusions::add);
updateFastCheck = block.getEntry("updateFastCheck", BooleanConfigEntry.class);
useWhitelist = block.getEntry("useWhitelist", BooleanConfigEntry.class);
@ -190,28 +212,27 @@ public String getServerAddress() {
return serverAddress.getValue();
}
@LauncherAPI
public Set<MarkedString> getOptional()
{
return updateOptional;
}
@LauncherAPI
public void markOptional(String opt)
{
if(!updateOptional.contains(opt)) throw new SecurityException(String.format("Optional mod %s not found in optionalList",opt));
markUpdateOptional.add(opt);
if(!updateOptional.contains(new MarkedString(opt))) throw new SecurityException(String.format("Optional mod %s not found in optionalList",opt));
updateOptional.forEach(e -> {if(e.string.equals(opt)) e.mark = true;});
}
@LauncherAPI
public void unmarkOptional(String opt)
{
if(!updateOptional.contains(opt)) throw new SecurityException(String.format("Optional mod %s not found in optionalList",opt));
markUpdateOptional.remove(opt);
if(!updateOptional.contains(new MarkedString(opt))) throw new SecurityException(String.format("Optional mod %s not found in optionalList",opt));
updateOptional.forEach(e -> {if(e.string.equals(opt)) e.mark = false;});
}
public void pushOptional(HashedDir dir,boolean digest) throws IOException {
for(String opt : updateOptional)
for(MarkedString opt : updateOptional)
{
dir.remove(opt);
}
for(String opt : markUpdateOptional)
{
Path path = Paths.get(opt);
File file = new File(path.toAbsolutePath().toString());
dir.pushHashedFile(opt, new HashedFile(path,file.getUsableSpace(),digest));
if(!opt.mark) dir.removeR(opt.string);
}
}
@LauncherAPI