|
38 | 38 | import java.util.List; |
39 | 39 | import java.util.Locale; |
40 | 40 | import java.util.Map; |
| 41 | +import java.util.Objects; |
41 | 42 | import java.util.Optional; |
42 | 43 | import java.util.Properties; |
43 | 44 | import java.util.Set; |
|
47 | 48 | import java.util.concurrent.Executors; |
48 | 49 | import java.util.concurrent.atomic.AtomicInteger; |
49 | 50 | import java.util.function.Consumer; |
50 | | -import java.util.stream.Collectors; |
51 | 51 | import java.util.stream.Stream; |
52 | 52 | import java.util.zip.GZIPInputStream; |
53 | 53 |
|
@@ -415,8 +415,13 @@ public static void findMods(Executor executor, IDiscoveryPipeline pipeline) thro |
415 | 415 | requestJson.addProperty("platform", getPlatform()); |
416 | 416 | requestJson.addProperty("dev", !FMLLoader.isProduction()); |
417 | 417 | requestJson.addProperty("server", FMLLoader.getDist().isDedicatedServer()); |
418 | | - requestJson.addProperty("gzip", true); |
419 | | - requestJson.addProperty("request_server_list", true); |
| 418 | + |
| 419 | + var supportedFeatures = new JsonArray(); |
| 420 | + supportedFeatures.add("gzip"); |
| 421 | + supportedFeatures.add("server_list"); |
| 422 | + supportedFeatures.add("session"); |
| 423 | + |
| 424 | + requestJson.add("supported_features", supportedFeatures); |
420 | 425 |
|
421 | 426 | var syncRequest = HTTP_CLIENT.send(requestBuilderBase.copy().uri(URI.create(api + "/sync/" + URLEncoder.encode(packCode, StandardCharsets.UTF_8))).POST(HttpRequest.BodyPublishers.ofString(requestJson.toString(), StandardCharsets.UTF_8)).build(), HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); |
422 | 427 |
|
@@ -603,81 +608,93 @@ public static void findMods(Executor executor, IDiscoveryPipeline pipeline) thro |
603 | 608 | } |
604 | 609 |
|
605 | 610 | if (syncJson.has("options")) { |
606 | | - var options = new LinkedHashMap<String, String>(); |
607 | | - var path = gameDir.resolve("options.txt"); |
608 | | - boolean changed = false; |
| 611 | + futures.add(CompletableFuture.runAsync(() -> { |
| 612 | + LOGGER.info("Updating options.txt..."); |
| 613 | + var path = gameDir.resolve("options.txt"); |
609 | 614 |
|
610 | | - if (Files.exists(path)) { |
611 | | - for (var line : Files.readAllLines(path)) { |
612 | | - var parts = line.split(":", 2); |
| 615 | + try { |
| 616 | + var options = new LinkedHashMap<String, String>(); |
| 617 | + boolean changed = false; |
| 618 | + |
| 619 | + if (Files.exists(path)) { |
| 620 | + for (var line : Files.readAllLines(path)) { |
| 621 | + var parts = line.split(":", 2); |
613 | 622 |
|
614 | | - if (parts.length == 2) { |
615 | | - options.put(parts[0], parts[1]); |
| 623 | + if (parts.length == 2) { |
| 624 | + options.put(parts[0], parts[1]); |
| 625 | + } |
| 626 | + } |
616 | 627 | } |
617 | | - } |
618 | | - } else { |
619 | | - options.put("version", "4325"); // FIXME: Figure out how to get SharedConstants.getCurrentVersion().getDataVersion().getVersion() |
620 | | - } |
621 | 628 |
|
622 | | - for (var entry : syncJson.get("options").getAsJsonArray()) { |
623 | | - var json = entry.getAsJsonObject(); |
624 | | - var key = json.get("key").getAsString(); |
625 | | - var value = json.get("value").getAsString(); |
626 | | - var force = json.has("force") && json.get("force").getAsBoolean(); |
| 629 | + var arr = syncJson.get("options").getAsJsonArray(); |
627 | 630 |
|
628 | | - if (!options.containsKey(key) || force && !options.get(key).equals(value)) { |
629 | | - options.put(key, value); |
630 | | - changed = true; |
631 | | - } |
632 | | - } |
| 631 | + for (var entry : arr) { |
| 632 | + var json = entry.getAsJsonObject(); |
| 633 | + var key = json.get("key").getAsString(); |
| 634 | + var value = json.get("value").getAsString(); |
| 635 | + var force = json.has("force") && json.get("force").getAsBoolean(); |
633 | 636 |
|
634 | | - if (changed) { |
635 | | - futures.add(CompletableFuture.runAsync(() -> { |
636 | | - LOGGER.info("Updating options.txt..."); |
| 637 | + if (force || !options.containsKey(key)) { |
| 638 | + if (!Objects.equals(options.put(key, value), value)) { |
| 639 | + changed = true; |
| 640 | + } |
| 641 | + } |
| 642 | + } |
637 | 643 |
|
638 | | - try { |
639 | | - Files.writeString(path, options.entrySet().stream().map(e -> e.getKey() + ":" + e.getValue()).collect(Collectors.joining("\n"))); |
640 | | - } catch (Exception ex) { |
641 | | - pipeline.addIssue(ModLoadingIssue.warning("Failed to update options.txt!").withCause(ex).withAffectedPath(path)); |
| 644 | + if (!options.containsKey("version")) { |
| 645 | + options.putFirst("version", "4325"); // FIXME: Figure out how to get SharedConstants.getCurrentVersion().getDataVersion().getVersion() |
| 646 | + changed = true; |
642 | 647 | } |
643 | | - }, executor)); |
644 | | - } |
| 648 | + |
| 649 | + if (changed) { |
| 650 | + var lines = options.entrySet().stream().map(e -> e.getKey() + ":" + e.getValue()).toList(); |
| 651 | + Files.write(path, lines); |
| 652 | + } |
| 653 | + } catch (Exception ex) { |
| 654 | + pipeline.addIssue(ModLoadingIssue.warning("Failed to update options.txt!").withCause(ex).withAffectedPath(path)); |
| 655 | + } |
| 656 | + }, executor)); |
645 | 657 | } |
646 | 658 |
|
647 | 659 | if (syncJson.has("server_properties")) { |
648 | | - var properties = new Properties(); |
649 | | - var path = gameDir.resolve("server.properties"); |
650 | | - boolean changed = false; |
| 660 | + futures.add(CompletableFuture.runAsync(() -> { |
| 661 | + LOGGER.info("Updating server.properties..."); |
| 662 | + var path = gameDir.resolve("server.properties"); |
651 | 663 |
|
652 | | - if (Files.exists(path)) { |
653 | | - try (var in = Files.newInputStream(path)) { |
654 | | - properties.load(in); |
655 | | - } |
656 | | - } |
| 664 | + try { |
| 665 | + var properties = new Properties(); |
| 666 | + boolean changed = false; |
657 | 667 |
|
658 | | - for (var entry : syncJson.get("server_properties").getAsJsonArray()) { |
659 | | - var json = entry.getAsJsonObject(); |
660 | | - var key = json.get("key").getAsString(); |
661 | | - var value = json.get("value").getAsString(); |
662 | | - var force = json.has("force") && json.get("force").getAsBoolean(); |
| 668 | + if (Files.exists(path)) { |
| 669 | + try (var in = Files.newInputStream(path)) { |
| 670 | + properties.load(in); |
| 671 | + } |
| 672 | + } |
663 | 673 |
|
664 | | - if (!properties.containsKey(key) || force && !properties.get(key).equals(value)) { |
665 | | - properties.setProperty(key, value); |
666 | | - changed = true; |
667 | | - } |
668 | | - } |
| 674 | + var arr = syncJson.get("server_properties").getAsJsonArray(); |
669 | 675 |
|
670 | | - if (changed) { |
671 | | - futures.add(CompletableFuture.runAsync(() -> { |
672 | | - LOGGER.info("Updating server.properties..."); |
| 676 | + for (var entry : arr) { |
| 677 | + var json = entry.getAsJsonObject(); |
| 678 | + var key = json.get("key").getAsString(); |
| 679 | + var value = json.get("value").getAsString(); |
| 680 | + var force = json.has("force") && json.get("force").getAsBoolean(); |
673 | 681 |
|
674 | | - try (var out = Files.newOutputStream(path)) { |
675 | | - properties.store(out, "Minecraft server properties"); |
676 | | - } catch (Exception ex) { |
677 | | - pipeline.addIssue(ModLoadingIssue.warning("Failed to update server.properties!").withCause(ex).withAffectedPath(path)); |
| 682 | + if (force || !properties.containsKey(key)) { |
| 683 | + if (!Objects.equals(properties.setProperty(key, value), value)) { |
| 684 | + changed = true; |
| 685 | + } |
| 686 | + } |
678 | 687 | } |
679 | | - }, executor)); |
680 | | - } |
| 688 | + |
| 689 | + if (changed) { |
| 690 | + try (var out = Files.newOutputStream(path)) { |
| 691 | + properties.store(out, "Minecraft server properties"); |
| 692 | + } |
| 693 | + } |
| 694 | + } catch (Exception ex) { |
| 695 | + pipeline.addIssue(ModLoadingIssue.warning("Failed to update server.properties!").withCause(ex).withAffectedPath(path)); |
| 696 | + } |
| 697 | + }, executor)); |
681 | 698 | } |
682 | 699 |
|
683 | 700 | CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); |
|
0 commit comments