Skip to content

Remove Legacy Ordered Waypoints #1242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

45 changes: 33 additions & 12 deletions src/main/java/de/hysky/skyblocker/skyblock/waypoint/Waypoints.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.toast.SystemToast;
import org.apache.commons.io.IOUtils;
Expand All @@ -28,11 +27,9 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

Expand All @@ -42,10 +39,13 @@ public class Waypoints {
public static final Logger LOGGER = LoggerFactory.getLogger(Waypoints.class);
private static final Codec<List<WaypointGroup>> CODEC = WaypointGroup.CODEC.listOf();
private static final Codec<List<WaypointGroup>> SKYTILS_CODEC = WaypointGroup.SKYTILS_CODEC.listOf();
private static final Codec<Collection<WaypointGroup>> SKYBLOCKER_LEGACY_ORDERED_CODEC = Codec.unboundedMap(Codec.STRING, WaypointGroup.SKYBLOCKER_LEGACY_ORDERED_CODEC).xmap(Map::values, groups -> groups.stream().collect(Collectors.toMap(WaypointGroup::name, Function.identity())));
private static final String PREFIX = "[Skyblocker-Waypoint-Data-V1]";
private static final String SKYBLOCKER_LEGACY_ORDERED = "[Skyblocker::OrderedWaypoints::v1]";
protected static final SystemToast.Type WAYPOINTS_TOAST_TYPE = new SystemToast.Type();

private static final Path waypointsFile = FabricLoader.getInstance().getConfigDir().resolve(SkyblockerMod.NAMESPACE).resolve("waypoints.json");
private static final Path WAYPOINTS_FILE = SkyblockerMod.CONFIG_DIR.resolve("waypoints.json");
private static final Path SKYBLOCKER_LEGACY_ORDERED_FILE = SkyblockerMod.CONFIG_DIR.resolve("ordered_waypoints.json");
private static final Multimap<Location, WaypointGroup> waypoints = MultimapBuilder.enumKeys(Location.class).arrayListValues().build();

@Init
Expand All @@ -58,16 +58,27 @@ public static void init() {

public static void loadWaypoints() {
waypoints.clear();
try (BufferedReader reader = Files.newBufferedReader(waypointsFile)) {
try (BufferedReader reader = Files.newBufferedReader(WAYPOINTS_FILE)) {
List<WaypointGroup> waypointGroups = CODEC.parse(JsonOps.INSTANCE, SkyblockerMod.GSON.fromJson(reader, JsonArray.class)).resultOrPartial(LOGGER::error).orElseThrow();
waypointGroups.forEach(Waypoints::putWaypointGroup);
} catch (Exception e) {
LOGGER.error("[Skyblocker Waypoints] Encountered exception while loading waypoints", e);
}
}
try (BufferedReader reader = Files.newBufferedReader(SKYBLOCKER_LEGACY_ORDERED_FILE)) {
Collection<WaypointGroup> waypointGroups = SKYBLOCKER_LEGACY_ORDERED_CODEC.parse(JsonOps.INSTANCE, SkyblockerMod.GSON.fromJson(reader, JsonObject.class)).resultOrPartial(LOGGER::error).orElseThrow();
for (WaypointGroup group : waypointGroups) {
Waypoints.putWaypointGroup(group.withIsland(Location.DWARVEN_MINES).deepCopy());
Waypoints.putWaypointGroup(group.withIsland(Location.DWARVEN_MINES).deepCopy());
}
Files.move(SKYBLOCKER_LEGACY_ORDERED_FILE, SkyblockerMod.CONFIG_DIR.resolve("legacy_ordered_waypoints.json"));
LOGGER.info("[Skyblocker Waypoints] Successfully migrated {} ordered waypoints from {} groups to waypoints!", waypointGroups.stream().map(WaypointGroup::waypoints).mapToInt(List::size).sum(), waypointGroups.size());
} catch (IOException e) {
LOGGER.error("[Skyblocker Waypoints] Encountered exception while loading legacy ordered waypoints", e);
}
}

public static void saveWaypoints(MinecraftClient client) {
try (BufferedWriter writer = Files.newBufferedWriter(waypointsFile)) {
try (BufferedWriter writer = Files.newBufferedWriter(WAYPOINTS_FILE)) {
JsonElement waypointsJson = CODEC.encodeStart(JsonOps.INSTANCE, List.copyOf(waypoints.values())).resultOrPartial(LOGGER::error).orElseThrow();
SkyblockerMod.GSON.toJson(waypointsJson, writer);
LOGGER.info("[Skyblocker Waypoints] Saved waypoints");
Expand All @@ -76,14 +87,20 @@ public static void saveWaypoints(MinecraftClient client) {
}
}

public static List<WaypointGroup> fromSkyblocker(String waypointsString) {
public static 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);
}
}
} 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 Collections.emptyList();
}

Expand Down Expand Up @@ -133,7 +150,7 @@ public static List<WaypointGroup> fromSkytilsJson(String waypointGroupsString, L
waypointGroupsJson.add(waypointGroupJson);
}
List<WaypointGroup> waypointGroups = SKYTILS_CODEC.parse(JsonOps.INSTANCE, waypointGroupsJson).resultOrPartial(LOGGER::error).orElseThrow();
return waypointGroups.stream().map(waypointGroup -> waypointGroup.island() == Location.UNKNOWN ? waypointGroup.withIsland(defaultIsland) : waypointGroup).toList();
return applyDefaultLocation(waypointGroups, defaultIsland);
}

public static String toSkytilsBase64(List<WaypointGroup> waypointGroups) {
Expand All @@ -150,6 +167,10 @@ public static WaypointGroup fromColeweightJson(String waypointsJson, Location de
return WaypointGroup.COLEWEIGHT_CODEC.parse(JsonOps.INSTANCE, JsonParser.parseString(waypointsJson)).resultOrPartial(LOGGER::error).orElseThrow().withIsland(defaultIsland);
}

public static List<WaypointGroup> applyDefaultLocation(Collection<WaypointGroup> waypointGroups, Location defaultIsland) {
return waypointGroups.stream().map(waypointGroup -> waypointGroup.island() == Location.UNKNOWN ? waypointGroup.withIsland(defaultIsland) : waypointGroup).toList();
}

/**
* Gets the waypoint groups for the specified island.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected void init() {
GridWidget.Adder adder = gridWidget.createAdder(2);
adder.add(ButtonWidget.builder(Text.translatable("skyblocker.waypoints.importWaypointsSkyblocker"), buttonImport -> {
try {
List<WaypointGroup> waypointGroups = Waypoints.fromSkyblocker(client.keyboard.getClipboard());
List<WaypointGroup> waypointGroups = Waypoints.fromSkyblocker(client.keyboard.getClipboard(), island);
for (WaypointGroup waypointGroup : waypointGroups) {
selectedWaypoints.addAll(waypointGroup.waypoints());
waypoints.put(waypointGroup.island(), waypointGroup);
Expand Down
14 changes: 10 additions & 4 deletions src/main/java/de/hysky/skyblocker/utils/InstancedUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

import com.mojang.logging.LogUtils;

import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import it.unimi.dsi.fastutil.objects.ObjectSet;

/**
* @implNote If implementing any of these onto a class, ensure that all subclasses have an implementation of the methods too.
Expand Down Expand Up @@ -71,7 +72,7 @@ public static MethodHandle toString(Class<?> type) {
try {
Field[] fields = getClassFields(type);
MethodHandle[] getters = getFieldGetters(fields);
String fieldNames = String.join(";", Arrays.stream(fields).map(Field::getName).toArray(String[]::new));
String fieldNames = String.join(";", Arrays.stream(fields).filter(InstancedUtils::nonStatic).map(Field::getName).toArray(String[]::new));

MethodHandle toStringHandle = (MethodHandle) ObjectMethods.bootstrap(MethodHandles.lookup(), "toString", MethodHandle.class, type, fieldNames, getters);

Expand All @@ -90,10 +91,11 @@ private static Field[] getClassFields(Class<?> type) {
}

private static MethodHandle[] getFieldGetters(Field[] fields) throws Throwable {
ObjectOpenHashSet<MethodHandle> handles = new ObjectOpenHashSet<>();
// Keep insertion order to make sure getters and field names match
ObjectSet<MethodHandle> handles = new ObjectLinkedOpenHashSet<>();

for (Field field : fields) {
if ((field.getModifiers() & Modifier.STATIC) != 0) continue;
if (!nonStatic(field)) continue;

field.setAccessible(true);

Expand All @@ -104,4 +106,8 @@ private static MethodHandle[] getFieldGetters(Field[] fields) throws Throwable {

return handles.toArray(MethodHandle[]::new);
}

private static boolean nonStatic(Field field) {
return (field.getModifiers() & Modifier.STATIC) == 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import de.hysky.skyblocker.utils.CodecUtils;
import de.hysky.skyblocker.utils.ColorUtils;
import de.hysky.skyblocker.utils.render.RenderHelper;
import it.unimi.dsi.fastutil.floats.FloatArrayList;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.text.Text;
import net.minecraft.text.TextCodecs;
Expand Down Expand Up @@ -50,6 +51,11 @@ public class NamedWaypoint extends Waypoint {
CodecUtils.optionalDouble(Codec.DOUBLE.optionalFieldOf("b")).forGetter(waypoint -> OptionalDouble.of(waypoint.colorComponents[2])),
ColeweightOptions.CODEC.optionalFieldOf("options").forGetter(waypoint -> Optional.of(new ColeweightOptions(Optional.of(waypoint.name.getString()))))
).apply(instance, NamedWaypoint::fromColeweight));
static final Codec<NamedWaypoint> SKYBLOCKER_LEGACY_ORDERED_CODEC = RecordCodecBuilder.create(instance -> instance.group(
BlockPos.CODEC.fieldOf("pos").forGetter(waypoint -> waypoint.pos),
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 final Text name;
public final Vec3d centerPos;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ public class WaypointGroup {
NamedWaypoint.SKYTILS_CODEC.listOf().fieldOf("waypoints").forGetter(WaypointGroup::waypoints)
).apply(instance, WaypointGroup::new));
public static final Codec<WaypointGroup> COLEWEIGHT_CODEC = NamedWaypoint.COLEWEIGHT_CODEC.listOf().xmap(coleWeightWaypoints -> new WaypointGroup("Coleweight", Location.UNKNOWN, coleWeightWaypoints, true), WaypointGroup::waypoints);
public static final Codec<WaypointGroup> SKYBLOCKER_LEGACY_ORDERED_CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.STRING.fieldOf("name").forGetter(WaypointGroup::name),
Codec.BOOL.fieldOf("enabled").forGetter(group -> !group.waypoints().isEmpty() && group.waypoints().stream().allMatch(Waypoint::isEnabled)),
NamedWaypoint.SKYBLOCKER_LEGACY_ORDERED_CODEC.listOf().fieldOf("waypoints").forGetter(WaypointGroup::waypoints)
).apply(instance, (name, enabled, waypoints) -> {
waypoints.forEach(enabled ? Waypoint::setMissing : Waypoint::setFound);
return new WaypointGroup(name, Location.UNKNOWN, waypoints, true);
}));
public static final int WAYPOINT_ACTIVATION_RADIUS = 2;

private final String name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ void testHashCodeOfDifferentFieldValues() {

@Test
void testToString() {
Vector3i vec1 = new Vector3i(8, 8, 8);
Vector3i vec1 = new Vector3i(1, 2, 3);

Assertions.assertEquals(vec1.toString(), "Vector3i[x=8, y=8, z=8]");
Assertions.assertEquals("Vector3i[x=1, y=2, z=3]", vec1.toString());
}

@SuppressWarnings("unused")
Expand Down
Loading