Skip to content

Commit

Permalink
Add converter api and DecentHolograms converter (#173)
Browse files Browse the repository at this point in the history
* 🔥 Test converter

* 🔥 Working on a more advanced api

* Rename

* 🔥 Add dev-friendly interface for converters

* 🔥 Working `DecentHolograms` converter

* 🔥 Warn with --processIcons and remove #ICON lines

* 🔥 Complete DecentHolograms converter.
  • Loading branch information
Matt-MX authored Dec 26, 2024
1 parent e720a28 commit 948ebf0
Show file tree
Hide file tree
Showing 12 changed files with 640 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public enum HologramModification {
TEXT,
POSITION,
SCALE,
TRANSLATION,
BILLBOARD,
BACKGROUND,
TEXT_SHADOW,
Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ tasks {

downloadPlugins {
modrinth("fancynpcs", "2.4.0")
hangar("ViaVersion", "5.1.1")
hangar("ViaBackwards", "5.1.1")
hangar("ViaVersion", "5.2.0")
hangar("ViaBackwards", "5.2.0")
// modrinth("multiverse-core", "4.3.11")
hangar("PlaceholderAPI", "2.11.6")
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/de/oliver/fancyholograms/FancyHolograms.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import de.oliver.fancyholograms.listeners.PlayerListener;
import de.oliver.fancyholograms.listeners.WorldListener;
import de.oliver.fancyholograms.storage.FlatFileHologramStorage;
import de.oliver.fancyholograms.storage.converter.FHConversionRegistry;
import de.oliver.fancyholograms.util.PluginUtils;
import de.oliver.fancylib.FancyLib;
import de.oliver.fancylib.Metrics;
Expand Down Expand Up @@ -172,6 +173,8 @@ public void onEnable() {
}, getHologramConfiguration().getAutosaveInterval(), getHologramConfiguration().getAutosaveInterval() * 60L, TimeUnit.SECONDS);
}

FHConversionRegistry.registerBuiltInConverters();

fancyLogger.info("Successfully enabled FancyHolograms version %s".formatted(getDescription().getVersion()));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package de.oliver.fancyholograms.commands;

import de.oliver.fancyholograms.FancyHolograms;
import de.oliver.fancyholograms.api.data.HologramData;
import de.oliver.fancyholograms.api.hologram.Hologram;
import de.oliver.fancyholograms.storage.converter.ConverterTarget;
import de.oliver.fancyholograms.storage.converter.FHConversionRegistry;
import de.oliver.fancyholograms.storage.converter.HologramConversionSession;
import de.oliver.fancyholograms.util.Constants;
import de.oliver.fancylib.MessageHelper;
import de.oliver.fancylib.translations.message.Message;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Stream;

public final class FancyHologramsCMD extends Command {
Expand All @@ -28,8 +34,8 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String label, @No
return false;
}

if (args.length != 1) {
MessageHelper.info(sender, "/FancyHolograms <save|reload|version>");
if (args.length < 1) {
MessageHelper.info(sender, Constants.FH_COMMAND_USAGE);
return false;
}

Expand All @@ -50,8 +56,47 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String label, @No
FancyHolograms.get().getVersionConfig().checkVersionAndDisplay(sender, false);
});
}
case "convert" -> {
if (args.length < 3) {
MessageHelper.info(sender, "Usage: /fancyholograms convert <type> <targets> [args...]");
return false;
}

final String converterId = args[1];
FHConversionRegistry.getConverterById(converterId)
.ifPresentOrElse((converter) -> {
final String[] converterArgs = Arrays.asList(args)
.subList(2, args.length)
.toArray(String[]::new);

final ConverterTarget target = ConverterTarget.ofStringNullable(args[2]);

if (target == null) {
MessageHelper.error(sender, "Invalid regex for your conversion target!");
return;
}

final HologramConversionSession session = new HologramConversionSession(target, sender, converterArgs);

try {
final List<HologramData> holograms = converter.convert(session);

for (final HologramData data : holograms) {
final Hologram hologram = this.plugin.getHologramsManager().create(data);
this.plugin.getHologramsManager().addHologram(hologram);
}

this.plugin.getHologramsManager().saveHolograms();
// TODO(matt): Give options to delete them or teleport and a list of IDs please

MessageHelper.success(sender, String.format("Converted successfully, produced %s total holograms!", holograms.size()));
} catch (Exception error) {
MessageHelper.error(sender, error.getMessage());
}
}, () -> MessageHelper.error(sender, "That converter is not registered. Look at the developer documentation if you are adding converters."));
}
default -> {
MessageHelper.info(sender, "/FancyHolograms <save|reload|version>");
MessageHelper.info(sender, Constants.FH_COMMAND_USAGE);
return false;
}
}
Expand All @@ -61,12 +106,34 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String label, @No

@Override
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String label, @NotNull String[] args) throws IllegalArgumentException {
if (args.length != 1) {
if (args.length < 1) {
return Collections.emptyList();
}

return Stream.of("version", "reload", "save")
.filter(alias -> alias.startsWith(args[0].toLowerCase(Locale.ROOT)))
.toList();
List<String> suggestions = new ArrayList<>();

if (args.length == 1) {
suggestions.addAll(Arrays.asList("version", "reload", "save", "convert"));
} else {
if (Objects.equals(args[0], "convert")) {

if (args.length == 2) {
suggestions.addAll(FHConversionRegistry.getAllUsableConverterIds());
} else if (args.length == 3) {
final String converterId = args[1];
FHConversionRegistry.getConverterById(converterId)
.ifPresent((converter) -> {
suggestions.addAll(converter.getConvertableHolograms());
suggestions.add("*");
});
}
}
}

String lastArgument = args[args.length - 1];

return suggestions.stream()
.filter(alias -> alias.startsWith(lastArgument.toLowerCase(Locale.ROOT)))
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String label, @No

final var usingNpcs = PluginUtils.isFancyNpcsEnabled();

List<String> suggestions = new ArrayList<>(Arrays.asList("position", "moveHere", "center", "moveTo", "rotate", "rotatepitch", "billboard", "scale", "visibilityDistance", "visibility", "shadowRadius", "shadowStrength", "brightness", usingNpcs ? "linkWithNpc" : "", usingNpcs ? "unlinkWithNpc" : ""));
List<String> suggestions = new ArrayList<>(Arrays.asList("position", "moveHere", "center", "moveTo", "rotate", "rotatepitch", "billboard", "scale", "translate", "visibilityDistance", "visibility", "shadowRadius", "shadowStrength", "brightness", usingNpcs ? "linkWithNpc" : "", usingNpcs ? "unlinkWithNpc" : ""));
suggestions.addAll(type.getCommands());

return suggestions.stream().filter(input -> input.toLowerCase().startsWith(args[2].toLowerCase(Locale.ROOT))).toList();
Expand Down Expand Up @@ -320,6 +320,7 @@ private boolean edit(@NotNull final CommandSender player, @NotNull final Hologra
case "rotatepitch" -> new RotatePitchCMD().run(player, hologram, args);
case "billboard" -> new BillboardCMD().run(player, hologram, args);
case "scale" -> new ScaleCMD().run(player, hologram, args);
case "translate" -> new TranslateCommand().run(player, hologram, args);
case "updatetextinterval" -> new UpdateTextIntervalCMD().run(player, hologram, args);
case "visibilitydistance" -> new VisibilityDistanceCMD().run(player, hologram, args);
case "visibility" -> new VisibilityCMD().run(player, hologram, args);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package de.oliver.fancyholograms.commands.hologram;

import com.google.common.primitives.Floats;
import de.oliver.fancyholograms.FancyHolograms;
import de.oliver.fancyholograms.api.hologram.Hologram;
import de.oliver.fancyholograms.api.data.DisplayHologramData;
import de.oliver.fancyholograms.api.events.HologramUpdateEvent;
import de.oliver.fancyholograms.commands.HologramCMD;
import de.oliver.fancyholograms.commands.Subcommand;
import de.oliver.fancylib.MessageHelper;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3f;

import java.util.List;

public class TranslateCommand implements Subcommand {

@Override
public List<String> tabcompletion(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) {
return null;
}

@Override
public boolean run(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) {

if (!(player.hasPermission("fancyholograms.hologram.edit.translate"))) {
MessageHelper.error(player, "You don't have the required permission to change the translation of a hologram");
return false;
}

final var translateX = Floats.tryParse(args[3]);
final var translateY = args.length >= 6 ? Floats.tryParse(args[4]) : translateX;
final var translateZ = args.length >= 6 ? Floats.tryParse(args[5]) : translateX;

if (translateX == null || translateY == null || translateZ == null) {
MessageHelper.error(player, "Could not parse translation");
return false;
}

if (!(hologram.getData() instanceof DisplayHologramData displayData)) {
MessageHelper.error(player, "This command can only be used on display holograms");
return false;
}

if (Float.compare(translateX, displayData.getTranslation().x()) == 0 &&
Float.compare(translateY, displayData.getTranslation().y()) == 0 &&
Float.compare(translateZ, displayData.getTranslation().z()) == 0) {
MessageHelper.warning(player, "This hologram is already at this translation");
return false;
}

final var copied = displayData.copy(displayData.getName());
copied.setTranslation(new Vector3f(translateX, translateY, translateZ));

if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.TRANSLATION)) {
return false;
}

if (Float.compare(copied.getTranslation().x(), displayData.getTranslation().x()) == 0 &&
Float.compare(copied.getTranslation().y(), displayData.getTranslation().y()) == 0 &&
Float.compare(copied.getTranslation().z(), displayData.getTranslation().z()) == 0) {
MessageHelper.warning(player, "This hologram is already at this translation");
return false;
}

displayData.setTranslation(new Vector3f(
copied.getTranslation().x(),
copied.getTranslation().y(),
copied.getTranslation().z()));

if (FancyHolograms.get().getHologramConfiguration().isSaveOnChangedEnabled()) {
FancyHolograms.get().getHologramStorage().save(hologram);
}

MessageHelper.success(player, "Changed translation to " + translateX + ", " + translateY + ", " + translateZ);
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package de.oliver.fancyholograms.storage.converter;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.regex.Pattern;

public class ConverterTarget {
private final @NotNull Pattern hologramIdRegex;

public ConverterTarget(@NotNull Pattern matching) {
this.hologramIdRegex = matching;
}

public @NotNull Pattern getRegex() {
return hologramIdRegex;
}

public boolean matches(@NotNull String hologramId) {
return hologramIdRegex.asMatchPredicate().test(hologramId);
}

private static final ConverterTarget ALL = new ConverterTarget(Pattern.compile(".*"));
public static @NotNull ConverterTarget all() {
return ALL;
}

public static @NotNull ConverterTarget ofAll(@NotNull String first, @NotNull String... others) {
StringBuilder builder = new StringBuilder(first);

if (others.length > 0) {
builder.append("|");
}

builder.append(String.join("|", others));

return new ConverterTarget(Pattern.compile(builder.toString()));
}

public static @NotNull ConverterTarget ofSingle(@NotNull String match) {
return new ConverterTarget(Pattern.compile(match));
}

public static @Nullable ConverterTarget ofStringNullable(@NotNull String match) {

if (match.equalsIgnoreCase("*")) {
return all();
}

try {
return new ConverterTarget(Pattern.compile(match));
} catch (Exception ignored) {
return null;
}
}

}
Loading

0 comments on commit 948ebf0

Please sign in to comment.