aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorviciscat <51047087+viciscat@users.noreply.github.com>2025-07-21 21:25:51 +0200
committerGitHub <noreply@github.com>2025-07-21 15:25:51 -0400
commitb0c4c1f669721e5edbe2b4c34d361a000b744b13 (patch)
treef49b2e7fb22163d23bcf85fbad93423d6637e7d4
parent4a43f346a9415f338aff68e51d6cd5f62c57608e (diff)
downloadSkyblocker-b0c4c1f669721e5edbe2b4c34d361a000b744b13.tar.gz
Skyblocker-b0c4c1f669721e5edbe2b4c34d361a000b744b13.tar.bz2
Skyblocker-b0c4c1f669721e5edbe2b4c34d361a000b744b13.zip
waypoint import options + fixes (#1434)
* waypoint import options * actually show error toast if failed to import
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/waypoint/Waypoints.java12
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/waypoint/WaypointsShareScreen.java56
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/waypoint/NamedWaypoint.java30
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/waypoint/WaypointGroup.java5
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_us.json4
5 files changed, 93 insertions, 14 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Waypoints.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Waypoints.java
index 5184fdd8..c71fb88a 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Waypoints.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Waypoints.java
@@ -31,6 +31,7 @@ import net.minecraft.command.argument.EnumArgumentType;
import net.minecraft.text.Text;
import net.minecraft.util.StringIdentifiable;
import org.apache.commons.io.IOUtils;
+import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -130,21 +131,24 @@ public class Waypoints {
}
}
- public static List<WaypointGroup> fromSkyblocker(String waypointsString, Location defaultIsland) {
+ public static @Nullable List<WaypointGroup> fromSkyblocker(String waypointsString, Location defaultIsland) {
if (waypointsString.startsWith(PREFIX)) {
try (GZIPInputStream reader = new GZIPInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(waypointsString.replace(PREFIX, ""))))) {
return CODEC.parse(JsonOps.INSTANCE, SkyblockerMod.GSON.fromJson(new String(reader.readAllBytes()), JsonArray.class)).resultOrPartial(LOGGER::error).orElseThrow();
} catch (IOException e) {
LOGGER.error("[Skyblocker Waypoints] Encountered exception while parsing Skyblocker waypoint data", e);
+ return null;
}
} else if (waypointsString.startsWith(SKYBLOCKER_LEGACY_ORDERED)) {
try (GZIPInputStream reader = new GZIPInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(waypointsString.replace(SKYBLOCKER_LEGACY_ORDERED, ""))))) {
return applyDefaultLocation(SKYBLOCKER_LEGACY_ORDERED_CODEC.parse(JsonOps.INSTANCE, SkyblockerMod.GSON.fromJson(new String(reader.readAllBytes()), JsonObject.class)).resultOrPartial(LOGGER::error).orElseThrow(), defaultIsland);
} catch (IOException e) {
LOGGER.error("[Skyblocker Waypoints] Encountered exception while parsing Skyblocker legacy ordered waypoint data", e);
+ return null;
}
}
- return Collections.emptyList();
+ LOGGER.error("[Skyblocker Waypoints] Unknown skyblocker waypoint data prefix");
+ return null;
}
public static String toSkyblocker(List<WaypointGroup> waypointGroups) {
@@ -158,7 +162,7 @@ public class Waypoints {
return PREFIX + new String(Base64.getEncoder().encode(output.toByteArray()));
}
- public static List<WaypointGroup> fromSkytils(String waypointsString, Location defaultIsland) {
+ public static @Nullable List<WaypointGroup> fromSkytils(String waypointsString, Location defaultIsland) {
try {
if (waypointsString.startsWith("<Skytils-Waypoint-Data>(V")) {
int version = Integer.parseInt(waypointsString.substring(25, waypointsString.indexOf(')')));
@@ -173,8 +177,10 @@ public class Waypoints {
} else return fromSkytilsJson(new String(Base64.getDecoder().decode(waypointsString)), defaultIsland);
} catch (NumberFormatException e) {
LOGGER.error("[Skyblocker Waypoints] Encountered exception while parsing Skytils waypoint data version", e);
+ return null;
} catch (Exception e) {
LOGGER.error("[Skyblocker Waypoints] Encountered exception while decoding Skytils waypoint data", e);
+ return null;
}
return Collections.emptyList();
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/WaypointsShareScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/WaypointsShareScreen.java
index 7773c9c9..f3a31135 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/WaypointsShareScreen.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/WaypointsShareScreen.java
@@ -6,9 +6,7 @@ import de.hysky.skyblocker.utils.waypoint.NamedWaypoint;
import de.hysky.skyblocker.utils.waypoint.WaypointGroup;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.tooltip.Tooltip;
-import net.minecraft.client.gui.widget.ButtonWidget;
-import net.minecraft.client.gui.widget.GridWidget;
-import net.minecraft.client.gui.widget.SimplePositioningWidget;
+import net.minecraft.client.gui.widget.*;
import net.minecraft.client.toast.SystemToast;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
@@ -20,6 +18,10 @@ import java.util.Set;
public class WaypointsShareScreen extends AbstractWaypointsScreen<WaypointsScreen> {
private final Set<NamedWaypoint> selectedWaypoints = new HashSet<>();
+ // Import options
+ private boolean overrideLocation = false;
+ private boolean sortWaypoints = false;
+
protected WaypointsShareScreen(WaypointsScreen parent, Multimap<Location, WaypointGroup> waypoints) {
super(Text.translatable("skyblocker.waypoints.shareWaypoints"), parent, waypoints, parent.island);
}
@@ -29,11 +31,18 @@ public class WaypointsShareScreen extends AbstractWaypointsScreen<WaypointsScree
super.init();
GridWidget gridWidget = new GridWidget();
gridWidget.getMainPositioner().marginX(5).marginY(2);
- GridWidget.Adder adder = gridWidget.createAdder(2);
+ GridWidget.Adder adder = gridWidget.createAdder(3);
+ // First row
adder.add(ButtonWidget.builder(Text.translatable("skyblocker.waypoints.importWaypointsSkyblocker"), buttonImport -> {
try {
List<WaypointGroup> waypointGroups = Waypoints.fromSkyblocker(client.keyboard.getClipboard(), island);
+ if (waypointGroups == null) {
+ showErrorToast();
+ return;
+ }
for (WaypointGroup waypointGroup : waypointGroups) {
+ if (overrideLocation) waypointGroup = waypointGroup.withIsland(island);
+ if (sortWaypoints) waypointGroup = waypointGroup.sortWaypoints(NamedWaypoint.NAME_COMPARATOR);
selectedWaypoints.addAll(waypointGroup.waypoints());
waypoints.put(waypointGroup.island(), waypointGroup);
}
@@ -41,8 +50,8 @@ public class WaypointsShareScreen extends AbstractWaypointsScreen<WaypointsScree
SystemToast.show(client.getToastManager(), Waypoints.WAYPOINTS_TOAST_TYPE, Text.translatable("skyblocker.waypoints.importSuccess"), Text.translatable("skyblocker.waypoints.importSuccessText", waypointGroups.stream().map(WaypointGroup::waypoints).mapToInt(List::size).sum(), waypointGroups.size()));
} catch (Exception e) {
Waypoints.LOGGER.error("[Skyblocker Waypoints] Encountered exception while parsing Skyblocker waypoint data", e);
- SystemToast.show(client.getToastManager(), Waypoints.WAYPOINTS_TOAST_TYPE, Text.translatable("skyblocker.waypoints.importError"), Text.translatable("skyblocker.waypoints.importErrorText"));
- }
+ showErrorToast();
+ }
}).tooltip(Tooltip.of(Text.translatable("skyblocker.waypoints.importWaypointsSkyblocker.tooltip"))).build());
adder.add(ButtonWidget.builder(Text.translatable("skyblocker.waypoints.exportWaypointsSkyblocker"), buttonExport -> {
try {
@@ -54,10 +63,22 @@ public class WaypointsShareScreen extends AbstractWaypointsScreen<WaypointsScree
SystemToast.show(client.getToastManager(), Waypoints.WAYPOINTS_TOAST_TYPE, Text.translatable("skyblocker.waypoints.exportError"), Text.translatable("skyblocker.waypoints.exportErrorText"));
}
}).tooltip(Tooltip.of(Text.translatable("skyblocker.waypoints.exportWaypointsSkyblocker.tooltip"))).build());
+ adder.add(CheckboxWidget.builder(Text.translatable("skyblocker.waypoints.importOptions.overrideLocation"), textRenderer)
+ .maxWidth(ButtonWidget.DEFAULT_WIDTH)
+ .callback((checkbox, checked) -> overrideLocation = checked)
+ .tooltip(Tooltip.of(Text.translatable("skyblocker.waypoints.importOptions.overrideLocation.tooltip")))
+ .build());
+ // Second row
adder.add(ButtonWidget.builder(Text.translatable("skyblocker.waypoints.importWaypointsSkytils"), buttonImport -> {
try {
List<WaypointGroup> waypointGroups = Waypoints.fromSkytils(client.keyboard.getClipboard(), island);
+ if (waypointGroups == null) {
+ showErrorToast();
+ return;
+ }
for (WaypointGroup waypointGroup : waypointGroups) {
+ if (overrideLocation) waypointGroup = waypointGroup.withIsland(island);
+ if (sortWaypoints) waypointGroup = waypointGroup.sortWaypoints(NamedWaypoint.NAME_COMPARATOR);
selectedWaypoints.addAll(waypointGroup.waypoints());
waypoints.put(waypointGroup.island(), waypointGroup);
}
@@ -65,8 +86,8 @@ public class WaypointsShareScreen extends AbstractWaypointsScreen<WaypointsScree
SystemToast.show(client.getToastManager(), Waypoints.WAYPOINTS_TOAST_TYPE, Text.translatable("skyblocker.waypoints.importSuccess"), Text.translatable("skyblocker.waypoints.importSuccessText", waypointGroups.stream().map(WaypointGroup::waypoints).mapToInt(List::size).sum(), waypointGroups.size()));
} catch (Exception e) {
Waypoints.LOGGER.error("[Skyblocker Waypoints] Encountered exception while parsing Skytils waypoint data", e);
- SystemToast.show(client.getToastManager(), Waypoints.WAYPOINTS_TOAST_TYPE, Text.translatable("skyblocker.waypoints.importError"), Text.translatable("skyblocker.waypoints.importErrorText"));
- }
+ showErrorToast();
+ }
}).tooltip(Tooltip.of(Text.translatable("skyblocker.waypoints.importWaypointsSkytils.tooltip"))).build());
adder.add(ButtonWidget.builder(Text.translatable("skyblocker.waypoints.exportWaypointsSkytils"), buttonExport -> {
try {
@@ -78,17 +99,26 @@ public class WaypointsShareScreen extends AbstractWaypointsScreen<WaypointsScree
SystemToast.show(client.getToastManager(), Waypoints.WAYPOINTS_TOAST_TYPE, Text.translatable("skyblocker.waypoints.exportError"), Text.translatable("skyblocker.waypoints.exportErrorText"));
}
}).tooltip(Tooltip.of(Text.translatable("skyblocker.waypoints.exportWaypointsSkytils.tooltip"))).build());
+ adder.add(CheckboxWidget.builder(Text.translatable("skyblocker.waypoints.importOptions.sortWaypoints"), textRenderer)
+ .maxWidth(ButtonWidget.DEFAULT_WIDTH)
+ .callback((checkbox, checked) -> sortWaypoints = checked)
+ .tooltip(Tooltip.of(Text.translatable("skyblocker.waypoints.importOptions.sortWaypoints.tooltip")))
+ .build());
+
+ // Third row
adder.add(ButtonWidget.builder(Text.translatable("skyblocker.waypoints.importWaypointsSnoopy"), buttonImport -> {
try {
WaypointGroup waypointGroup = Waypoints.fromColeweightJson(client.keyboard.getClipboard(), island);
+ if (overrideLocation) waypointGroup = waypointGroup.withIsland(island);
+ if (sortWaypoints) waypointGroup = waypointGroup.sortWaypoints(NamedWaypoint.NAME_COMPARATOR);
selectedWaypoints.addAll(waypointGroup.waypoints());
waypoints.put(waypointGroup.island(), waypointGroup);
waypointsListWidget.updateEntries();
SystemToast.show(client.getToastManager(), Waypoints.WAYPOINTS_TOAST_TYPE, Text.translatable("skyblocker.waypoints.importSuccess"), Text.translatable("skyblocker.waypoints.importSuccessText", waypointGroup.waypoints().size(), 1));
} catch (Exception e) {
Waypoints.LOGGER.error("[Skyblocker Waypoints] Encountered exception while parsing Snoopy waypoint data", e);
- SystemToast.show(client.getToastManager(), Waypoints.WAYPOINTS_TOAST_TYPE, Text.translatable("skyblocker.waypoints.importError"), Text.translatable("skyblocker.waypoints.importErrorText"));
- }
+ showErrorToast();
+ }
}).tooltip(Tooltip.of(Text.translatable("skyblocker.waypoints.importWaypointsSnoopy.tooltip"))).build());
adder.add(ButtonWidget.builder(ScreenTexts.DONE, buttonBack -> close()).build());
gridWidget.refreshPositions();
@@ -96,7 +126,11 @@ public class WaypointsShareScreen extends AbstractWaypointsScreen<WaypointsScree
gridWidget.forEachChild(this::addDrawableChild);
}
- @Override
+ private void showErrorToast() {
+ SystemToast.show(client.getToastManager(), Waypoints.WAYPOINTS_TOAST_TYPE, Text.translatable("skyblocker.waypoints.importError"), Text.translatable("skyblocker.waypoints.importErrorText"));
+ }
+
+ @Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 16, 0xFFFFFF);
diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/NamedWaypoint.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/NamedWaypoint.java
index 8387be4d..6be3cdb1 100644
--- a/src/main/java/de/hysky/skyblocker/utils/waypoint/NamedWaypoint.java
+++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/NamedWaypoint.java
@@ -17,6 +17,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ColorHelper;
import net.minecraft.util.math.Vec3d;
+import java.util.Comparator;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalDouble;
@@ -56,6 +57,8 @@ public class NamedWaypoint extends Waypoint {
Codec.floatRange(0, 1).listOf().xmap(Floats::toArray, FloatArrayList::new).optionalFieldOf("colorComponents", new float[0]).forGetter(waypoint -> waypoint.colorComponents)
).apply(instance, (pos, colorComponents) -> new OrderedNamedWaypoint(pos, "", new float[]{0, 1, 0})));
+ public static final Comparator<NamedWaypoint> NAME_COMPARATOR = new NameComparator();
+
public final Text name;
public final Vec3d centerPos;
@@ -169,4 +172,31 @@ public class NamedWaypoint extends Waypoint {
Codec.either(Codec.STRING, Codec.INT).xmap(either -> either.map(Function.identity(), Object::toString), Either::left).optionalFieldOf("name").forGetter(ColeweightOptions::name)
).apply(instance, ColeweightOptions::new));
}
+
+ private static class NameComparator implements Comparator<NamedWaypoint> {
+
+ @Override
+ public int compare(NamedWaypoint o1, NamedWaypoint o2) {
+ String string1 = o1.getName().getString();
+ String string2 = o2.getName().getString();
+
+ String prefix1 = string1.replaceFirst("\\d+$", "");
+ String prefix2 = string2.replaceFirst("\\d+$", "");
+
+ int i = prefix1.compareTo(prefix2);
+ if (i != 0) return i;
+
+ String num1 = string1.substring(prefix1.length());
+ String num2 = string2.substring(prefix2.length());
+ if (num1.isEmpty() || num2.isEmpty()) return string1.compareTo(string2);
+
+ try {
+ int i1 = Integer.parseInt(num1);
+ int i2 = Integer.parseInt(num2);
+ return Integer.compare(i1, i2);
+ } catch (NumberFormatException e) {
+ return string1.compareTo(string2);
+ }
+ }
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/WaypointGroup.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/WaypointGroup.java
index 200b4eaa..6a4c50e1 100644
--- a/src/main/java/de/hysky/skyblocker/utils/waypoint/WaypointGroup.java
+++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/WaypointGroup.java
@@ -8,6 +8,7 @@ import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.math.BlockPos;
+import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -100,6 +101,10 @@ public class WaypointGroup {
return new WaypointGroup(name, island, waypoints.stream().filter(predicate).toList(), ordered);
}
+ public WaypointGroup sortWaypoints(Comparator<NamedWaypoint> comparator) {
+ return new WaypointGroup(name, island, waypoints.stream().sorted(comparator).toList(), ordered);
+ }
+
/**
* Returns a deep copy of this {@link WaypointGroup} with a mutable waypoints list for editing.
*/
diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json
index 377b2dac..5447f383 100644
--- a/src/main/resources/assets/skyblocker/lang/en_us.json
+++ b/src/main/resources/assets/skyblocker/lang/en_us.json
@@ -1328,6 +1328,10 @@
"skyblocker.waypoints.importWaypointsSnoopy.tooltip": "Import Waypoints from Clipboard (Snoopy Format)",
"skyblocker.waypoints.exportWaypointsSkytils": "Export Waypoints (Skytils)",
"skyblocker.waypoints.exportWaypointsSkytils.tooltip": "Export Waypoints to Clipboard (Skytils Format)",
+ "skyblocker.waypoints.importOptions.overrideLocation": "Override Location",
+ "skyblocker.waypoints.importOptions.overrideLocation.tooltip": "Import the waypoints in the currently selected location instead of the one saved.",
+ "skyblocker.waypoints.importOptions.sortWaypoints": "Sort Waypoints",
+ "skyblocker.waypoints.importOptions.sortWaypoints.tooltip": "Sorts the imported waypoints based on their names.",
"skyblocker.waypoints.importSuccess": "Waypoints Imported",
"skyblocker.waypoints.importSuccessText": "Successfully imported %d waypoint(s) from %d group(s).",
"skyblocker.waypoints.importError": "Error Importing Waypoints",