From 30f36dfb80b79fbed49d6a2f75e9b142efca6543 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 31 Mar 2020 23:57:46 +1300 Subject: [PATCH 01/20] Optimize server startup file scan We were needlessly hashing every file in the included directories even though many of them may just be filtered out as ignored moments later. --- .../serversync/filemanager/FileManager.java | 43 ++++++++++++------- .../serversync/server/ServerSetup.java | 21 ++------- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java index be3b9167..0653efb6 100644 --- a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java +++ b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java @@ -1,5 +1,6 @@ package com.superzanti.serversync.filemanager; +import com.superzanti.serversync.config.IgnoredFilesMatcher; import com.superzanti.serversync.server.Function; import com.superzanti.serversync.util.FileHash; import com.superzanti.serversync.util.Logger; @@ -11,8 +12,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.stream.Collectors; +import java.util.stream.Stream; public class FileManager { public static final String clientOnlyFilesDirectoryName = "clientmods"; @@ -62,22 +63,34 @@ public Map getDiffableFilesFromDirectories(List included dirs.add(dir); } - List allFiles = dirs.stream().flatMap(dir -> { - try { - return Files.walk(dir).filter(dirPath -> !Files.isDirectory(dirPath)); - } catch (IOException e) { - Logger.debug(String.format("Failed to access files in the directory: %s", dir)); - Logger.debug(e); - } - return null; - }).collect(Collectors.toList()); - - if (allFiles.stream().anyMatch(Objects::isNull)) { - throw new IOException("Some files could not be accessed"); - } + List allFiles = dirs + .parallelStream() + .flatMap(dir -> { + try { + return Files.walk(dir).filter(dirPath -> !Files.isDirectory(dirPath)); + } catch (IOException e) { + Logger + .debug(String.format("Failed to access files in the directory: %s", dir)); + Logger.debug(e); + } + return Stream.empty(); + }).collect(Collectors.toList()); + Logger.debug(String.format("All files: %s", allFiles)); + + List ignoredFiles = allFiles + .parallelStream() + .filter(IgnoredFilesMatcher::matches) + .collect(Collectors.toList()); + Logger.debug(String.format("Ignored files: %s", ignoredFiles)); + + List filteredFiles = allFiles + .parallelStream() + .filter(f -> !IgnoredFilesMatcher.matches(f)) + .collect(Collectors.toList()); + Logger.debug(String.format("Filtered files: %s", filteredFiles)); //TODO add file size to this map - return allFiles.stream().collect(Collectors.toMap(Path::toString, FileHash::hashFile)); + return filteredFiles.stream().collect(Collectors.toMap(Path::toString, FileHash::hashFile)); } public static void removeEmptyDirectories(List directories, Function emptyDirectoryCallback) { diff --git a/src/main/java/com/superzanti/serversync/server/ServerSetup.java b/src/main/java/com/superzanti/serversync/server/ServerSetup.java index 5fa70f8e..b330d712 100644 --- a/src/main/java/com/superzanti/serversync/server/ServerSetup.java +++ b/src/main/java/com/superzanti/serversync/server/ServerSetup.java @@ -61,20 +61,7 @@ public ServerSetup() { Files.createDirectories(Paths.get(managedDirectory)); } - Map managedFiles = fileManager - .getDiffableFilesFromDirectories(managedDirectories); - - //TODO add file include list for white / black list matching combos - // Glob matching from user configured patterns - Map filteredFiles = managedFiles - .entrySet() - .stream() - .filter(entry -> { - Path file = Paths.get(entry.getKey()); - return !GlobPathMatcher - .matches(file, config.FILE_IGNORE_LIST); - }) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + Map managedFiles = fileManager.getDiffableFilesFromDirectories(managedDirectories); Logger.log(String.format( "Found %d files in %d directories <%s>", @@ -82,9 +69,7 @@ public ServerSetup() { managedDirectories.size(), String.join(", ", managedDirectories) )); - Logger.debug("unfiltered: " + managedFiles.toString()); - Logger.debug("filtered: " + filteredFiles.toString()); - serverFiles.putAll(filteredFiles); + serverFiles.putAll(managedFiles); // Add config include files Map configIncludeFiles = config.CONFIG_INCLUDE_LIST @@ -98,7 +83,7 @@ public ServerSetup() { "Found %d included configs in ", configIncludeFiles.size() )); - Logger.debug("files: " + String.join(",", configIncludeFiles.keySet())); + Logger.debug("Config files: " + String.join(",", configIncludeFiles.keySet())); serverFiles.putAll(configIncludeFiles); if (shouldPushClientOnlyFiles()) { From 27760e0668d7d1a9e106fe43554dc208d7534935 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Thu, 2 Apr 2020 16:23:33 +1300 Subject: [PATCH 02/20] Prettify list output in logs --- .../serversync/filemanager/FileManager.java | 14 +++++--------- .../serversync/server/ServerSetup.java | 2 +- .../serversync/util/PrettyList.java | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/superzanti/serversync/util/PrettyList.java diff --git a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java index 0653efb6..5469373b 100644 --- a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java +++ b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java @@ -2,10 +2,7 @@ import com.superzanti.serversync.config.IgnoredFilesMatcher; import com.superzanti.serversync.server.Function; -import com.superzanti.serversync.util.FileHash; -import com.superzanti.serversync.util.Logger; -import com.superzanti.serversync.util.PathBuilder; -import com.superzanti.serversync.util.PathUtils; +import com.superzanti.serversync.util.*; import java.io.IOException; import java.nio.file.*; @@ -69,25 +66,24 @@ public Map getDiffableFilesFromDirectories(List included try { return Files.walk(dir).filter(dirPath -> !Files.isDirectory(dirPath)); } catch (IOException e) { - Logger - .debug(String.format("Failed to access files in the directory: %s", dir)); + Logger.debug(String.format("Failed to access files in the directory: %s", dir)); Logger.debug(e); } return Stream.empty(); }).collect(Collectors.toList()); - Logger.debug(String.format("All files: %s", allFiles)); + Logger.debug(String.format("All files: %s", PrettyList.get(allFiles))); List ignoredFiles = allFiles .parallelStream() .filter(IgnoredFilesMatcher::matches) .collect(Collectors.toList()); - Logger.debug(String.format("Ignored files: %s", ignoredFiles)); + Logger.debug(String.format("Ignored files: %s", PrettyList.get(ignoredFiles))); List filteredFiles = allFiles .parallelStream() .filter(f -> !IgnoredFilesMatcher.matches(f)) .collect(Collectors.toList()); - Logger.debug(String.format("Filtered files: %s", filteredFiles)); + Logger.debug(String.format("Filtered files: %s", PrettyList.get(filteredFiles))); //TODO add file size to this map return filteredFiles.stream().collect(Collectors.toMap(Path::toString, FileHash::hashFile)); diff --git a/src/main/java/com/superzanti/serversync/server/ServerSetup.java b/src/main/java/com/superzanti/serversync/server/ServerSetup.java index b330d712..662f84f7 100644 --- a/src/main/java/com/superzanti/serversync/server/ServerSetup.java +++ b/src/main/java/com/superzanti/serversync/server/ServerSetup.java @@ -55,7 +55,7 @@ public ServerSetup() { try { Logger.log("Starting scan for managed files: " + dateFormatter.format(new Date())); - Logger.debug(String.format("Ignore patterns: %s", String.join(", ", config.FILE_IGNORE_LIST))); + Logger.debug(String.format("Ignore patterns: %s", PrettyList.get(config.FILE_IGNORE_LIST))); for (String managedDirectory : managedDirectories) { Files.createDirectories(Paths.get(managedDirectory)); diff --git a/src/main/java/com/superzanti/serversync/util/PrettyList.java b/src/main/java/com/superzanti/serversync/util/PrettyList.java new file mode 100644 index 00000000..ae10149c --- /dev/null +++ b/src/main/java/com/superzanti/serversync/util/PrettyList.java @@ -0,0 +1,19 @@ +package com.superzanti.serversync.util; + +import java.util.List; +import java.util.stream.Collectors; + +public class PrettyList { + public static String get(List list) { + StringBuilder b = new StringBuilder(); + b.append("{"); + b.append("\n "); + String l = list.stream() + .map(Object::toString) + .collect(Collectors.joining("\n ")); + b.append(l); + b.append("\n"); + b.append("}"); + return b.toString(); + } +} From a09fd594961063f99909d67eef015682b544321a Mon Sep 17 00:00:00 2001 From: Rheimus Date: Thu, 2 Apr 2020 17:49:06 +1300 Subject: [PATCH 03/20] Switch to concurrent map for file stream --- .../com/superzanti/serversync/filemanager/FileManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java index 5469373b..c73b1c97 100644 --- a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java +++ b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java @@ -85,8 +85,7 @@ public Map getDiffableFilesFromDirectories(List included .collect(Collectors.toList()); Logger.debug(String.format("Filtered files: %s", PrettyList.get(filteredFiles))); - //TODO add file size to this map - return filteredFiles.stream().collect(Collectors.toMap(Path::toString, FileHash::hashFile)); + return filteredFiles.stream().collect(Collectors.toConcurrentMap(Path::toString, FileHash::hashFile)); } public static void removeEmptyDirectories(List directories, Function emptyDirectoryCallback) { From b3408336bd1cf04ea4721f4c64b632622aeca6a3 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Thu, 2 Apr 2020 17:58:18 +1300 Subject: [PATCH 04/20] Move walker into try with resources --- .../com/superzanti/serversync/filemanager/FileManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java index c73b1c97..3667c857 100644 --- a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java +++ b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java @@ -63,8 +63,8 @@ public Map getDiffableFilesFromDirectories(List included List allFiles = dirs .parallelStream() .flatMap(dir -> { - try { - return Files.walk(dir).filter(dirPath -> !Files.isDirectory(dirPath)); + try(Stream walker = Files.walk(dir).filter(dirPath -> !Files.isDirectory(dirPath))) { + return walker; } catch (IOException e) { Logger.debug(String.format("Failed to access files in the directory: %s", dir)); Logger.debug(e); From 685e98061355a65adfaa7afba4a6c87e07c10682 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Thu, 2 Apr 2020 17:58:18 +1300 Subject: [PATCH 05/20] Revert "Move walker into try with resources" This reverts commit b3408336bd1cf04ea4721f4c64b632622aeca6a3. --- .../com/superzanti/serversync/filemanager/FileManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java index 3667c857..c73b1c97 100644 --- a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java +++ b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java @@ -63,8 +63,8 @@ public Map getDiffableFilesFromDirectories(List included List allFiles = dirs .parallelStream() .flatMap(dir -> { - try(Stream walker = Files.walk(dir).filter(dirPath -> !Files.isDirectory(dirPath))) { - return walker; + try { + return Files.walk(dir).filter(dirPath -> !Files.isDirectory(dirPath)); } catch (IOException e) { Logger.debug(String.format("Failed to access files in the directory: %s", dir)); Logger.debug(e); From 44a504ade4dda0a54dbdda275da68d421d82edb6 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Thu, 2 Apr 2020 18:41:41 +1300 Subject: [PATCH 06/20] Switch file hash to using NIO --- .../superzanti/serversync/util/FileHash.java | 30 +++++-------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/util/FileHash.java b/src/main/java/com/superzanti/serversync/util/FileHash.java index edc8fd64..f6cfd594 100644 --- a/src/main/java/com/superzanti/serversync/util/FileHash.java +++ b/src/main/java/com/superzanti/serversync/util/FileHash.java @@ -1,37 +1,21 @@ package com.superzanti.serversync.util; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; +import java.nio.file.Files; import java.nio.file.Path; import java.security.MessageDigest; public class FileHash { public static String hashFile(Path file) { - //TODO Just use NIO in the first place - return FileHash.hashString(file.toFile()); - } - - public static String hashString(File file) { try { - InputStream fin = new FileInputStream(file); + byte[] fileBytes = Files.readAllBytes(file); MessageDigest hash = MessageDigest.getInstance("SHA-256"); - - // Push file to hash - byte[] buffer = new byte[1024]; - int read; - do { - read = fin.read(buffer); - if (read > 0) { - hash.update(buffer, 0, read); - } - } while (read != -1); - fin.close(); + hash.update(fileBytes); // Digest file byte[] digest = hash.digest(); if (digest == null) { - return null; + Logger.debug(String.format("Failed to digest file: %s", file)); + return ""; } // Convert to string @@ -42,7 +26,9 @@ public static String hashString(File file) { return sb.toString(); } catch (Exception e) { - return null; + Logger.debug(String.format("Failed to hash file: %s", file)); + Logger.debug(e); } + return ""; } } From daa52eea18c93d859ca7b98467e6394b7b060eff Mon Sep 17 00:00:00 2001 From: Rheimus Date: Thu, 2 Apr 2020 18:41:58 +1300 Subject: [PATCH 07/20] Add defensive files existing check --- .../com/superzanti/serversync/filemanager/FileManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java index c73b1c97..7cd0dea7 100644 --- a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java +++ b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java @@ -85,7 +85,9 @@ public Map getDiffableFilesFromDirectories(List included .collect(Collectors.toList()); Logger.debug(String.format("Filtered files: %s", PrettyList.get(filteredFiles))); - return filteredFiles.stream().collect(Collectors.toConcurrentMap(Path::toString, FileHash::hashFile)); + return filteredFiles.stream() + .filter(Files::exists) + .collect(Collectors.toConcurrentMap(Path::toString, FileHash::hashFile)); } public static void removeEmptyDirectories(List directories, Function emptyDirectoryCallback) { From 530c349a8206d76fa7ba1a68362bd7eda625f4af Mon Sep 17 00:00:00 2001 From: Rheimus Date: Thu, 2 Apr 2020 20:52:50 +1300 Subject: [PATCH 08/20] Update file hash to NIO --- .../superzanti/serversync/util/FileHash.java | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/util/FileHash.java b/src/main/java/com/superzanti/serversync/util/FileHash.java index f6cfd594..29714a8c 100644 --- a/src/main/java/com/superzanti/serversync/util/FileHash.java +++ b/src/main/java/com/superzanti/serversync/util/FileHash.java @@ -1,30 +1,23 @@ package com.superzanti.serversync.util; +import java.io.BufferedInputStream; +import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; +import java.security.DigestInputStream; import java.security.MessageDigest; public class FileHash { public static String hashFile(Path file) { - try { - byte[] fileBytes = Files.readAllBytes(file); - MessageDigest hash = MessageDigest.getInstance("SHA-256"); - hash.update(fileBytes); - - // Digest file - byte[] digest = hash.digest(); - if (digest == null) { - Logger.debug(String.format("Failed to digest file: %s", file)); - return ""; - } - - // Convert to string - StringBuilder sb = new StringBuilder(64); - for (byte aDigest : digest) { - sb.append(Integer.toString((aDigest & 0xff) + 0x100, 16).substring(1)); - } - - return sb.toString(); + try ( + DigestInputStream in = new DigestInputStream( + new BufferedInputStream(Files.newInputStream(file)), + MessageDigest.getInstance("SHA-256") + ) + ) { + byte[] buffer = new byte[8192]; + while (in.read(buffer) > -1) { } + return String.format("%064x", new BigInteger(1, in.getMessageDigest().digest())); } catch (Exception e) { Logger.debug(String.format("Failed to hash file: %s", file)); Logger.debug(e); From 6592b81b574cf2a94c30b3a6c5417c881a88c9eb Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 16:43:01 +1200 Subject: [PATCH 09/20] Add logging of the client file being processed --- src/main/java/com/superzanti/serversync/server/Server.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/server/Server.java b/src/main/java/com/superzanti/serversync/server/Server.java index 0ceca635..79e5f824 100644 --- a/src/main/java/com/superzanti/serversync/server/Server.java +++ b/src/main/java/com/superzanti/serversync/server/Server.java @@ -156,8 +156,7 @@ public Map syncFiles(VoidFunction afterEachFile) // Server: Do you have this file? String path = ois.readUTF(); String hash = ois.readUTF(); - - + Logger.debug(String.format("Processing file: %s, with hash: %s", path, hash)); if (isClientOnlyFile(path)) { if (config.REFUSE_CLIENT_MODS) { From 8c24458372e02ab55bdb5020b2920bdf108d62f1 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 17:02:36 +1200 Subject: [PATCH 10/20] Change server config include handling Only scan for configs if there are actually some in the config_include_list. This saves wasting time reading files when there is nothing to include. --- .../serversync/server/ServerSetup.java | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/server/ServerSetup.java b/src/main/java/com/superzanti/serversync/server/ServerSetup.java index 662f84f7..84d183bf 100644 --- a/src/main/java/com/superzanti/serversync/server/ServerSetup.java +++ b/src/main/java/com/superzanti/serversync/server/ServerSetup.java @@ -71,20 +71,24 @@ public ServerSetup() { )); serverFiles.putAll(managedFiles); - // Add config include files - Map configIncludeFiles = config.CONFIG_INCLUDE_LIST - .stream() - .parallel() - .map(p -> new PathBuilder("config").add(p).buildPath()) - .filter(path -> Files.exists(path) && !IgnoredFilesMatcher.matches(path)) - .collect(Collectors.toMap(Path::toString, FileHash::hashFile)); - - Logger.log(String.format( - "Found %d included configs in ", - configIncludeFiles.size() - )); - Logger.debug("Config files: " + String.join(",", configIncludeFiles.keySet())); - serverFiles.putAll(configIncludeFiles); + // Only include configs if some are actually listed + // saves wasting time scanning the config directory. + if (config.CONFIG_INCLUDE_LIST.size() > 0) { + // Add config include files + Map configIncludeFiles = config.CONFIG_INCLUDE_LIST + .stream() + .parallel() + .map(p -> new PathBuilder("config").add(p).buildPath()) + .filter(path -> Files.exists(path) && !IgnoredFilesMatcher.matches(path)) + .collect(Collectors.toMap(Path::toString, FileHash::hashFile)); + + Logger.log(String.format( + "Found %d included configs in ", + configIncludeFiles.size() + )); + Logger.debug("Config files: " + String.join(",", configIncludeFiles.keySet())); + serverFiles.putAll(configIncludeFiles); + } if (shouldPushClientOnlyFiles()) { Logger.log("Server configured to push client only mods, clients can still refuse these mods!"); From bd4f74bdd18f944e2435b3c81749a4d1000bc113 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 17:10:07 +1200 Subject: [PATCH 11/20] Improve config include logging Make logging more consistent and valuable. --- .../com/superzanti/serversync/server/ServerSetup.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/server/ServerSetup.java b/src/main/java/com/superzanti/serversync/server/ServerSetup.java index 84d183bf..555b3f27 100644 --- a/src/main/java/com/superzanti/serversync/server/ServerSetup.java +++ b/src/main/java/com/superzanti/serversync/server/ServerSetup.java @@ -74,20 +74,24 @@ public ServerSetup() { // Only include configs if some are actually listed // saves wasting time scanning the config directory. if (config.CONFIG_INCLUDE_LIST.size() > 0) { + Logger.log(String.format("Starting scan for managed configs: %s", dateFormatter.format(new Date()))); + Logger.log(String.format("Include patterns: %s", PrettyList.get(config.CONFIG_INCLUDE_LIST))); // Add config include files Map configIncludeFiles = config.CONFIG_INCLUDE_LIST .stream() .parallel() .map(p -> new PathBuilder("config").add(p).buildPath()) .filter(path -> Files.exists(path) && !IgnoredFilesMatcher.matches(path)) - .collect(Collectors.toMap(Path::toString, FileHash::hashFile)); + .collect(Collectors.toConcurrentMap(Path::toString, FileHash::hashFile)); Logger.log(String.format( "Found %d included configs in ", configIncludeFiles.size() )); - Logger.debug("Config files: " + String.join(",", configIncludeFiles.keySet())); - serverFiles.putAll(configIncludeFiles); + if (configIncludeFiles.size() > 0) { + Logger.debug("Config files: " + String.join(",", configIncludeFiles.keySet())); + serverFiles.putAll(configIncludeFiles); + } } if (shouldPushClientOnlyFiles()) { From 88c1e870481ff77b8077a9a1ebbea1bb601a57dd Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 17:29:00 +1200 Subject: [PATCH 12/20] Support maps for pretty print --- .../serversync/filemanager/FileManager.java | 6 +-- .../serversync/server/ServerSetup.java | 12 +++--- .../serversync/util/PrettyCollection.java | 39 +++++++++++++++++++ .../serversync/util/PrettyList.java | 19 --------- 4 files changed, 49 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/superzanti/serversync/util/PrettyCollection.java delete mode 100644 src/main/java/com/superzanti/serversync/util/PrettyList.java diff --git a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java index 7cd0dea7..281b0998 100644 --- a/src/main/java/com/superzanti/serversync/filemanager/FileManager.java +++ b/src/main/java/com/superzanti/serversync/filemanager/FileManager.java @@ -71,19 +71,19 @@ public Map getDiffableFilesFromDirectories(List included } return Stream.empty(); }).collect(Collectors.toList()); - Logger.debug(String.format("All files: %s", PrettyList.get(allFiles))); + Logger.debug(String.format("All files: %s", PrettyCollection.get(allFiles))); List ignoredFiles = allFiles .parallelStream() .filter(IgnoredFilesMatcher::matches) .collect(Collectors.toList()); - Logger.debug(String.format("Ignored files: %s", PrettyList.get(ignoredFiles))); + Logger.debug(String.format("Ignored files: %s", PrettyCollection.get(ignoredFiles))); List filteredFiles = allFiles .parallelStream() .filter(f -> !IgnoredFilesMatcher.matches(f)) .collect(Collectors.toList()); - Logger.debug(String.format("Filtered files: %s", PrettyList.get(filteredFiles))); + Logger.debug(String.format("Filtered files: %s", PrettyCollection.get(filteredFiles))); return filteredFiles.stream() .filter(Files::exists) diff --git a/src/main/java/com/superzanti/serversync/server/ServerSetup.java b/src/main/java/com/superzanti/serversync/server/ServerSetup.java index 555b3f27..f05dfb1c 100644 --- a/src/main/java/com/superzanti/serversync/server/ServerSetup.java +++ b/src/main/java/com/superzanti/serversync/server/ServerSetup.java @@ -55,7 +55,7 @@ public ServerSetup() { try { Logger.log("Starting scan for managed files: " + dateFormatter.format(new Date())); - Logger.debug(String.format("Ignore patterns: %s", PrettyList.get(config.FILE_IGNORE_LIST))); + Logger.debug(String.format("Ignore patterns: %s", PrettyCollection.get(config.FILE_IGNORE_LIST))); for (String managedDirectory : managedDirectories) { Files.createDirectories(Paths.get(managedDirectory)); @@ -75,7 +75,7 @@ public ServerSetup() { // saves wasting time scanning the config directory. if (config.CONFIG_INCLUDE_LIST.size() > 0) { Logger.log(String.format("Starting scan for managed configs: %s", dateFormatter.format(new Date()))); - Logger.log(String.format("Include patterns: %s", PrettyList.get(config.CONFIG_INCLUDE_LIST))); + Logger.log(String.format("Include patterns: %s", PrettyCollection.get(config.CONFIG_INCLUDE_LIST))); // Add config include files Map configIncludeFiles = config.CONFIG_INCLUDE_LIST .stream() @@ -89,7 +89,7 @@ public ServerSetup() { configIncludeFiles.size() )); if (configIncludeFiles.size() > 0) { - Logger.debug("Config files: " + String.join(",", configIncludeFiles.keySet())); + Logger.debug(String.format("Config files: %s", PrettyCollection.get(configIncludeFiles))); serverFiles.putAll(configIncludeFiles); } } @@ -111,8 +111,10 @@ public ServerSetup() { clientOnlyFiles.size(), FileManager.clientOnlyFilesDirectoryName )); - Logger.debug(clientOnlyFiles.toString()); - serverFiles.putAll(clientOnlyFiles); + if (clientOnlyFiles.size() > 0) { + Logger.debug(String.format("Client only files: %s", PrettyCollection.get(clientOnlyFiles))); + serverFiles.putAll(clientOnlyFiles); + } } } } catch (IOException e) { diff --git a/src/main/java/com/superzanti/serversync/util/PrettyCollection.java b/src/main/java/com/superzanti/serversync/util/PrettyCollection.java new file mode 100644 index 00000000..bde956c7 --- /dev/null +++ b/src/main/java/com/superzanti/serversync/util/PrettyCollection.java @@ -0,0 +1,39 @@ +package com.superzanti.serversync.util; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class PrettyCollection { + public static String get(Map map) { + String body = map.entrySet().stream() + .map(entry -> String.format("%s -> %s", entry.getKey(), entry.getValue())) + .collect(Collectors.joining("\n ")); + return build(body); + } + + public static String get(List list) { + String body = list.stream() + .map(Object::toString) + .collect(Collectors.joining("\n ")); + return build(body); + } + + private static void appendHeader(StringBuilder builder) { + builder.append("{"); + builder.append("\n "); + } + + private static void appendFooter(StringBuilder builder) { + builder.append("\n"); + builder.append("}"); + } + + private static String build(String body) { + StringBuilder builder = new StringBuilder(); + appendHeader(builder); + builder.append(body); + appendFooter(builder); + return builder.toString(); + } +} diff --git a/src/main/java/com/superzanti/serversync/util/PrettyList.java b/src/main/java/com/superzanti/serversync/util/PrettyList.java deleted file mode 100644 index ae10149c..00000000 --- a/src/main/java/com/superzanti/serversync/util/PrettyList.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.superzanti.serversync.util; - -import java.util.List; -import java.util.stream.Collectors; - -public class PrettyList { - public static String get(List list) { - StringBuilder b = new StringBuilder(); - b.append("{"); - b.append("\n "); - String l = list.stream() - .map(Object::toString) - .collect(Collectors.joining("\n ")); - b.append(l); - b.append("\n"); - b.append("}"); - return b.toString(); - } -} From 33a4b0599cf5434b562dfa9dc384ced00491b6a0 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 17:30:33 +1200 Subject: [PATCH 13/20] Fix ServerSync name in logs --- src/main/java/com/superzanti/serversync/server/ServerSetup.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/superzanti/serversync/server/ServerSetup.java b/src/main/java/com/superzanti/serversync/server/ServerSetup.java index f05dfb1c..cc655aa6 100644 --- a/src/main/java/com/superzanti/serversync/server/ServerSetup.java +++ b/src/main/java/com/superzanti/serversync/server/ServerSetup.java @@ -159,7 +159,7 @@ public void run() { clientThread.start(); } catch (IOException e) { Logger.error( - "Error while accepting client connection, breaking server listener. You will need to restart serversync"); + "Error while accepting client connection, breaking server listener. You will need to restart ServerSync"); try { server.close(); } catch (IOException ex) { From 09d1c0a62b54d2abfae04223b7b353b1dc1b8144 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 17:56:21 +1200 Subject: [PATCH 14/20] Update language files with new strings --- .../lang/MessagesBundle_en_US.properties | 63 ++++++------- .../lang/MessagesBundle_pl_PL.properties | 88 +++++++------------ .../lang/MessagesBundle_ru_RU.properties | 88 +++++++------------ .../lang/MessagesBundle_zh_CN.properties | 80 +++++++---------- 4 files changed, 126 insertions(+), 193 deletions(-) diff --git a/src/main/resources/assets/serversync/lang/MessagesBundle_en_US.properties b/src/main/resources/assets/serversync/lang/MessagesBundle_en_US.properties index efc809c3..8411ed44 100644 --- a/src/main/resources/assets/serversync/lang/MessagesBundle_en_US.properties +++ b/src/main/resources/assets/serversync/lang/MessagesBundle_en_US.properties @@ -1,31 +1,32 @@ -title = Serversync -server_address = IP Address -server_port = Port -go_button = Sync -button_tooltip = Synchronize client & server -console_title = Information -ignoring = Ignoring -delete_success = deleted -message_file_failed_to_sync = One or more files failed to sync! -message_file_failed_to_delete = One or more files failed to delete! -message_file_failed_to_access = Failed to access file -message_attempting_sync_retry = Attempting to retry sync... -message_attempting_delete_retry = Attempting to retry delete... -message_manual_action_required = Failed to process files, manual action required! -message_client_refused_file = Refused file -connection_message = Connecting to server -connection_failed_host = Could not connect to host -connection_failed_server = Could not connect to server at -connection_attempt_server = Establishing a socket connection to the server... -update_not_needed = No update needed, for a full log check the logs folder in the minecraft directory -update_happened = Files updated -update_start = Starting Update Process -update_complete = Update Complete! Have a nice day! -update_success = Sucessfully updated -update_error = Errors occurred, please check ip/port details are correct. For a detailed log check the logs folder in your minecraft directory -delete_start = Starting deletion process -debug_IO_streams = Creating input/output streams... -debug_IO_streams_failed = Failed to obtain input/output streams from client -debug_server_exit = Telling server to exit... -debug_server_close = Closing connections... -debug_server_close_success = All of serversync's sockets to the server have been closed \ No newline at end of file +title=ServerSync +server_address=IP Address +server_port=Port +go_button=Sync +button_tooltip=Synchronize client & server +console_title=Information +ignoring=Ignoring +delete_success=deleted +message_file_failed_to_sync=One or more files failed to sync! +message_file_failed_to_delete=One or more files failed to delete! +message_file_failed_to_access=Failed to access file +message_attempting_sync_retry=Attempting to retry sync... +message_attempting_delete_retry=Attempting to retry delete... +message_manual_action_required=Failed to process files, manual action required! +message_client_refused_file=Refused file +connection_message=Connecting to server +connection_failed_host=Could not connect to host +connection_failed_server=Could not connect to server at +connection_attempt_server=Establishing a socket connection to the server... +update_not_needed=No update needed, for a full log check the logs folder in the minecraft directory +update_happened=Files updated +update_start=Starting Update Process +update_complete=Update Complete! Have a nice day! +update_success=Successfully updated +update_error=Errors occurred, please check ip/port details are correct. For a detailed log check the logs folder in your minecraft directory +delete_start=Starting deletion process +debug_IO_streams=Creating input/output streams... +debug_IO_streams_failed=Failed to obtain input/output streams from client +debug_server_exit=Telling server to exit... +debug_server_close=Closing connections... +debug_server_close_success=All of ServerSync's sockets to the server have been closed +server_message_file_missing=File: %s has gone missing! \ No newline at end of file diff --git a/src/main/resources/assets/serversync/lang/MessagesBundle_pl_PL.properties b/src/main/resources/assets/serversync/lang/MessagesBundle_pl_PL.properties index cc0e4ef8..643b6105 100644 --- a/src/main/resources/assets/serversync/lang/MessagesBundle_pl_PL.properties +++ b/src/main/resources/assets/serversync/lang/MessagesBundle_pl_PL.properties @@ -1,57 +1,31 @@ -// GUI strings /////////////////////////////////// -title = Serversync -server_address = Adres IP -server_port = Port -go_button = Synchronizuj -button_tooltip = Zsynchronizuj klienta i serwer -console_title = Informacje -////////////////////////////////////////////////// - -// Words ///////////////////////////////////////// -ignoring = Ignoruj\u0119 -delete_success = usuni\u0119to -////////////////////////////////////////////////// - -// Phrases /////////////////////////////////////// -up_to_date = jest aktualny -no_syncable_directories = Serwer nie ustawi\u0142 \u017Cadnych folder\u00F3w do synchronizacji -failed_handshake = Nie uda\u0142o si\u0119 uzyska\u0107 komend z serwera -does_not_exist = Nie istnieje... -does_not_match = Nie zgadza si\u0119... -connection_message = \u0141\u0105czenie z serwerem -connection_failed_host = Nie uda\u0142o si\u0119 po\u0142\u0105czy\u0107 do hosta -connection_failed_server = Nie uda\u0142o si\u0119 po\u0142\u0105czy\u0107 z serwerem -connection_attempt_server = \u0141\u0105czenie z serwerem... -info_syncable_client = Mody klienta do synchronizacji to -info_syncable_server = Mody serwera do synchronizacji to -info_config_desync = Konfiguracja nieaktualna, aktualizuj\u0119... -info_security_recieved=Otrzymano informacje bezpiecze\u0144stwa od serwera -update_not_needed = Aktualizacja nie wymagana, dla wszystkich informacji sprawd\u017A folder log\u00F3w w folderze Minecrafta -update_happened = Zaaktualizowano pliki -update_start = Rozpoczynam aktualizacj\u0119 -update_complete = Aktualizacja uko\u0144czona! Mi\u0142ego dnia! -update_success = Pomy\u015Blnie zaaktualizowano -update_failed = Nie uda\u0142o si\u0119 uzyska\u0107 informacji o aktualizacji -update_error = Wyst\u0105pi\u0142y problemy, prosz\u0119 sprawd\u017A czy adres IP/port si\u0119 zgadza. Dla wszystkich informacji sprawd\u017A folder log\u00F3w w folderze Minecrafta -delete_start = Rozpoczynam proces usuwania -delete_fail = Nie uda\u0142o si\u0119 usun\u0105\u0107 flag dla deleteOnExit -delete_attempt = Pr\u00F3buj\u0119 usun\u0105\u0107 -config_check = Sprawdzam konfiguracje... -client_check = Sprawdzam u klienta -mods_incompatable = Mody mi\u0119dzy serwerem a klientem s\u0105 niekompatybilne... Aktualizuje... -mods_get = Pobieram mody... -mods_accepting_clientmods = Akceptuj\u0119 mody klienta! Dodano mody klienta do listy mod\u00F3w -mods_clientmod_added = Dodano mod klienta -mods_refusing_clientmods = Odrzucam mody klienta z serwera! -debug_IO_streams = Tworz\u0119 strumienie wej\u015Bcia/wyj\u015Bcia... -debug_IO_streams_failed = Nie uda\u0142o si\u0119 uzyska\u0107 strumieni wej\u015Bcia/wyj\u015Bcia od klienta -debug_server_exit = M\u00F3wi\u0119 serwerowi by sko\u0144czy\u0142 po\u0142\u0105czenie... -debug_server_close = Ko\u0144cz\u0119 po\u0142\u0105czenia... -debug_server_close_success = Wszystkie sockety serversync'a z serwerem zosta\u0142y zamkni\u0119te -debug_server_reconnect = Reinitializuje po\u0142\u0105czenia... -debug_server_reconnect_failed = Nie uda\u0142o si\u0119 zresetowa\u0107 strumieni -debug_files_server_tree = Otrzymano drzewo plik\u00F3w z serwera -debug_files_client_only = Otrzymano pliki klienta -debug_files_size_failed = Nie uda\u0142o si\u0119 uzyska\u0107 rozmiaru plik\u00F3w -error_failed_to_find_config_files=Nie uda\u0142o si\u0119 uzyska\u0107 plik\u00F3w konfiguracji. Synchronizacja nie mo\u017Ce by\u0107 kontynuowana -/////////////////////////////////////////////////// \ No newline at end of file +title=ServerSync +server_address=Adres IP +server_port=Port +go_button=Synchronizuj +button_tooltip=Zsynchronizuj klienta i serwer +console_title=Informacje +ignoring=Ignoruj\u0119 +delete_success=usuni\u0119to +message_file_failed_to_sync=One or more files failed to sync! +message_file_failed_to_delete=One or more files failed to delete! +message_file_failed_to_access=Failed to access file +message_attempting_sync_retry=Attempting to retry sync... +message_attempting_delete_retry=Attempting to retry delete... +message_manual_action_required=Failed to process files, manual action required! +message_client_refused_file=Refused file +connection_message=\u0141\u0105czenie z serwerem +connection_failed_host=Nie uda\u0142o si\u0119 po\u0142\u0105czy\u0107 do hosta +connection_failed_server=Nie uda\u0142o si\u0119 po\u0142\u0105czy\u0107 z serwerem +connection_attempt_server=\u0141\u0105czenie z serwerem... +update_not_needed=Aktualizacja nie wymagana, dla wszystkich informacji sprawd\u017A folder log\u00F3w w folderze Minecrafta +update_happened=Zaaktualizowano pliki +update_start=Rozpoczynam aktualizacj\u0119 +update_complete=Aktualizacja uko\u0144czona! Mi\u0142ego dnia! +update_success=Pomy\u015Blnie zaaktualizowano +update_error=Wyst\u0105pi\u0142y problemy, prosz\u0119 sprawd\u017A czy adres IP/port si\u0119 zgadza. Dla wszystkich informacji sprawd\u017A folder log\u00F3w w folderze Minecrafta +delete_start=Rozpoczynam proces usuwania +debug_IO_streams=Tworz\u0119 strumienie wej\u015Bcia/wyj\u015Bcia... +debug_IO_streams_failed=Nie uda\u0142o si\u0119 uzyska\u0107 strumieni wej\u015Bcia/wyj\u015Bcia od klienta +debug_server_exit=M\u00F3wi\u0119 serwerowi by sko\u0144czy\u0142 po\u0142\u0105czenie... +debug_server_close=Ko\u0144cz\u0119 po\u0142\u0105czenia... +debug_server_close_success=Wszystkie sockety ServerSync'a z serwerem zosta\u0142y zamkni\u0119te \ No newline at end of file diff --git a/src/main/resources/assets/serversync/lang/MessagesBundle_ru_RU.properties b/src/main/resources/assets/serversync/lang/MessagesBundle_ru_RU.properties index a89e9379..822342dd 100644 --- a/src/main/resources/assets/serversync/lang/MessagesBundle_ru_RU.properties +++ b/src/main/resources/assets/serversync/lang/MessagesBundle_ru_RU.properties @@ -1,56 +1,32 @@ -//=GUI strings /////////////////////////////////// -title = Serversync -server_address = IP-адрес -server_port = Порт -go_button = Синхронизировать -button_tooltip = Синхронизация клиента и сервера -console_title = Информация -//////////////////////////////////////////////////= - -//=Words ///////////////////////////////////////// -ignoring = Ignoring -delete_success = deleted -//////////////////////////////////////////////////= - -//=Phrases /////////////////////////////////////// -up_to_date = is up to date -no_syncable_directories = Сервер не установил никаких синхронизируемых директорий -failed_handshake = Не удалось получить команды сервера -does_not_exist = Does not exist... -does_not_match = Does not match... -connection_message = Подключение к серверу -connection_failed_host = Не удалось подключиться к хосту -connection_failed_server = Не удалось подключиться к серверу -connection_attempt_server = Установка соединения сокета с сервером... -info_syncable_client = Синхронизируемые клиентские моды: -info_syncable_server = Синхронизируемые серверные моды: -info_config_desync = Configs out of sync, updating... -info_security_recieved = Получена информация о безопасности с сервера -update_not_needed = Обновление не требуется, для подробной информации проверьте папку журналов в директории Minecraft -update_happened = Файлы обновлены -update_start = Запуск процесса обновления -update_complete = Обновление завершено! Хорошего дня! -update_success = Sucessfully updated -update_failed = Не удалось получить информацию об обновлении -update_error = Произошла ошибка, проверьте правильность данных ip/порта. Для подробной информации проверьте папку журналов в директории Minecraft -delete_start = Запуск процесса удаления -delete_fail = Не удалось удалить отметку для deleteOnExit -delete_attempt = Attempting to delete -config_check = Проверка конфигурации... -client_check = Проверка клиентов -mods_incompatable = Моды между сервером и клиентом несовместимы... Обновление... -mods_get = Получение модов... -mods_accepting_clientmods = Accepting client mods! Added client mods to server list -mods_clientmod_added = Client only mod added -mods_refusing_clientmods = Refusing client mods from server! -debug_IO_streams = Создание потоков ввода-вывода... -debug_IO_streams_failed = Не удалось получить потоки ввода-вывода от клиента -debug_server_exit = Telling server to exit... -debug_server_close = Закрытие соединений... -debug_server_close_success = All of serversync's sockets to the server have been closed -debug_server_reconnect = Повторная инициализация соединения... -debug_server_reconnect_failed = Не удалось сбросить потоки -debug_files_server_tree = Recieved server file tree -debug_files_client_only = Recieved client only files -debug_files_size_failed = Не удалось получить размер файла -///////////////////////////////////////////////////= +title=ServerSync +server_address=IP-адрес +server_port=Порт +go_button=Синхронизировать +button_tooltip=Синхронизация клиента и сервера +console_title=Информация +ignoring=Ignoring +delete_success=deleted +message_file_failed_to_sync=One or more files failed to sync! +message_file_failed_to_delete=One or more files failed to delete! +message_file_failed_to_access=Failed to access file +message_attempting_sync_retry=Attempting to retry sync... +message_attempting_delete_retry=Attempting to retry delete... +message_manual_action_required=Failed to process files, manual action required! +message_client_refused_file=Refused file +connection_message=Подключение к серверу +connection_failed_host=Не удалось подключиться к хосту +connection_failed_server=Не удалось подключиться к серверу +connection_attempt_server=Установка соединения сокета с сервером... +update_not_needed=Обновление не требуется, для подробной информации проверьте папку журналов в директории Minecraft +update_happened=Файлы обновлены +update_start=Запуск процесса обновления +update_complete=Обновление завершено! Хорошего дня! +update_success=Sucessfully updated +update_error=Произошла ошибка, проверьте правильность данных ip/порта. Для подробной информации проверьте папку журналов в директории Minecraft +delete_start=Запуск процесса удаления +debug_IO_streams=Создание потоков ввода-вывода... +debug_IO_streams_failed=Не удалось получить потоки ввода-вывода от клиента +debug_server_exit=Telling server to exit... +debug_server_close=Закрытие соединений... +debug_server_close_success=All of ServerSync's sockets to the server have been closed +server_message_file_missing=File: %s has gone missing! diff --git a/src/main/resources/assets/serversync/lang/MessagesBundle_zh_CN.properties b/src/main/resources/assets/serversync/lang/MessagesBundle_zh_CN.properties index 0f62aec9..84ef5e0f 100644 --- a/src/main/resources/assets/serversync/lang/MessagesBundle_zh_CN.properties +++ b/src/main/resources/assets/serversync/lang/MessagesBundle_zh_CN.properties @@ -1,49 +1,31 @@ -title = Serversync -server_address = IP地址 -server_port = 端口 -go_button = 开始同步 -button_tooltip = 正在同步客户端与服务器... -console_title = 信息 -ignoring = 已忽略 -delete_success = 已删除 -up_to_date = 文件已是最新 -no_syncable_directories = 服务器尚未设置任何可同步目录 -failed_handshake = 无法获取服务器命令 -does_not_exist = 不存在 -does_not_match = 不匹配 -connection_message = 正在连接服务器... -connection_failed_host = 无法连接到主机 -connection_failed_server = 无法连接到服务器 -connection_attempt_server = 建立与服务器的套接字连接... -info_syncable_client = 同步客户端... -info_syncable_server = 同步服务器... -info_config_desync = 配置不同步,正在更新... -info_security_recieved = 检索到服务器安全配置 -update_not_needed = 无需更新,详细信息请查看minecraft目录下的log文件 -update_happened = 文件已更新 -update_start = 开始更新过程 -update_complete = 更新完成,祝你今天愉快! -update_success = 更新成功 -update_failed = 无法获取更新信息 -update_error = 发生错误,请检查IP/端口详细信息是否正确。有关详细的日志,请检查您的minecraft目录中的logs文件夹 -delete_start = 开始删除过程... -delete_fail = 删除文件失败 -delete_attempt = 正在尝试删除... -config_check = 正在检查配置... -client_check = 正在检查客户端... -mods_incompatable = 服务器与客户端之间的Mod不兼容...正在更新... -mods_get = 获取Mods... -mods_accepting_clientmods = 接受客户端Mod!将客户端模块添加到服务器列表 -mods_clientmod_added = 仅添加客户端Mod -mods_refusing_clientmods = 拒绝来自服务器的客户端Mod -debug_IO_streams = 创建输入/输出流... -debug_IO_streams_failed = 无法从客户端获取输入/输出流 -debug_server_exit = 服务器退出... -debug_server_close = 关闭连接... -debug_server_close_success = 服务器的所有serversync套接字都已关闭 -debug_server_reconnect = 重新初始化连接... -debug_server_reconnect_failed = 重置流失败 -debug_files_server_tree = 接收到服务器文件树 -debug_files_client_only = 仅限客户端已接收的文件 -debug_files_size_failed = 无法获取文件大小 -error_failed_to_find_config_files = 无法获取配置文件,同步过程无法继续 \ No newline at end of file +title=ServerSync +server_address=IP地址 +server_port=端口 +go_button=开始同步 +button_tooltip=正在同步客户端与服务器... +console_title=信息 +ignoring=已忽略 +delete_success=已删除 +message_file_failed_to_sync=One or more files failed to sync! +message_file_failed_to_delete=One or more files failed to delete! +message_file_failed_to_access=Failed to access file +message_attempting_sync_retry=Attempting to retry sync... +message_attempting_delete_retry=Attempting to retry delete... +message_manual_action_required=Failed to process files, manual action required! +message_client_refused_file=Refused file +connection_message=正在连接服务器... +connection_failed_host=无法连接到主机 +connection_failed_server=无法连接到服务器 +connection_attempt_server=建立与服务器的套接字连接... +update_not_needed=无需更新,详细信息请查看minecraft目录下的log文件 +update_happened=文件已更新 +update_start=开始更新过程 +update_complete=更新完成,祝你今天愉快! +update_success=更新成功 +update_error=发生错误,请检查IP/端口详细信息是否正确。有关详细的日志,请检查您的minecraft目录中的logs文件夹 +delete_start=开始删除过程... +debug_IO_streams=创建输入/输出流... +debug_IO_streams_failed=无法从客户端获取输入/输出流 +debug_server_exit=服务器退出... +debug_server_close=关闭连接... +debug_server_close_success=服务器的所有ServerSync套接字都已关闭 \ No newline at end of file From d65ed49b6f40e76de05d487fe0d48abd57605a11 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 18:01:47 +1200 Subject: [PATCH 15/20] Update readme for translations --- .../assets/serversync/lang/readme.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/resources/assets/serversync/lang/readme.md b/src/main/resources/assets/serversync/lang/readme.md index 76beee04..164a0aef 100644 --- a/src/main/resources/assets/serversync/lang/readme.md +++ b/src/main/resources/assets/serversync/lang/readme.md @@ -3,4 +3,23 @@ - Rename to MessagesBundle_(your language and country code).properties - Replace strings with appropriate translations +## Notes +Ignore string formatting entries e.g. `%s`,`%d`,`%f` etc, these will be filled in by ServerSync with various data from the program. + +e.g. + +`List of mods: %s` would become: +```text +List of mods: { + modA, + modB +} +``` + +`Day of the week: %d` would become: +```text +Day of the week: 4 +``` + + http://lh.2xlibre.net/locales/ From e5d050cb60b7c89670251d4ca3ca49097effa9f4 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 20:32:23 +1200 Subject: [PATCH 16/20] #175 Fix i18n resource bundle path --- src/main/java/com/superzanti/serversync/ServerSync.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/ServerSync.java b/src/main/java/com/superzanti/serversync/ServerSync.java index 32b1cf22..10ad4756 100644 --- a/src/main/java/com/superzanti/serversync/ServerSync.java +++ b/src/main/java/com/superzanti/serversync/ServerSync.java @@ -39,10 +39,10 @@ public static void main(String[] args) { private static void commonInit() { Locale locale = SyncConfig.getConfig().LOCALE; try { - System.out.println("Loading language file: " + locale); - strings = ResourceBundle.getBundle("assets.serversync.MessagesBundle", locale); + Logger.log("Loading language file: " + locale); + strings = ResourceBundle.getBundle("assets.serversync.lang.MessagesBundle", locale); } catch (MissingResourceException e) { - System.out.println("No language file available for: " + locale + ", defaulting to en_US"); + Logger.log("No language file available for: " + locale + ", defaulting to en_US"); strings = ResourceBundle.getBundle("assets.serversync.lang.MessagesBundle", new Locale("en", "US")); } } From 9e763220f42742d35c181311466d64a082846847 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 20:33:11 +1200 Subject: [PATCH 17/20] Add log tags to detailed logs --- src/main/java/com/superzanti/serversync/util/Log.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/superzanti/serversync/util/Log.java b/src/main/java/com/superzanti/serversync/util/Log.java index bad510f2..9e83a350 100644 --- a/src/main/java/com/superzanti/serversync/util/Log.java +++ b/src/main/java/com/superzanti/serversync/util/Log.java @@ -39,7 +39,7 @@ public Log add(String tag, String message) { if (shouldOutputToSystem) { System.out.println(tag + message); } - this.logContent.append(message); + this.logContent.append(tag).append(message); this.logContent.append("\r\n"); this.setChanged(); this.notifyObservers(); From 5e4682622c7f3218b8c87bafeedf7c5144992f31 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 20:33:48 +1200 Subject: [PATCH 18/20] Streamline server setup logging --- .../com/superzanti/serversync/server/ServerSetup.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/server/ServerSetup.java b/src/main/java/com/superzanti/serversync/server/ServerSetup.java index cc655aa6..bf1ca7d8 100644 --- a/src/main/java/com/superzanti/serversync/server/ServerSetup.java +++ b/src/main/java/com/superzanti/serversync/server/ServerSetup.java @@ -55,7 +55,7 @@ public ServerSetup() { try { Logger.log("Starting scan for managed files: " + dateFormatter.format(new Date())); - Logger.debug(String.format("Ignore patterns: %s", PrettyCollection.get(config.FILE_IGNORE_LIST))); + Logger.log(String.format("Ignore patterns: %s", PrettyCollection.get(config.FILE_IGNORE_LIST))); for (String managedDirectory : managedDirectories) { Files.createDirectories(Paths.get(managedDirectory)); @@ -69,7 +69,10 @@ public ServerSetup() { managedDirectories.size(), String.join(", ", managedDirectories) )); - serverFiles.putAll(managedFiles); + if (managedFiles.size() > 0) { + serverFiles.putAll(managedFiles); + Logger.log(String.format("Managed files: %s", PrettyCollection.get(managedFiles))); + } // Only include configs if some are actually listed // saves wasting time scanning the config directory. @@ -89,7 +92,7 @@ public ServerSetup() { configIncludeFiles.size() )); if (configIncludeFiles.size() > 0) { - Logger.debug(String.format("Config files: %s", PrettyCollection.get(configIncludeFiles))); + Logger.log(String.format("Config files: %s", PrettyCollection.get(configIncludeFiles))); serverFiles.putAll(configIncludeFiles); } } @@ -112,7 +115,7 @@ public ServerSetup() { FileManager.clientOnlyFilesDirectoryName )); if (clientOnlyFiles.size() > 0) { - Logger.debug(String.format("Client only files: %s", PrettyCollection.get(clientOnlyFiles))); + Logger.log(String.format("Client only files: %s", PrettyCollection.get(clientOnlyFiles))); serverFiles.putAll(clientOnlyFiles); } } From 7c027634ab50fd732539632702c5108e48b629a6 Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 20:34:24 +1200 Subject: [PATCH 19/20] #175 Fix config loading of locale strings --- src/main/java/com/superzanti/serversync/SyncConfig.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/superzanti/serversync/SyncConfig.java b/src/main/java/com/superzanti/serversync/SyncConfig.java index c4ba4528..6b271611 100644 --- a/src/main/java/com/superzanti/serversync/SyncConfig.java +++ b/src/main/java/com/superzanti/serversync/SyncConfig.java @@ -272,7 +272,13 @@ private void writeConfig() { private void init() { String couldNotFindString = "Could not find %s config entry"; try { - LOCALE = new Locale(config.getEntryByName("LOCALE").getString()); + String localeString = config.getEntryByName("LOCALE").getString(); + String[] localeParts = localeString.split("_"); + if (localeParts.length != 2) { + Logger.error("Malformed locale string!"); + localeParts = new String[]{"en", "US"}; + } + LOCALE = new Locale(localeParts[0], localeParts[1]); } catch (NullPointerException e) { Logger.debug(String.format(couldNotFindString, "LOCALE")); isUsingIncompatableConfig = true; From 56dcd21a480203ce50f12b81f07b8409d466549e Mon Sep 17 00:00:00 2001 From: Rheimus Date: Tue, 7 Apr 2020 20:35:15 +1200 Subject: [PATCH 20/20] #177 Add server handling of missing files --- .../serversync/server/ServerWorker.java | 96 +++++++++++-------- .../lang/MessagesBundle_en_US.properties | 3 +- .../lang/MessagesBundle_ru_RU.properties | 1 + 3 files changed, 59 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/superzanti/serversync/server/ServerWorker.java b/src/main/java/com/superzanti/serversync/server/ServerWorker.java index 169a986e..315f0e73 100644 --- a/src/main/java/com/superzanti/serversync/server/ServerWorker.java +++ b/src/main/java/com/superzanti/serversync/server/ServerWorker.java @@ -1,15 +1,13 @@ package com.superzanti.serversync.server; import com.superzanti.serversync.ServerSync; +import com.superzanti.serversync.util.Logger; import com.superzanti.serversync.util.LoggerNG; import com.superzanti.serversync.util.enums.EBinaryAnswer; import com.superzanti.serversync.util.enums.EServerMessage; import com.superzanti.serversync.util.errors.UnknownMessageError; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import java.io.*; import java.net.Socket; import java.net.SocketException; import java.nio.file.Files; @@ -40,7 +38,7 @@ public class ServerWorker implements Runnable { private Timer timeout; private TimerTask timeoutTask; - private LoggerNG logger; + private LoggerNG clientLogger; ServerWorker( Socket socket, @@ -49,7 +47,7 @@ public class ServerWorker implements Runnable { List managedDirectories, Map serverFiles ) { - logger = new LoggerNG(String.format("server-connection-from-%s", socket.getInetAddress().toString().replaceAll("[/\\.:@?|\\*\"]","-"))); + clientLogger = new LoggerNG(String.format("server-connection-from-%s", socket.getInetAddress().toString().replaceAll("[/\\.:@?|\\*\"]", "-"))); clientSocket = socket; messages = comsMessages; directories = managedDirectories; @@ -58,7 +56,7 @@ public class ServerWorker implements Runnable { Date clientConnectionStarted = new Date(); DateFormat dateFormatter = DateFormat.getDateTimeInstance(); - logger.log("Connection established with " + clientSocket + dateFormatter.format(clientConnectionStarted)); + clientLogger.log("Connection established with " + clientSocket + dateFormatter.format(clientConnectionStarted)); } @Override @@ -67,7 +65,7 @@ public void run() { ois = new ObjectInputStream(clientSocket.getInputStream()); oos = new ObjectOutputStream(clientSocket.getOutputStream()); } catch (IOException e) { - logger.log("Failed to create client streams"); + clientLogger.log("Failed to create client streams"); e.printStackTrace(); } @@ -76,17 +74,17 @@ public void run() { try { setTimeout(ServerWorker.DEFAULT_CLIENT_TIMEOUT_MS); message = (String) ois.readObject(); - logger.log( + clientLogger.log( String.format("Received message: %s, from client: %s", message, clientSocket.getInetAddress())); } catch (SocketException e) { // Client timed out break; } catch (ClassNotFoundException | IOException e) { - logger.debug(e); + clientLogger.debug(e); } if (message == null) { - logger.debug("Received null message, this should not happen."); + clientLogger.debug("Received null message, this should not happen."); continue; } @@ -94,7 +92,7 @@ public void run() { // <----> // always called first if (message.equals(ServerSync.HANDSHAKE)) { - logger.log("Sending coms messages"); + clientLogger.log("Sending coms messages"); oos.writeObject(messages); oos.flush(); continue; @@ -104,12 +102,12 @@ public void run() { // fallback if I don't know what this message is if (!messages.containsValue(message)) { try { - logger.log("Unknown message received from: " + clientSocket.getInetAddress()); + clientLogger.log("Unknown message received from: " + clientSocket.getInetAddress()); oos.writeObject(new UnknownMessageError(message)); oos.flush(); } catch (IOException e) { - logger.log("Failed to write error to client " + clientSocket); - logger.debug(e); + clientLogger.log("Failed to write error to client " + clientSocket); + clientLogger.debug(e); } // There should not be unknown messages being sent to ServerSync, disconnect from the client. @@ -128,7 +126,7 @@ public void run() { if (files.size() > 0) { for (Map.Entry entry : files.entrySet()) { try { - logger.debug(String.format("Asking client if the have file: %s", entry.getKey())); + clientLogger.debug(String.format("Asking client if the have file: %s", entry.getKey())); oos.writeBoolean(true); // There are files left oos.writeUTF(entry.getKey()); // The path oos.writeUTF(entry.getValue()); // The hash @@ -137,24 +135,25 @@ public void run() { // Client: Nope, don't have it joe! if (EBinaryAnswer.NO.getValue() == ois.readInt()) { - logger.debug("Client said they don't have the file"); + clientLogger.debug("Client said they don't have the file"); setTimeout(ServerWorker.FILE_SYNC_CLIENT_TIMEOUT_MS); transferFile(entry.getKey()); } else { - logger.debug("Client said they have the file already"); + clientLogger.debug("Client said they have the file already"); setTimeout(ServerWorker.DEFAULT_CLIENT_TIMEOUT_MS); } } catch (IOException ex) { - logger.debug(ex); - logger.log(String.format("Encountered error during sync with %s, killing sync process", clientSocket.getInetAddress())); + clientLogger.debug(ex); + clientLogger + .log(String.format("Encountered error during sync with %s, killing sync process", clientSocket.getInetAddress())); break; } } - logger.debug("Finished sync"); + clientLogger.debug("Finished sync"); oos.writeBoolean(false); // No files left } else { - logger.debug("No files on the server?"); + clientLogger.debug("No files on the server?"); oos.writeBoolean(false); // No files at all? } oos.flush(); @@ -178,17 +177,17 @@ public void run() { continue; } } catch (SocketException e) { - logger.log("Client " + clientSocket + " closed by timeout"); + clientLogger.log("Client " + clientSocket + " closed by timeout"); break; } catch (IOException e) { - logger.log("Failed to write to " + clientSocket + " client stream"); + clientLogger.log("Failed to write to " + clientSocket + " client stream"); e.printStackTrace(); break; } // <----> if (matchMessage(message, EServerMessage.EXIT)) { - logger.log(String.format( + clientLogger.log(String.format( "Client requested exit, sync process complete for: %s", clientSocket.getInetAddress() )); @@ -196,7 +195,7 @@ public void run() { } } - logger.log("Closing connection with: " + clientSocket); + clientLogger.log("Closing connection with: " + clientSocket); teardown(); } @@ -206,26 +205,43 @@ private void transferFile(String path) throws IOException { // Not checking if the file exists as this is coming from a list of // files that we already know exist. - logger.log("Writing " + file.toString() + " to client " + clientSocket.getInetAddress() + "..."); - InputStream fis = Files.newInputStream(file); + clientLogger.log("Writing " + file.toString() + " to client " + clientSocket.getInetAddress() + "..."); // -- Size, for client GUI progress tracking - long size = Files.size(file); - logger.debug(String.format("File size is: %d", size)); + long size = 0L; + try { + size = Files.size(file); + } catch (IOException e) { + clientLogger.debug(e); + String error = String.format(ServerSync.strings.getString("server_message_file_missing"), file); + clientLogger.error(error); + Logger.error(error); + } catch (SecurityException se) { + clientLogger.debug(se); + clientLogger.error(String.format(ServerSync.strings.getString("server_message_file_permission_denied"), file)); + } + clientLogger.debug(String.format("File size is: %d", size)); oos.writeLong(size); oos.flush(); // -- - int bytesRead; - byte[] buffer = new byte[clientSocket.getSendBufferSize()]; - while ((bytesRead = fis.read(buffer)) > 0) { - oos.write(buffer, 0, bytesRead); - } + if(size > 0) { + int bytesRead; + byte[] buffer = new byte[clientSocket.getSendBufferSize()]; - fis.close(); - oos.flush(); + try (BufferedInputStream fis = new BufferedInputStream(Files.newInputStream(file))) { + while ((bytesRead = fis.read(buffer)) > 0) { + oos.write(buffer, 0, bytesRead); + } + } catch(IOException e) { + clientLogger.debug(String.format("Failed to write file: %s", file)); + clientLogger.debug(e); + } finally { + oos.flush(); + } + } - logger.log(String.format( + clientLogger.log(String.format( "Finished writing: %s, to client: %s", file.toString(), clientSocket.getInetAddress() @@ -247,7 +263,7 @@ private void setTimeout(int durationMs) { clearTimeout(); timeoutTask = new ServerTimeout(this); timeout.schedule(timeoutTask, durationMs); - logger.debug(String.format( + clientLogger.debug(String.format( "Reset timeout for client: %s, with a timeout of: %s", clientSocket.getInetAddress(), durationMs @@ -269,7 +285,7 @@ private void teardown() { public void timeoutShutdown() { try { - logger.log("Client connection timed out, closing " + clientSocket); + clientLogger.log("Client connection timed out, closing " + clientSocket); if (!clientSocket.isClosed()) { clientSocket.close(); diff --git a/src/main/resources/assets/serversync/lang/MessagesBundle_en_US.properties b/src/main/resources/assets/serversync/lang/MessagesBundle_en_US.properties index 8411ed44..6be997e1 100644 --- a/src/main/resources/assets/serversync/lang/MessagesBundle_en_US.properties +++ b/src/main/resources/assets/serversync/lang/MessagesBundle_en_US.properties @@ -29,4 +29,5 @@ debug_IO_streams_failed=Failed to obtain input/output streams from client debug_server_exit=Telling server to exit... debug_server_close=Closing connections... debug_server_close_success=All of ServerSync's sockets to the server have been closed -server_message_file_missing=File: %s has gone missing! \ No newline at end of file +server_message_file_missing=File: %s has gone missing! +server_message_file_permission_denied=File: %s says permission denied \ No newline at end of file diff --git a/src/main/resources/assets/serversync/lang/MessagesBundle_ru_RU.properties b/src/main/resources/assets/serversync/lang/MessagesBundle_ru_RU.properties index 822342dd..cd3b3995 100644 --- a/src/main/resources/assets/serversync/lang/MessagesBundle_ru_RU.properties +++ b/src/main/resources/assets/serversync/lang/MessagesBundle_ru_RU.properties @@ -30,3 +30,4 @@ debug_server_exit=Telling server to exit... debug_server_close=Закрытие соединений... debug_server_close_success=All of ServerSync's sockets to the server have been closed server_message_file_missing=File: %s has gone missing! +server_message_file_permission_denied=File: %s says permission denied