From 4ef4df0911c0b60e3be1e9f8da2372831be639fa Mon Sep 17 00:00:00 2001 From: Gravit Date: Tue, 25 Sep 2018 19:05:20 +0700 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=BF=D1=86=D0=B8=D0=BE=D0=BD=D0=B0?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=BC=D0=BE=D0=B4=D1=8B=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../launcher/client/ClientLauncher.java | 38 ++++++++---- .../ru/gravit/launcher/hasher/HashedDir.java | 47 +++++++++------ .../launcher/profiles/ClientProfile.java | 59 +++++++++++++------ 3 files changed, 97 insertions(+), 47 deletions(-) diff --git a/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java b/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java index ff621c7a..284ffae0 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java +++ b/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java @@ -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 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 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(); diff --git a/libLauncher/src/main/java/ru/gravit/launcher/hasher/HashedDir.java b/libLauncher/src/main/java/ru/gravit/launcher/hasher/HashedDir.java index d82a9a4e..054edd4f 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/hasher/HashedDir.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/hasher/HashedDir.java @@ -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 dir_stack = new Stack<>(); - StringTokenizer st = new StringTokenizer(name,"/"); - while(st.hasMoreTokens()) - { - dir_stack.push(st.nextToken()); - } - HashedDir dir; - Map 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 dirs = new LinkedList<>(); + StringTokenizer t = new StringTokenizer(name,"/"); + while(t.hasMoreTokens()) + { + dirs.add(t.nextToken()); + } + Map 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); diff --git a/libLauncher/src/main/java/ru/gravit/launcher/profiles/ClientProfile.java b/libLauncher/src/main/java/ru/gravit/launcher/profiles/ClientProfile.java index f8134c00..2f8481a9 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/profiles/ClientProfile.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/profiles/ClientProfile.java @@ -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 update = new ArrayList<>(); private final List updateExclusions = new ArrayList<>(); private final List updateVerify = new ArrayList<>(); - private final List updateOptional = new ArrayList<>(); - private final List markUpdateOptional = new ArrayList<>(); + private final Set 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 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