diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/feedback/Feedback.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/feedback/Feedback.java new file mode 100644 index 0000000..32a4b4f --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/feedback/Feedback.java @@ -0,0 +1,99 @@ +package eu.mhsl.craftattack.spawn.appliances.feedback; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import eu.mhsl.craftattack.spawn.Main; +import eu.mhsl.craftattack.spawn.appliance.Appliance; +import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.appliances.feedback.commands.FeedbackCommand; +import eu.mhsl.craftattack.spawn.appliances.feedback.commands.RequestFeedbackCommand; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.ComponentBuilder; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.*; + +public class Feedback extends Appliance { + private final URI apiEndpoint; + + public Feedback() { + super("feedback"); + this.apiEndpoint = URI.create(Objects.requireNonNull(localConfig().getString("api"))); + } + + public void requestFeedback(String eventName, List receivers, @Nullable String question) { + Map feedbackUrls = createPersonalizedUrls( + new Request(eventName, receivers.stream().map(Entity::getUniqueId).toList()) + ); + + System.out.println(feedbackUrls.toString()); + + Component border = Component.text("-".repeat(40), NamedTextColor.GRAY); + + receivers.forEach(player -> { + String feedbackUrl = feedbackUrls.get(player.getUniqueId()); + if(feedbackUrl == null) { + Main.logger().warning(String.format("FeedbackUrl not found for player '%s' from backend!", player.getUniqueId())); + return; + } + + ComponentBuilder message = Component.text() + .append(border) + .appendNewline(); + + if(question != null) { + message + .append(Component.text(question, NamedTextColor.GREEN)) + .appendNewline() + .appendNewline(); + } + + message + .append(Component.text("Klicke hier und gib uns Feedback, damit wir dein Spielerlebnis verbessern können!", NamedTextColor.DARK_GREEN) + .clickEvent(ClickEvent.openUrl(feedbackUrl))) + .hoverEvent(HoverEvent.showText(Component.text("Klicke, um Feedback zu geben."))) + .appendNewline() + .append(border); + + player.sendMessage(message.build()); + }); + } + + private record Request(String event, List users) {} + private final Type responseType = new TypeToken>(){}.getType(); + private Map createPersonalizedUrls(Request data) { + try(HttpClient client = HttpClient.newHttpClient()) { + HttpRequest httpRequest = HttpRequest.newBuilder() + .uri(this.apiEndpoint) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(new Gson().toJson(data))) + .build(); + + HttpResponse httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + return new Gson().fromJson(httpResponse.body(), responseType); + } catch(IOException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + @Override + protected @NotNull List> commands() { + return List.of( + new FeedbackCommand(), + new RequestFeedbackCommand() + ); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/feedback/commands/FeedbackCommand.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/feedback/commands/FeedbackCommand.java new file mode 100644 index 0000000..d14b0dc --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/feedback/commands/FeedbackCommand.java @@ -0,0 +1,22 @@ +package eu.mhsl.craftattack.spawn.appliances.feedback.commands; + +import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.appliances.feedback.Feedback; +import eu.mhsl.craftattack.spawn.util.text.ComponentUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class FeedbackCommand extends ApplianceCommand.PlayerChecked { + public FeedbackCommand() { + super("feedback"); + } + + @Override + protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { + sender.sendMessage(ComponentUtil.pleaseWait()); + getAppliance().requestFeedback("self-issued-ingame", List.of(getPlayer()), null); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/feedback/commands/RequestFeedbackCommand.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/feedback/commands/RequestFeedbackCommand.java new file mode 100644 index 0000000..c7161d9 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/feedback/commands/RequestFeedbackCommand.java @@ -0,0 +1,21 @@ +package eu.mhsl.craftattack.spawn.appliances.feedback.commands; + +import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.appliances.feedback.Feedback; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; + +public class RequestFeedbackCommand extends ApplianceCommand { + public RequestFeedbackCommand() { + super("requestFeedback"); + } + + @Override + protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { + getAppliance().requestFeedback("admin-issued-ingame", new ArrayList<>(Bukkit.getOnlinePlayers()), String.join(" ", args)); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index fef788d..28704b9 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -69,4 +69,7 @@ packselect: icon: "" # base64 player-head texture, can be obtained from sites like https://minecraft-heads.com/ under developers > Value endPrevent: - endDisabled: true \ No newline at end of file + endDisabled: true + +feedback: + api: https://mhsl.eu/craftattack/api/feedback \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1ff774e..c837b8c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -50,3 +50,5 @@ commands: acInform: infobar: endPrevent: + feedback: + requestFeedback: \ No newline at end of file