added feedback

This commit is contained in:
Elias Müller 2024-12-03 20:37:14 +01:00
parent 1572096020
commit eae979ee65
7 changed files with 134 additions and 28 deletions

View File

@ -1,34 +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.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
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 {
public void requestFeedback(String eventName) {
List<Player> players = Bukkit.getOnlinePlayers().stream()
.map(player -> (Player) player)
.toList();
private final URI apiEndpoint;
requestFeedback(eventName, players);
public Feedback() {
super("feedback");
this.apiEndpoint = URI.create(Objects.requireNonNull(localConfig().getString("api")));
}
public void requestFeedback(String eventName, List<Player> receivers) {
receivers.forEach(player -> player.sendMessage(
Component.text()
.append(Component.text("------------------------------", NamedTextColor.GRAY))
public void requestFeedback(String eventName, List<Player> receivers, @Nullable String question) {
Map<UUID, String> 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<TextComponent, TextComponent.Builder> message = Component.text()
.append(border)
.appendNewline();
if(question != null) {
message
.append(Component.text(question, NamedTextColor.GREEN))
.appendNewline()
.append(Component.text("Klicke hier und gib Feedback, damit wir dein Spielerlebnis verbessern können!", NamedTextColor.GREEN)
.clickEvent(ClickEvent.openUrl(String.format("https://www.google.com/search?q=%s", eventName))))
.hoverEvent(HoverEvent.showText(Component.text("Klicke, um Feedback zu geben.").color(NamedTextColor.GOLD)))
.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(Component.text("------------------------------", NamedTextColor.GRAY))
));
.append(border);
player.sendMessage(message.build());
});
}
private record Request(String event, List<UUID> users) {}
private final Type responseType = new TypeToken<Map<UUID, String>>(){}.getType();
private Map<UUID, String> 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<String> 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<ApplianceCommand<?>> commands() {
return List.of(
new FeedbackCommand(),
new RequestFeedbackCommand()
);
}
}

View File

@ -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<Feedback> {
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);
}
}

View File

@ -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<Feedback> {
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));
}
}

View File

@ -78,7 +78,7 @@ public class Report extends Appliance {
this.printResultMessage(issuer, httpResponse);
} catch(IOException | InterruptedException e) {
issuer.sendMessage(
Component.text("Internal server description: " + e.getMessage()).color(NamedTextColor.RED)
Component.text("Internal server error: " + e.getMessage()).color(NamedTextColor.RED)
);
throw new RuntimeException(e);
}

View File

@ -1,8 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.report;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import eu.mhsl.craftattack.spawn.util.text.ComponentUtil;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
@ -24,13 +23,7 @@ public class ReportCommand extends ApplianceCommand.PlayerChecked<Report> {
@Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
sender.sendMessage(
Component.newline()
.append(Component.text("Reportanfrage wird erstellt...", NamedTextColor.GREEN))
.appendNewline()
.append(Component.text("Bitte warte einen Augenblick", NamedTextColor.GRAY))
.appendNewline()
);
sender.sendMessage(ComponentUtil.pleaseWait());
if(args.length == 0) {
getAppliance().reportToUnknown(getPlayer());

View File

@ -70,3 +70,6 @@ packselect:
endPrevent:
endDisabled: true
feedback:
api: https://mhsl.eu/craftattack/api/feedback

View File

@ -48,3 +48,5 @@ commands:
acInform:
infobar:
endPrevent:
feedback:
requestFeedback: